Регулярное выражение в python: удаление квадратных скобок и частей фразы внутри скобок
У меня есть дамп Википедии и я изо всех сил пытаюсь найти подходящее регулярное выражение, чтобы удалить двойные квадратные скобки в выражении. Вот пример выражений:
line = 'is the combination of the code names for Herbicide Orange (HO) and Agent LNX, one of the [[herbicide]]s and [[defoliant]]s used by the [[United States armed forces|U.S. military]] as part of its [[herbicidal warfare]] program, [[Operation Ranch Hand]], during the [[Vietnam War]] from 1961 to 1971.'
Я ищу, чтобы удалить все квадратные скобки со следующими условиями:
Если в квадратной скобке нет вертикального разделителя, снимите скобки.
Пример:
[[herbicide]]sстановитсяherbicides.
Если есть вертикальный разделитель внутри скобки снимите скобку и используйте только фразу после разделителя.
Пример:
[[United States armed forces|U.S. military]]становитсяU.S. military.
Я попробовал использовать re.match и re.search, но не смог прийти к желаемому результату.
Спасибо вам за вашу помощь!
3 ответов:
То, что вам нужно, - это
re.sub. Обратите внимание, что квадратные скобки и трубы являются метасимволами, поэтому их необходимо экранировать.re.sub(r'\[\[(?:[^\]|]*\|)?([^\]|]*)\]\]', r'\1', line)Есть два предостережения. Это позволяет использовать только одну трубу между открывающим и закрывающим кронштейнами. Если их несколько, Вам нужно будет указать, хотите ли вы все после первого или все после последнего. Другая оговорка заключается в том, что одиночные
\1в строке замены ссылается на то, что было сопоставлено внутри скобок, которые неначинаются с?:(т. е. в любом случае текст, который вы хотите иметь).]между открывающими и закрывающими скобками не допускаются. Если бы это было проблемой, то все еще существовало бы регулярное выражение, но оно было бы значительно сложнее.Для полного объяснения паттерна:
\[\[ # match two literal [ (?: # start optional non-capturing subpattern for pre-| text [^\]|] # this looks a bit confusing but it is a negated character class # allowing any character except for ] and | * # zero or more of those \| # a literal | )? # end of subpattern; make it optional ( # start of capturing group 1 - the text you want to keep [^\]|]* # the same character class as above ) # end of capturing group \]\] # match two literal ]
>>> import re >>> re.sub(r'\[\[(?:[^|\]]*\|)?([^\]]*)]]', r'\1', line) 'is the combination of the code names for Herbicide Orange (HO) and Agent LNX, one of the herbicides and defoliants used by the U.S. military as part of its herbicidal warfare program, Operation Ranch Hand, during the Vietnam War from 1961 to 1971.'Пояснение:
Заменяя совпадения приведенного выше регулярного выражения содержимым группы захвата 1, вы получите содержимое квадратных скобок, но только то, что находится после разделителя, если он присутствует.\[\[ # match two opening square brackets (?: # start optional non-capturing group [^|\]]* # match any number of characters that are not '|' or ']' \| # match a '|' )? # end optional non-capturing group ( # start capture group 1 [^\]]* # match any number of characters that are not ']' ) # end capture group 1 ]] # match two closing square brackets
Вы можете использовать
re.sub, чтобы просто найти все между[[и]], и я думаю, что немного легче передать лямбда-функцию, чтобы сделать замену (взять все от последнего '|' и далее)>>> import re >>> re.sub(r'\[\[(.*?)\]\]', lambda L: L.group(1).rsplit('|', 1)[-1], line) 'is the combination of the code names for Herbicide Orange (HO) and Agent LNX, one of the herbicides and defoliants used by the U.S. military as part of its herbicidal warfare program, Operation Ranch Hand, during the Vietnam War from 1961 to 1971.'
Comments