Regex выдает или не выдает ошибку в зависимости от того, какой REPL используется

Рассмотрим следующий код Python, использующий библиотеку регулярных выражений re.

import re
re.compile(rf"{''.join(['{c}\\s*' for c in 'qqqq'])}")

Я запускал его в двух разных REPL:

https://www.pythonmorsels.com/repl/
https://www.online-python.com/#google_vignette

Первый из которых не выдает ошибки, а второй выдает следующую ошибку:

File "main.py", line 2
    re.compile(rf"{''.join(['{c}\\s*' for c in 'qqqq'])}")
               ^
SyntaxError: f-string expression part cannot include a backslash

Я хотел бы понять, почему иногда я получаю сообщение об ошибке, а не другие. Как я могу сузить именно то, в чем заключается разница?

Теперь попробуйте сам Python? А затем быстро подумайте над тем, что вы написали: rf не имеет смысла, потому что r означает «необработанная строка», т. е. все внутри разделителей буквально то, что есть, нет никакого скрытого значения, замен, экранирования и т. д., тогда как f означает «отформатированное». строка», где {...} делает прямо противоположное тому, что, по утверждению r, должно произойти. Но что еще более любопытно: ваш join уже формирует соответствующим образом определенную строку, зачем вам тогда заключать ее в пустую строку? Просто скажите re.compile(''.join(['{c}\\s*' for c in 'qqqq'])), готово.

Mike 'Pomax' Kamermans 30.06.2024 02:57

«Это из-за другой версии Python?» — спрашиваете вы, не удосужившись сообщить о версиях Python на машине вашего друга и на вашей.

Kaz 30.06.2024 02:58

@Kaz, спасибо, что указали на путаницу. Я упростил вопрос, сосредоточив внимание только на ответах. Пожалуйста, учтите это изменение.

Mathew 30.06.2024 03:23

@Mike'Pomax'Kamermans, согласен, это странная вещь, я не планирую использовать этот код, меня просто интересует тот факт, что есть разница в поведении одного репла и другого

Mathew 30.06.2024 03:25

Я не говорю, что это «странная вещь», я указываю на то, что это «невозможно сделать»: что-то не может быть «сырой и не сырой» строкой одновременно. Понимание того, почему два сервиса по-разному справляются с полной ерундой, нас ничему не учит. Если вам действительно интересно, вам следует посмотреть, что говорит Python, а затем связаться с сопровождающими службы, которая не генерирует правильный результат, чтобы они могли исправить свой веб-сайт.

Mike 'Pomax' Kamermans 30.06.2024 03:37

@Mike'Pomax'Kamermans Строки в «необработанном формате» имеют смысл, «необработанная» часть означает, что не интерпретируются символы обратной косой черты в строковой части, «отформатированный» означает, что существуют интерполированные выражения. Однажды я использовал строку «rf» для построения регулярного выражения (пожалуйста, не распинайте меня за часть регулярных выражений, я был молод и неопытен)

dragoncoder047 30.06.2024 04:33
Почему в 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
75
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Обойти проблему можно с помощью:

import re
re.compile("{0}".format(''.join([fr'{c}\s*' for c in 'qqqq'])))

Это работает для обоих предоставленных вами ответов. Он отправляет 'q\s*q\s*q\s*q\s*' для повторной компиляции.

Я предполагаю, что «\\s» предназначалось для сокращения до «\s».

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

Второй, выдающий синтаксическую ошибку, использует Python 3.8.5, который был до того, как в Python был добавлен PEP 701. PEP 701 наконец-то добавил f-строки в парсер Python 3.12, чтобы они могли содержать любое допустимое выражение, включающее строки с обратной косой чертой. Python до версии 3.12 постобрабатывает f-строки с помощью странного специального анализатора, который действительно сбивается с толку, когда видит обратную реакцию внутри части выражения.

Первый онлайн-REPL, который не выдает ошибок, работает под управлением Python 3.12.0.

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