LINUX.ORG.RU

Регулярное выражение: вырезать текст в скобках

 , ,


1

1

Всем привет.

Столкнулся с интересной задачкой по регуляркам, в частности использую sed. Вот упрощенный вариант.

Имеется такая строка:

1+2+(3+4+(5+6+(7+8)+9))+10+(11+12+13+14+(15+16)+17+(18+19+(20+21))+22)+23+24

Задача 1. Нужно вырезать из нее все, что в скобках. То есть получить такое:

1+2+10+23+24

Задача 2. То же, но начиная со второго уровня скобок. То есть так:

1+2+(3+4)+10+(11+12+13+14+17+22)+23+24

Как?

Update:

Задача 1 решена:

$ echo "1+2+(3+4+(5+6+(7+8)+9))+10+(11+12+13+14+(15+16)+17+(18+19+(20+21))+22)+23+24" | sed ':a s/([^()]*)//g
t a'
1+2++10++23+24

# Или с косметикой:
$ echo "1+2+(3+4+(5+6+(7+8)+9))+10+(11+12+13+14+(15+16)+17+(18+19+(20+21))+22)+23+24" | sed ':a s/([^()]*)+\?//g
t a'
1+2+10+23+24

★★★★★

Последнее исправление: Kroz (всего исправлений: 2)

какие регулярки, метод конечных автоматов:

сканируешь строку посимвольно.
( — меняет 1 состояние, Уровень++;
) — меняет 2 состояние, Уровень--;
не скобка и состояние 0 (или <Уровня) — печать (символа)

anonymous
()

На любом языке программирования уже написал бы :/

CrossFire ★★★★★
()

типо такой наркомании, как уже сказал ананимус

# -*- coding: utf-8 -*-
a = '1+2+(3+4+(5+6+(7+8)+9))+10+(11+12+13+14+(15+16)+17+(18+19+(20+21))+22)+23+24'
lt = 0
string = ''
for s in a:
	if not lt:
		string +=s
	if s == '(':
		lt +=1
	if s == ')':
		lt -=1
print string.replace('+(', '')

system-root ★★★★★
()
Ответ на: комментарий от anonymous

+ CrossFire, system-root
Я в курсе, что на любом языке программирования это задача для первого класса. Здесь нужна регулярка, ибо:
- желателен однострочник чтобы запускался из коммандной строки на многих компах. Проще написать однострочник в чате, чем передавать кусок кода, рассказывать как его запихивать в файл и делать файл исполняемым. Чисто организаторские неудобства.
- там на самом деле больше таких вот «парных» символов, притом есть варианты когда они экранированы (и соотв. их нужно пропускать). Код распухнет, что усугубит.
- вариант регуляркой будет лаконичней.

Note: решение для первой задачи уже нашел - в шапке.

Kroz ★★★★★
() автор топика
Последнее исправление: Kroz (всего исправлений: 1)
Ответ на: комментарий от Kroz

притом есть варианты когда они экранированы (и соотв. их нужно пропускать

Ой вей! Если "\" — пропустить след. символ.

Ну продолжайте насиловать регулярки, всем пофиг на самом деле.

anonymous
()
Ответ на: комментарий от Kroz

Если \ — пропустить след. символ если он не \

anonymous
()

Это из FAQ по регулярным выражениям: нерешаемо ими. Метка и переход уже делают что-то похожее на машину Тьюринга, а не регулярное выражение.

См. тему «Pumping Lemma».

AEP ★★★★★
()

perl пойдёт?

$ STR="1+2+(3+4+(5+6+(7+8)+9))+10+(11+12+13+14+(15+16)+17+(18+19+(20+21))+22)+23+24"

$ echo $STR | perl -nle ' print s/\W\(([^()]|(?R))*\)//gr '                                
1+2+10+23+24

$ echo $STR | perl -nle ' s/\W\([^()]*\)//g while $i++ < 2; print'
1+2+(3+4)+10+(11+12+13+14+17+22)+23+24
Deleted
()
Ответ на: perl пойдёт? от Deleted

Хмм. Есть на любом компе, однострочник - да, вполне.

Очень, очень благодарю!

Kroz ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.