Подтвердить что ты не робот

Регулярные выражения Python с более чем 100 группами?

Есть ли способ преодолеть ограничение в 100 групп для регулярных выражений в Python? Кроме того, кто-то может объяснить, почему есть предел.

4b9b3361

Ответ 1

Я не уверен, что вы делаете в точности, но попробуйте использовать одну группу с большим количеством предложений OR внутри... так что (this) | (that) становится (this | that). Вы можете делать умные вещи с результатами, передавая функцию, которая делает что-то с конкретным словом, которое соответствует:

 newContents, num = cregex.subn(lambda m: replacements[m.string[m.start():m.end()]], contents)

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

Ответ 2

Существует предел, потому что для сохранения полного состояния машины требуется слишком много памяти. Я бы сказал, что если у вас в вашей группе более 100 групп, что-то не так, как в самом re, так и в том, как вы их используете. Возможно, вам нужно разбить вход и работать с меньшими кусками или чем-то еще.

Ответ 3

Я нашел самый простой способ:

import regex as re

вместо

import re

По умолчанию _MAXCACHE для regex - 500 вместо 100. Это одна из многих причин, по которым я нахожу регулярное выражение лучшим модулем, чем re.

Ответ 4

Если я не ошибаюсь, модуль "новый" regex (в настоящее время сторонний, но предназначенный, чтобы в конечном итоге заменить re модуль в stdlib) не имеет этого предела, поэтому вы можете попробовать попробовать.

Ответ 5

Я сомневаюсь, что вам действительно нужно обработать 100 именованных групп следующими командами или использовать их в команде regexp replacement. Это было бы непрактично. Если вам просто нужны группы, чтобы выразить богатые условия в regexp, вы можете использовать группу без группировки.

(?:word1|word2)(?:word3|word4)

и т.д.. Возможны сложные сценарии, включая группы вложенности. Для групп без группировки нет предела.

Ответ 6

Во-первых, как говорили другие, есть, вероятно, хорошие альтернативы использованию 100 групп. Метод re.findall может быть полезным для начала. Если вам действительно нужно более 100 групп, единственным обходным решением, которое я вижу, является изменение основного кода Python.

В [python-install-dir]/lib/sre_compile.py просто измените функцию compile(), удалив следующие строки:

# in lib/sre_compile.py
if pattern.groups > 100:
    raise AssertionError(
        "sorry, but this version only supports 100 named groups"
        )

Для немного более гибкой версии просто определите константу в верхней части модуля sre_compile и сравните приведенную выше строку с этой константой вместо 100.

Как ни странно, в источнике (Python 2.5) есть комментарий, указывающий, что в будущих версиях планируется удалить 100-групповой лимит.

Ответ 7

Когда я сталкивался с этим, у меня был очень сложный шаблон, который фактически состоял из кучки высокоуровневых шаблонов, соединенных с ORs, например:

pattern_string = u"pattern1|" \
    u"pattern2|" \
    u"patternN"
pattern = re.compile(pattern_string, re.UNICODE)

for match in pattern.finditer(string_to_search):
    pass # Extract data from the groups in the match.

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

pattern_strings = [
    u"pattern1",
    u"pattern2",
    u"patternN",
]
patterns = [re.compile(pattern_string, re.UNICODE) for pattern_string in pattern_strings]

for pattern in patterns:
    for match in pattern.finditer(string_to_search):
        pass # Extract data from the groups in the match.
    string_to_search = pattern.sub(u"", string_to_search)

Ответ 8

Я обнаружил, что Python 3 не имеет этого ограничения, тогда как тот же код, запущенный в последних 2.7, отображает эту ошибку.

Ответ 9

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

Ответ 10

в моем случае, у меня есть словарь из n слов и вы хотите создать одно регулярное выражение, которое соответствует всем им.. то есть: если мой словарь

hello
goodbye

мое регулярное выражение было бы следующим: (^|\s)hello($|\s)|(^|\s)goodbye($|\s)... это единственный способ сделать это, и отлично работает на небольших словарях, но когда у вас есть более 50 слов, хорошо...

Ответ 11

Очень легко решить эту ошибку: Откройте класс re, и вы увидите эту константу _MAXCACHE = 100. Измените значение на 1000, например, и выполните тест.