Python 3.7.4: 're.error: bad escape \ s в позиции 0' - PullRequest
0 голосов
/ 10 октября 2019

Моя программа выглядит примерно так:

import re
# Escape the string, in case it happens to have re metacharacters
my_str = "The quick brown fox jumped"
escaped_str = re.escape(my_str)
# "The\\ quick\\ brown\\ fox\\ jumped"
# Replace escaped space patterns with a generic white space pattern
spaced_pattern = re.sub(r"\\\s+", r"\s+", escaped_str)
# Raises error

Ошибка такая:

Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/home/swfarnsworth/programs/pycharm-2019.2/helpers/pydev/_pydev_bundle/pydev_umd.py", line 197, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
  File "/home/swfarnsworth/programs/pycharm-2019.2/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "/home/swfarnsworth/projects/medaCy/medacy/tools/converters/con_to_brat.py", line 255, in <module>
    content = convert_con_to_brat(full_file_path)
  File "/home/swfarnsworth/projects/my_file.py", line 191, in convert_con_to_brat
    start_ind = get_absolute_index(text_lines, d["start_ind"], d["data_item"])
  File "/home/swfarnsworth/projects/my_file.py", line 122, in get_absolute_index
    entity_pattern_spaced = re.sub(r"\\\s+", r"\s+", entity_pattern_escaped)
  File "/usr/local/lib/python3.7/re.py", line 192, in sub
    return _compile(pattern, flags).sub(repl, string, count)
  File "/usr/local/lib/python3.7/re.py", line 309, in _subx
    template = _compile_repl(template, pattern)
  File "/usr/local/lib/python3.7/re.py", line 300, in _compile_repl
    return sre_parse.parse_template(repl, pattern)
  File "/usr/local/lib/python3.7/sre_parse.py", line 1024, in parse_template
    raise s.error('bad escape %s' % this, len(this))
re.error: bad escape \s at position 0

Я получаю эту ошибку, даже если я удаляю две обратные косые черты до '\s+' илиесли я сделаю необработанную строку (r"\\\s+") в обычную строку. Я проверил документацию по Python 3.7, и оказалось, что \s все еще является escape-последовательностью для пробелов.

Ответы [ 3 ]

2 голосов
/ 10 октября 2019

Попробуйте поиграться с обратными слешами, чтобы избежать того, что регулярное выражение пытается интерпретировать \s:

spaced_pattern = re.sub(r"\\\s+", "\\\s+", escaped_str)

сейчас

>>> spaced_pattern
'The\\s+quick\\s+brown\\s+fox\\s+jumped'
>>> print(spaced_pattern)
The\s+quick\s+brown\s+fox\s+jumped

Но почему?

Кажется, что python пытается интерпретировать \s так, как он интерпретирует r"\n" вместо того, чтобы оставить его в покое, как это обычно делает Python. Если вы делаете. Например:

re.sub(r"\\\s+", r"\n+", escaped_str)

выход:

The
+quick
+brown
+fox
+jumped

, даже если \n использовалось в необработанной строке.

Изменение было введено в Проблема# 27030: Неизвестные экранированные символы, состоящие из '\' и буквы ASCII в

Код, выполняющий замену, находится в sre_parse.py (python 3.7):

        else:
            try:
                this = chr(ESCAPES[this][1])
            except KeyError:
                if c in ASCIILETTERS:
                    raise s.error('bad escape %s' % this, len(this))

Этот кодищет то, что стоит за литералом \ и пытается заменить его на соответствующий не-ascii символ. Очевидно, что s нет в словаре ESCAPES, поэтому срабатывает исключение KeyError, а затем появляется сообщение.

В предыдущих версиях просто выдавалось предупреждение:

import warnings
warnings.warn('bad escape %s' % this,
              DeprecationWarning, stacklevel=4)

Похоже, мы не одни страдаем от 3,6 до 3,7 апгрейда: https://github.com/gi0baro/weppy/issues/227

1 голос
/ 10 октября 2019

Движки Regex ведут себя так же (в основном), когда дело доходит до заменяющих строк
, которые им передаются.
Они пытаются вставить управляющий код, эквивалентный экранированным символам, таким как табуляция crlf и т. Д.
Любая последовательность побега, которую он не распознает, она просто убирает побег.

Учитывая
spaced_pattern = re.sub(r"\\\s+", r"\s+", escaped_str)

r"\s+" вручает двигателю эту заменяющую строку \s+.
Поскольку такой escape-последовательности нет, она просто удаляет escape
и вставляет s+ в положение замены.

Вы можете увидеть это здесь https://regex101.com/r/42QCvi/1
Не выдается никакой ошибки, но это должно произойти, так как вы не получаете то, что, как вы думаете, вы должны.

На самом деле буквальный побег всегда должен быть экранирован
, как можно увидеть здесь https://regex101.com/r/bzQgfN/1

Ничего нового, они просто говорят, что это ошибка, но это действительноУведомление, предупреждающее
о том, что вы не получаете того, о чем думаете.
Так было годами и годами. Иногда это ошибка, иногда нет.

0 голосов
/ 10 октября 2019

Полагаю, вы, возможно, пытаетесь это сделать:

import re
# Escape the string, in case it happens to have re metacharacters
my_str = "The\\ quick\\ brown\\ fox\\ jumped"
escaped_str = re.escape(my_str)
# "The\\ quick\\ brown\\ fox\\ jumped"
# Replace escaped space patterns with a generic white space pattern
print(re.sub(r"\\\\\\\s+", " ", escaped_str))

Вывод 1

The quick brown fox jumped

Если вы хотите использовать литерал \ s +, попробуйте этот ответ или возможно:

import re
# Escape the string, in case it happens to have re metacharacters
my_str = "The\\ quick\\ brown\\ fox\\ jumped"
escaped_str = re.escape(my_str)
print(re.sub(r"\\\\\\\s+", re.escape(r"\s") + '+', escaped_str))

Выход 2

The\s+quick\s+brown\s+fox\s+jumped

Или может быть:

import re
# Escape the string, in case it happens to have re metacharacters
my_str = "The\\ quick\\ brown\\ fox\\ jumped"
print(re.sub(r"\s+", "s+", my_str))

Выход 3

The\s+quick\s+brown\s+fox\s+jumped

Если вы хотите упростить / изменить / изучить выражение, это было объяснено на верхней правой панели regex101.com . Если хотите, вы также можете посмотреть в эту ссылку , как она будет сопоставляться с некоторыми примерами ввода.


RegEx Circuit

jex.im визуализирует регулярные выражения:

enter image description here

Демо

...