Есть ли способ преодолеть ограничение в 100 групп для регулярных выражений в Python? Кроме того, кто-то может объяснить, почему есть предел.
Регулярные выражения Python с более чем 100 группами?
Ответ 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
, например, и выполните тест.