Я новичок в мире regex.
Поэтому я сожалею, если это может показаться основным. Я закончил чтение сообщества регулярных выражений и книгу Лопеса о регулярном выражении для Python, чтобы убедиться, что я не отправляю вопрос начального уровня.
Я очистил данные из вики (для обучения), и я пытаюсь извлечь строки
a), которые начинаются с \wiki
б) которые не содержат :
Здесь текст:
/wiki/Template:Kevin_Bacon
/wiki/Category:Best_Miniseries_or_Television_Movie_Actor_Golden_Globe_winners
/wiki/Al_Pacino
/wiki/Paul_Giamatti
/wiki/Kevin_Costner
/wiki/Kevin_Costner
/wiki/Michael_Douglas
/wiki/Mark_Ruffalo
/wiki/Idris_Elba
/wiki/Bryan_Cranston
/wiki/Alexander_Skarsg%C3%A5rd
/wiki/Biblioteca_Nacional_de_Espa%C3%B1a
/wiki/Template:Kevin_Bacon
https://hy.wikipedia.org/wiki/%D5%94%D6%87%D5%AB%D5%B6_%D4%B2%D5%A5%D5%B5%D6%84%D5%B8%D5%B6
Вывод должен быть сгруппирован, т.е. я должен получить список (или кортеж) этих строк:
/wiki/Al_Pacino
/wiki/Paul_Giamatti
/wiki/Kevin_Costner
/wiki/Kevin_Costner
/wiki/Michael_Douglas
/wiki/Mark_Ruffalo
/wiki/Idris_Elba
/wiki/Bryan_Cranston
/wiki/Alexander_Skarsg%C3%A5rd
/wiki/Biblioteca_Nacional_de_Espa%C3%B1a
Вот мои попытки извлечь строки:
a) Использование негативного r^/wiki/.*(?!:).*
: идея состоит в том, чтобы не выбирать строку, за которой следует :
r^/wiki/.*(?!:).*
Однако выше код по-прежнему выбирает строки с помощью :
ie /wiki/Template:Kevin_Bacon
b) ^/wiki/.*[^:].*
регулярное выражение, чтобы не выбирать :
^/wiki/.*[^:].*
Однако выше код по-прежнему выбирает строки с помощью :
ie /wiki/Template:Kevin_Bacon
c) Использовать квантификатор, чтобы указать, что :
должно происходить нулевое время ^/wiki/.*:{0}.*$
Однако выше код по-прежнему выбирает строки с помощью :
ie /wiki/Template:Kevin_Bacon
У меня есть два вопроса:
a) Мне очень нравится regex
. Может кто-нибудь объяснить, что неправильно с помощью вышеуказанных попыток?
б) Как я могу решить проблему, используя вышеуказанные подходы?
Я собираюсь использовать модуль regex
в python. В соответствии с рекомендациями SO я пытался отлаживать regex
на regex101
сайте regex101
. Здесь ссылка: https://regex101.com/r/Wt40Cz/1
Я искренне ценю любую помощь. Заранее спасибо.
Ваше регулярное выражение неверно.
^/wiki/.*[^:].*
анализируется следующим образом:
^
: соответствие началу строки/wiki/
: соответствие буквенной последовательности /wiki/
.*
: совпадение нуля или более любого символа[^:]
: сопоставить все, что не является :
.*
: совпадение нуля или более любого символаТак что
/wiki/
(ok):
", если последний символ не является :
(хм...) Поэтому ваше регулярное выражение заканчивается совпадением всей строки из-за .*
, Даже не проверяя :
кроме как в конце.
Теперь посмотрим, что делает правильное выражение
^\/wiki\/[^:]+$
^
: соответствие началу строки/wiki/
: соответствие буквенной последовательности /wiki/
[^:]+
: сопоставить одно или несколько из ничего, что не является :
$
: совпадение с концом строки
/wiki/
(ok):
в этом случае она не выполняетсяНадеюсь, это поможет вам лучше разобраться. Я настоятельно рекомендую https://www.regex101.com для создания и тестирования регулярных выражений (он имеет режим регулярного выражения, совместимый с Python), поскольку он также включает в себя объяснение того, что движок регулярного выражения делает шаг за шагом.
Изменение: чтобы ответить на второй вопрос, я не вижу другого разумного способа построения этого выражения. Не используйте lookaheads или quantifiers, что не для этого.
.*
Будет соответствовать 0 or more
символам, пока не достигнет [^:]
, когда он вернется назад и вообще исключит эту строку? Я не понял вашу пулю № 3. Если то, что вы сказали, верно, то не следует выбирать строки с помощью :
Из ссылки на regex101
я разместил, этого не происходит. Буду признателен за ваши мысли.
Попробуйте regex ^\/wiki\/[^:]*?$
Он будет соответствовать строке, начинающейся с /wiki/
а затем этой [^:]*?
будет соответствовать символам без :
до конца $
В вашем регулярном выражении ^/wiki/.*[^:].*$
было два .*
Так что :
будет сбежать с любым из .*
.So, [^:]*
будет достаточно, чтобы захватить все
^\/wiki\/[^:]+?$
.*
До и после «исключения двоеточия», то есть[^:]
. Я пытаюсь выучить логику. Заранее спасибо.