Ошибка Python re.sub () для многострочной строки - PullRequest
0 голосов
/ 01 сентября 2018

У меня есть часть сценария, которая выглядит примерно так:

import re, sys
print(sys.version) # so you can see my Python version

repl = (
    "use bravo\\api\\resources\\usersResource;\n"
    "use bravo\\api\\resources\\groupsResource;\n"
    "use bravo\\api\\resources\\bandsResource;\n"
    "use bravo\\api\\resources\\setlistsResource;\n"
    "use bravo\\api\\resources\\songsResource;"
)

pattern = r'\{\{\$use_table_resources\}\}'
string = "{{$use_table_resources}}"

re.sub(pattern, repl, string)

Всякий раз, когда я запускаю его, я получаю следующий вывод и ошибку:

3.6.2 |Anaconda, Inc.| (default, Sep 19 2017, 08:03:39) [MSC v.1900 64 bit (AMD64)]
Traceback (most recent call last):
  File "test.py", line 15, in <module>
    re.sub(pattern, repl, string)
  File "C:\ProgramData\Anaconda3\lib\re.py", line 191, in sub
    return _compile(pattern, flags).sub(repl, string, count)
  File "C:\ProgramData\Anaconda3\lib\re.py", line 326, in _subx
    template = _compile_repl(template, pattern)
  File "C:\ProgramData\Anaconda3\lib\re.py", line 317, in _compile_repl
    return sre_parse.parse_template(repl, pattern)
  File "C:\ProgramData\Anaconda3\lib\sre_parse.py", line 904, in parse_template
    raise s.error("missing <")
sre_constants.error: missing < at position 64 (line 2, column 26)

Иногда это работает, когда я делаю заменяемую строку repl короче, но я действительно не могу понять это. Насколько я могу сказать, я работаю в рамках их ограничений, в соответствии с re.sub (...) API

Я знаю, что этот простой случай не оправдывает использование регулярных выражений, но этот фрагмент кода взят из гораздо большего программного обеспечения. Мне не нужны никакие ответы, говорящие мне, что регулярное выражение является неправильным подходом, потому что это на самом деле самый простой случай, который я мог бы привести, который все еще воспроизводит проблему. являются более сложными случаями, когда мне нужно, чтобы RegEx фактически выполнял свою работу.

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

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

1 Ответ

0 голосов
/ 01 сентября 2018

недостаточно замены в вашей замещающей строке, поэтому обратные слеши интерпретируются механизмом регулярных выражений как начало захваченной группы (как классический r"\1" или "\\1" без необработанного префикса).

Вы можете добавить необработанный префикс перед каждой строкой, но я бы предпочел использовать многострочные raw строки, подобные этой (проще для чтения):

repl = r"""use bravo\\api\\resources\\usersResource;
use bravo\\api\\resources\\groupsResource;
use bravo\\api\\resources\\bandsResource;
use bravo\\api\\resources\\setlistsResource;
use bravo\\api\\resources\\songsResource;
"""

тогда полученная замена будет

use bravo\api\resources\usersResource;
use bravo\api\resources\groupsResource;
use bravo\api\resources\bandsResource;
use bravo\api\resources\setlistsResource;
use bravo\api\resources\songsResource;

Теперь без изменения ввода:

использование re.escape подобно re.sub(pattern, re.escape(repl), string) работает не так хорошо, потому что пробел и конец строк также экранируются

Но вы можете сделать это, поскольку знаете, что единственными проблемными символами являются обратные слэши:

re.sub(pattern, repl.replace("\\",r"\\"), string)

(он заменяет обратную косую черту на двойную обратную косую черту, а вывод совпадает)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...