У меня есть дамп викисловаря, и я изо всех сил пытаюсь найти подходящий шаблон регулярного выражения, чтобы удалить двойные скобки в выражении. Вот пример выражений:
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}}"
Спасибо за помощь!
как это сделать с регулярным выражением PyPi? Я никогда не использовал это
У вас может быть текст, который вы хотите сохранить после последнего }}
, или у вас может быть несколько совпадений в предложении?
Вы можете использовать следующее регулярное выражение для получения желаемого ответа.
\W+{{source\|.*}}
Код будет,
re.sub("\W+{{source\|.*}}", "", line )
Регулярное выражение почти такое же, как и в вопросе, за исключением ?
. Удаление ?
позволяет совпадать с .
как можно больше раз.
Кроме того, чтобы удалить пробел перед {{}}
, добавляется \W+
.
Если текст имеет несколько вхождений {{source|...}}
, это съест весь текст между первым и последним.
Вы можете установить библиотеку регулярных выражений 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 .
Это вычисляет инкрементный «уровень» встраивания, который повышается с каждым «{» и снижается после каждого «}». Символы нулевого уровня являются частью фактического текста, а все остальное исключается.
Вы имеете в виду, что хотите сделать это только с библиотекой
re
? Если вам нужно регулярное выражение, лучше всего использовать библиотеку регулярных выражений PyPi.