Поиск текста с регулярным выражением, чтобы соответствовать внешним конкретным символам - PullRequest
3 голосов
/ 18 марта 2010

У меня есть текст, который выглядит так:

Меня зовут (Ричард), и я не могу сделать [что угодно (Джек) не может сделать] и (Роберт) так же [в отличие от (Бетти)] спасибо (Джилл)

Цель - поиск с использованием регулярного выражения , чтобы найти все заключенные в скобки имена, которые встречаются в любом месте текста, НО между скобками.

Итак, в приведенном выше тексте результат, который я ищу:

  • Richard
  • Роберт
  • Jill

Ответы [ 6 ]

3 голосов
/ 18 марта 2010

Вы можете сделать это в два этапа:

step1 : сопоставить все содержимое скобок, используя:

\[[^\]]*\]

и замените его на ''

step2 : сопоставить все оставшиеся в скобках имена (глобально), используя:

\([^)]*\)
2 голосов
/ 18 марта 2010

Вы не сказали, какой язык используете, так что вот немного Python:

>>> import re
>>> REGEX = re.compile(r'(?:[^[(]+|\(([^)]*)\)|\[[^]]*])')
>>> s="""My name is (Richard) and I cannot do [whatever (Jack) can't do] and (Robert) is the same way [unlike (Betty)] thanks (Jill)"""
>>> filter(None, REGEX.findall(s))

Вывод:

['Richard', 'Robert', 'Jill']

Одно предостережение в том, что это не работает с произвольным вложением. Единственное вложение, с которым он действительно работает, это один уровень скобок в квадратных скобках, как указано в вопросе. Произвольное вложение не может быть сделано только с помощью регулярных выражений. (Это следствие леммы прокачки для обычных языков .)

Регулярное выражение ищет куски текста без скобок или скобок, куски текста, заключенные в скобки, и кусочки текста, заключенные в скобки. Только текст в скобках (не в квадратных скобках). findall Python находит все совпадения регулярного выражения в последовательности. В некоторых языках вам может понадобиться написать цикл для многократного совпадения. Для непаренных матчей findall вставляет пустую строку в список результатов, поэтому вызов filter удаляет их.

1 голос
/ 18 марта 2010

ЕСЛИ вы используете .NET, вы можете сделать что-то вроде:

"(?<!\[.*?)(?<name>\(\w+\))(?>!.*\])"
0 голосов
/ 19 марта 2010

То есть, вы хотите, чтобы регулярное выражение совпадало с именем, а не с круглыми скобками? Это должно сделать это:

[^()]+(?=\)[^\[\]]*(?:\[[^\[\]]*\][^\[\]]*)*$)

Как и в случае с другими ответами, я делаю некоторые предположения относительно вашей целевой строки, например, ожидая, что круглые скобки и квадратные скобки будут правильно сбалансированы и не будут вложенными.

Я говорю это должно работать, потому что, хотя я проверял это, я не знаю, с каким языком / инструментом вы используете соответствие регулярному выражению. Мы могли бы предоставить более качественные ответы, если бы имели эту информацию; все регулярные выражения не созданы равными.

0 голосов
/ 18 марта 2010
>>> s="My name is (Richard) and I cannot do [whatever (Jack) can't do (Jill) can] and (Robert) is the same way [unlike (Betty)] thanks (Jill)"
>>> for item in s.split("]"):
...     st = item.split("[")[0]
...     if ")" in st:
...         for i in  st.split(")"):
...             if "(" in i:
...                print i.split("(")[-1]
...
Richard
Robert
Jill
0 голосов
/ 18 марта 2010

Это на самом деле не лучшая работа для одного регулярного выражения - рассматривали ли вы, например, создание копии строки и затем удаление всего, что заключено в квадратные скобки? Тогда было бы довольно просто извлечь вещи из скобок. В качестве альтернативы, вы можете написать очень простой синтаксический анализатор, который разбивает строку на строки (на обычный текст, квадратные скобки и текст в скобках, я думаю), а затем анализирует дерево, которое создает; изначально это было бы больше работы, но сделало бы жизнь намного проще, если позже вы захотите усложнить поведение.

Сказав это, /(?:(?:^|\])[^\[]*)\((.*?)\)/ поможет вашему тестовому примеру (но он почти наверняка будет вести себя странно, если ваши [ и ] не будут правильно сопоставлены, и я не уверен, эффективный).

Быстрый (PHP) тестовый пример:

preg_match_all('/(?:(?:^|\])[^\[]*)\((.*?)\)/', "My name is ... (Jill)", $m);

print(implode(", ", $m[1]));

Выходы:

Richard, Robert, Jill
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...