Регулярное выражение Python не соответствует тому, что соответствует другим инструментам регулярных выражений

У меня есть следующий код:

currencies = ['USD', 'GBP', 'EUR', 'JPY', 'CHF', 'SEK', 'DKK', 'NOK', 'SGD', 'HKD', 'AUD', 'TWD', 'NZD', 'CNY', 'KRW', 'INR', 'CAD', 'VEF', 'EGP', 'THB', 'IDR', 'PKR', 'MYR', 'PHP', 'MXN', 'VND', 'CZK', 'HUF', 'PLN', 'TRY', 'ZAR', 'ILS', 'ARS', 'CLP', 'BRL', 'RUB', 'QAR', 'AED', 'COP', 'PEN', 'CNH', 'KWD', 'SAR']
exclusive_regexp = ".*/" + ".*|.*/".join(currencies) + ".*"
searching_regexp = "^(?! (" + exclusive_regexp + ")$)(.*/.*)$"
searching_regexp = re.compile(searching_regexp) 


with open('raw.txt', 'r') as unprocessed_ticks:
    print(re.findall(searching_regexp, unprocessed_ticks.read()))

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

Я проверил сгенерированное регулярное выражение с помощью онлайн-инструмента regex101.com. он работает с ароматом python. Но в реальном коде он ничему не соответствует: https://regex101.com/r/70uiuE/7 Почему это может произойти?

подозреваю re.findall(searching_regexp, unprocessed_ticks.read(), re.M)

Wiktor Stribiżew 28.05.2019 18:55

Разве \ не escape-символ в python, поэтому вам нужно дважды экранировать его?

Bob Vale 28.05.2019 18:57

Какой текст вы ожидаете, что это будет соответствовать? Косая черта не должна быть экранирована обратной косой чертой в Python.

tripleee 28.05.2019 18:59

.*, который вы так щедро посыпаете, вероятно, приводит к тому, что это соответствует более, чем вы предполагали.

tripleee 28.05.2019 19:00

Думаю, exclusive_regexp = "/(?:{})".format("|".join(currencies)) с searching_regexp = "^(?! .*" + exclusive_regexp + ")[^/]*/.*$" тоже сработает. Просто передайте re.M флаг.

Wiktor Stribiżew 28.05.2019 19:02

@WiktorStribiżew работает, спасибо! Не могли бы вы сформировать это как ответ? Я закрою вопрос, выбрав ваш ответ.

Bogdan Lashkov 28.05.2019 19:05
Почему в 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
6
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Несколько моментов:

  • Нет необходимости экранировать / в Python (и любых других) шаблонах нить (/ следует экранировать только тогда, когда регулярное выражение установлено через литерал регулярного выражения с косой чертой, используемой в качестве разделителей регулярных выражений)
  • Вы злоупотребляете шаблоном .*, вам следует свести к минимуму количество альтернатив, совпадающих в одном и том же месте в строке.
  • Чтобы ^ и $ соответствовали началу и концу строки, вы должны передать флаг re.M или re.MULTILINE регулярному выражению.

Я предлагаю изменить регулярные выражения на

exclusive_regexp = r"/(?:{})".format("|".join(currencies))
searching_regexp = re.compile(r"^(?! .*" + exclusive_regexp + ")[^/\n]*/.*", re.M) 

а потом

print(searching_regexp.findall(unprocessed_ticks.read()))

Регулярное выражение exclusive_regexp теперь будет выглядеть аккуратнее (/(?:USD|GBP|EUR|JPY|CHF|SEK|DKK|NOK|SGD|HKD|AUD|TWD|NZD|CNY|KRW|INR|CAD|VEF|EGP|THB|IDR|PKR|MYR|PHP|MXN|VND|CZK|HUF|PLN|TRY|ZAR|ILS|ARS|CLP|BRL|RUB|QAR|AED|COP|PEN|CNH|KWD|SAR)), а searching_regexp будет соответствовать любой строке, которая начинается с 0+ символов, кроме /, затем содержит /, а затем любое количество любых символов, кроме новой строки ([^/\n]*/.*), которая не начинается с пробела. , / и значение валюты.

См. демонстрация Python.

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