2010-09-02 51 views
3

有沒有一種方法可以確定正則表達式是否只匹配固定長度字符串? 我的想法是掃描*,+和?然後,需要一些智能邏輯來尋找其中m!= n的{m,n}。 沒有必要採取|運營商考慮在內。
小例子:^ \ d {4}是固定長度的;^\ d {4,5}或^ \ d +是可變長度確定正則表達式是否只匹配固定長度字符串

我正在使用PCRE。

謝謝。

保羅Praet

+2

編程? – kennytm 2010-09-02 13:32:59

+0

用另一個正則表達式? :) – Ani 2010-09-02 13:39:28

+0

它肯定有必要考慮'|'。畢竟,正則表達式'/ ab | c /'的固定長度是多少? – 2010-09-02 13:45:03

回答

4

嗯,你可以利用一個事實,即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 
+0

我在C編碼,使用PCRE庫......無論如何:-) – 2010-09-02 15:53:28

0

根據regular-expressions.info,所述PCRE發動機僅支持固定長度的正則表達式和交替內部lookbehinds。

所以,如果你有一個有效的正則表達式,圍繞它與(?<=)並看看它是否仍然編譯。然後你知道它是固定大小的還是固定大小的正則表達式的交替。

我不確定類似a(b|cd)e的東西 - 這絕對不是固定大小的,但它仍然可以編譯。你需要嘗試一下(我沒有安裝C/PCRE)。

1

只是爲了好玩。

假設我們反對只測試正則表達式支持+*?{m,n}{n}[...](除了一些奇怪的語法像[]][^]])。那麼正則表達式是僅當它跟隨語法固定長度:

REGEX  -> ELEMENT * 
ELEMENT -> CHARACTER ('{' (\d+) (',' \1)? '}')? 
CHARACTER -> [^+*?\\\[] | '\\' . | '[' ('\\' . | [^\\\]])+ ']' 

可以在PCRE被重寫爲:

^(?:(?:[^+*?\\\[{]|\\.|\[(?:\\.|[^\\\]])+\])(?:\{(\d+)(?:,\1)?\})?)*$ 
+1

我承認我不知道你的意思;-) 你的意思是正則表達式本身應該匹配上面的表達式? – 2010-09-02 19:57:08

相關問題