Что ж, вы могли бы использовать тот факт, что механизм регулярных выражений Python допускает только регулярные выражения фиксированной длины в утверждениях просмотра назад:
import re
regexes = [r".x{2}(abc|def)", # fixed
r"a|bc", # variable/finite
r"(.)\1", # fixed
r".{0,3}", # variable/finite
r".*"] # variable/infinite
for regex in regexes:
try:
r = re.compile("(?<=" + regex + ")")
except:
print("Not fixed length: {}".format(regex))
else:
print("Fixed length: {}".format(regex))
будет выводить
Fixed length: .x{2}(abc|def)
Not fixed length: a|bc
Fixed length: (.)\1
Not fixed length: .{0,3}
Not fixed length: .*
Я предполагаю, что само регулярное выражение действительно.
Теперь, как Python узнает, имеет ли регулярное выражение фиксированную длину или нет? Просто прочитайте исходный код — в sre_parse.py
есть метод getwidth()
, который возвращает кортеж, состоящий из наименьшей и наибольшей возможной длины, и если они не равны в утверждении просмотра назад, re.compile()
вызовет ошибку. Метод getwidth()
рекурсивно проходит через регулярное выражение:
def getwidth(self):
# determine the width (min, max) for this subpattern
if self.width:
return self.width
lo = hi = 0
UNITCODES = (ANY, RANGE, IN, LITERAL, NOT_LITERAL, CATEGORY)
REPEATCODES = (MIN_REPEAT, MAX_REPEAT)
for op, av in self.data:
if op is BRANCH:
i = sys.maxsize
j = 0
for av in av[1]:
l, h = av.getwidth()
i = min(i, l)
j = max(j, h)
lo = lo + i
hi = hi + j
elif op is CALL:
i, j = av.getwidth()
lo = lo + i
hi = hi + j
elif op is SUBPATTERN:
i, j = av[1].getwidth()
lo = lo + i
hi = hi + j
elif op in REPEATCODES:
i, j = av[2].getwidth()
lo = lo + int(i) * av[0]
hi = hi + int(j) * av[1]
elif op in UNITCODES:
lo = lo + 1
hi = hi + 1
elif op == SUCCESS:
break
self.width = int(min(lo, sys.maxsize)), int(min(hi, sys.maxsize))
return self.width
person
Tim Pietzcker
schedule
02.09.2010
|
. В конце концов, какова фиксированная длина регулярного выражения/ab|c/
? - person Philip Potter   schedule 02.09.2010