Регулярное выражение в python: удаление скобок со скобками внутри

У меня есть дамп викисловаря, и я изо всех сил пытаюсь найти подходящий шаблон регулярного выражения, чтобы удалить двойные скобки в выражении. Вот пример выражений:

line = "# Test is a cool word {{source|{{nom w pc|Chantal|Bouchard}}, ''La langue et le nombril'', Presses de l'Université de Montréal (PUM), 2020, p. 174}}."

Я хочу удалить все скобки, когда они начинаются с {{source|:

Пример:# Test is a cool word.

Я пытался использовать re.sub, как эта строка = re.sub("{{source\|.*?}}", "", line )

но я получил # Test is a cool word, ''La langue et le nombril'', Presses de l'Université de Montréal (PUM), 2020, p. 174}}.

Я мог бы также иметь другое предложение, как это line = "# Test is a cool word {{source|Nicolas|Daniel, Presses de l'Université de Montréal 4}}"

Спасибо за помощь!

Вы имеете в виду, что хотите сделать это только с библиотекой re? Если вам нужно регулярное выражение, лучше всего использовать библиотеку регулярных выражений PyPi.

Wiktor Stribiżew 21.12.2020 18:48

как это сделать с регулярным выражением PyPi? Я никогда не использовал это

kavaliero 21.12.2020 18:51

У вас может быть текст, который вы хотите сохранить после последнего }}, или у вас может быть несколько совпадений в предложении?

Wiktor Stribiżew 21.12.2020 18:58
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
3
127
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

\W+{{source\|.*}}

Код будет,

re.sub("\W+{{source\|.*}}", "", line )

Регулярное выражение почти такое же, как и в вопросе, за исключением ?. Удаление ? позволяет совпадать с . как можно больше раз.

Кроме того, чтобы удалить пробел перед {{}}, добавляется \W+.

Если текст имеет несколько вхождений {{source|...}}, это съест весь текст между первым и последним.

tripleee 21.12.2020 19:09
Ответ принят как подходящий

Вы можете установить библиотеку регулярных выражений PyPi (введите pip install regex в терминале/консоли и нажмите ENTER), а затем используйте

import regex
rx = r"\s*{{source\|(?>[^{}]|({{(?:[^{}]++|(?1))*}}))*}}\s*"
line = "# Test is a cool word {{source|{{nom w pc|Chantal|Bouchard}}, ''La langue et le nombril'', Presses de l'Université de Montréal (PUM), 2020, p. 174}}."
print( regex.sub('', line) )
# => # Test is a cool word.

Посмотрите демоверсию Python. Регулярное выражение

\s*\{\{source\|(?>[^{}]|(\{\{(?:[^{}]++|(?1))*}}))*}}\s*

Посмотрите демонстрацию регулярного выражения . Подробности:

  • \s* - ноль или более пробелов
  • {{source\| - буквальная {{source| строка
  • (?>[^{}]|({{(?:[^{}]++|(?1))*}}))* - ноль или более повторений:
    • [^{}] - символ, отличный от { и }
    • | - или
    • ({{(?:[^{}]++|(?1))*}}) - Группа 1 (необходима для рекурсии): {{, ноль или более вхождений любого одного или нескольких символов, кроме {{ и }} или рекурсивной группы 1, а затем строка }}
  • }} - строка }}
  • \s* - ноль или более пробелов.

Подвыражение .*?}} найдет самую короткую строку, оканчивающуюся на }}. Если вы хотите пропустить пары {{...}}, вы должны сказать об этом.

re.sub(r"\{\{source\|(?:\{\{.*?\}\})*.*?\}\}", "", line)

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

Вы можете сделать это без регулярного выражения и охватить все уровни встроенных метаданных.

line = "# Test is a cool word {{source|{{nom w pc|Chantal|Bouchard}}, ''La langue et le nombril'', Presses de l'Université de Montréal (PUM), 2020, p. 174}}."

from itertools import accumulate
levels = accumulate( (c= = "{")-(p= = "}") for c,p in zip(line," "+line) )
result = "".join(c for c,level in zip(line,levels) if level==0)

print(result)
# Test is a cool word .

Это вычисляет инкрементный «уровень» встраивания, который повышается с каждым «{» и снижается после каждого «}». Символы нулевого уровня являются частью фактического текста, а все остальное исключается.

Другие вопросы по теме