确定正则表达式是否只匹配固定长度字符串
有没有一种方法可以确定正则表达式是否只匹配固定长度字符串? 我的想法是扫描*,+和?然后,需要一些智能逻辑来寻找其中m!= n的{m,n}。 没有必要采取|运营商考虑在内。
小例子:^ \ d {4}是固定长度的;^\ d {4,5}或^ \ d +是可变长度确定正则表达式是否只匹配固定长度字符串
我正在使用PCRE。
谢谢。
保罗Praet
嗯,你可以利用一个事实,即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
我在C编码,使用PCRE库......无论如何:-) – 2010-09-02 15:53:28
根据regular-expressions.info,所述PCRE发动机仅支持固定长度的正则表达式和交替内部lookbehinds。
所以,如果你有一个有效的正则表达式,围绕它与(?<=
和)
并看看它是否仍然编译。然后你知道它是固定大小的还是固定大小的正则表达式的交替。
我不确定类似a(b|cd)e
的东西 - 这绝对不是固定大小的,但它仍然可以编译。你需要尝试一下(我没有安装C/PCRE)。
只是为了好玩。
假设我们反对只测试正则表达式支持+
,*
,?
,{m,n}
,{n}
和[...]
(除了一些奇怪的语法像[]]
和[^]]
)。那么正则表达式是仅当它跟随语法固定长度:
REGEX -> ELEMENT *
ELEMENT -> CHARACTER ('{' (\d+) (',' \1)? '}')?
CHARACTER -> [^+*?\\\[] | '\\' . | '[' ('\\' . | [^\\\]])+ ']'
可以在PCRE被重写为:
^(?:(?:[^+*?\\\[{]|\\.|\[(?:\\.|[^\\\]])+\])(?:\{(\d+)(?:,\1)?\})?)*$
我承认我不知道你的意思;-) 你的意思是正则表达式本身应该匹配上面的表达式? – 2010-09-02 19:57:08
编程? – kennytm 2010-09-02 13:32:59
用另一个正则表达式? :) – Ani 2010-09-02 13:39:28
它肯定有必要考虑'|'。毕竟,正则表达式'/ ab | c /'的固定长度是多少? – 2010-09-02 13:45:03