Ссылки на именованные группы при просмотре (Python 2.x)

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

Я понял, как разрешить динамические разделители и ограничить использование одного и того же разделителя дважды. НАПРИМЕР:

\w+(?P<kv_delim>[:;|])\d+(?P<g_delim>(?!(?P=kv_delim))[:;|])\w(?P=kv_delim)\d(?P=g_delim)?

Вы можете просмотреть пример regex101.com здесь. И это прекрасно работает, проблема возникает при использовании любой из двух именованных групп в позитивном ретроспективном анализе.

Допустим, строка

foo:1;r:2

«Разделитель ключ/значение» (группа с именем: kv_delim) — это :, затем «разделитель группы» (группа с названием: grp_delim) — это ;.

Что я пытаюсь сделать, так это динамически сопоставлять : и ;, а затем в операторе поиска искать foo<kv_delim> или bar<kv_delim>.

Если я жестко запрограммирую разделители (в обзоре), вы увидите, что это работает. Но если я попытаюсь сослаться на именованную группу kv_delim в операторе поиска, вы увидите, что это выдает ошибки< /а>. Я получаю сообщение об ошибке:

Ссылки на подшаблоны не допускаются в утверждении просмотра назад.

Это то, что пинает мою задницу

У кого-нибудь есть способ сделать эту работу?

Спасибо!


person Justin    schedule 12.09.2016    source источник
comment
Просто используйте . вместо обратной ссылки.   -  person Aran-Fey    schedule 12.09.2016
comment
Просто разделите текст на несколько строк. Попытка разобрать строку с помощью одного регулярного выражения, как это, обычно приводит к непонятному и неподдерживаемому коду.   -  person    schedule 12.09.2016
comment
В документации четко указано как для отрицательного, так и для положительного взгляда -behind утверждает, что Содержащийся шаблон должен соответствовать только строкам некоторой фиксированной длины.   -  person    schedule 12.09.2016
comment
Чего вы пытаетесь достичь, на самом деле? Возможно, вы ищете \G, который поддерживается только более новым модулем regex.   -  person Jan    schedule 12.09.2016


Ответы (1)


Подводя итог уже сказанному: дело в том, что длина шаблона неизвестна, когда вы помещаете обратные ссылки в lookbehind, который должен иметь фиксированную ширину во время разработки. Более новый модуль PyPi regex не имеет ограничений в отношении длины просмотра назад, поэтому текущий обходной путь заключается в использовании этот модуль с вашим регулярным выражением:

>>> import regex
>>> s = "foo:1;r:2"
>>> rx = r"\w+(?P<kv_delim>[:;|])\d+(?P<g_delim>(?!(?P=kv_delim))[:;|])\w(?P=kv_delim)\d(?P=g_delim)?"
>>> print(regex.findall(rx, s))
[(':', ';')]
>>> print([m.group() for m in regex.finditer(rx, s)])
['foo:1;r:2']
>>> 
person Wiktor Stribiżew    schedule 28.09.2016