[英]Python RegEx Discrepancy vs Kodos and RegExr: Can't Filter Specific Character in Python
[英]Standard Regex vs python regex discrepancy
我正在讀一本書,它們提供了一個如何將給定字符串與正則表達式匹配的示例。 這是他們的例子:
b*(abb*)*(a|∊) - Strings of a's and b's with no consecutive a's.
現在,我嘗試將其轉換為python,如下所示:
>> p = re.compile(r'b*(abb*)*(a|)') # OR
>> p = re.compile(r'b*(abb*)*(a|\b)')
# BUT it still doesn't work
>>> p.match('aa')
<_sre.SRE_Match object at 0x7fd9ad028c68>
我的問題有兩個:
澄清:對於那些問什么標准正則表達式的人-這是形式語言理論標准: http : //en.wikipedia.org/wiki/Regular_expression#Formal_language_theory
實際上,該示例工作得很好……只是一個很小的細節。 我會寫:
>>> p = re.compile('b*(abb*)*a?')
>>> m = p.match('aa')
>>> print m.group(0)
'a'
>>> m = p.match('abbabbabababbabbbbbaaaaa')
>>> print m.group(0)
abbabbabababbabbbbba
請注意,組0返回與正則表達式匹配的字符串部分。
如您所見,該表達式匹配連續的a和b,而不重復a。 如果確實要檢查整個字符串,則需要稍作更改:
>>> p = re.compile('^b*(abb*)*a?$')
>>> m = p.match('aa')
>>> print m
None
^
和$
強制識別字符串的開頭和結尾。
最后,您可以使用第一個正則表達式來組合這兩種方法,但最后要進行測試:
>>> len(m.group(0)) == len('aa')
補充:對於OT的第二部分,在我看來,標准正則表達式與python實現之間沒有差異。 當然,表示法略有不同,並且python實現建議了一些擴展(與大多數其他軟件包一樣)。
感謝您的回答。 我覺得每個答案都有一部分答案。 這是我一直在尋找的東西。
? 符號只是(something |ε)的簡寫。 因此(a |ε)可以改寫為a? 。 因此,示例變為:
b*(abb*)*a?
在python中,我們將編寫:
p = re.compile(r'^b*(abb*)*a?$')
將正則表達式語法直接轉換為python(即復制和粘貼)不起作用的原因是,因為python匹配最短的子字符串 (如果沒有$或^符號),而理論上的正則表達式匹配最長的初始子字符串 。
例如,如果我們有一個字符串:
s = 'aa'
我們的教科書正則表達式b *(abb *)* a? 不會匹配,因為它有兩個a。 但是,如果我們直接將其復制到python:
>> p = re.compile(r'b*(abb*)*a?') >> bool(p.match(s)) True
這是因為我們的正則表達式僅匹配字符串“ aa”的子字符串“ a”。
為了告訴python在整個字符串上進行匹配,我們必須告訴它字符串的開頭和結尾在哪里,分別用^和$符號:
>> p = re.compile(r'^b*(abb*)*a?$') >> bool(p.match(s)) False
請注意,python regex match()在字符串的開頭匹配,因此它會自動在開頭假設^ 。 但是search()函數沒有,因此我們保留^ 。
因此,例如:
>> s = 'aa' >> p = re.compile(r'b*(abb*)*a?$') >> bool(p.match(s)) False # Correct >> bool(p.search(s)) True # Incorrect - search ignored the first 'a'
1個
使用bool(p.match('aa'))
檢查正則表達式是否匹配
p = re.compile('b*(abb*)*a?$')
\\b
匹配字符串的邊框; \\w
和\\W
之間的位置(單詞字符和非單詞字符)
2
正則表達式在python中是非常標准的。 但是每種語言都有它們的風格,它們不是100%可移植的。 在使用任何特定語言的regexp之前,您應該先查找一些細微的差異。
加成
\\epsilon
在python中沒有特殊符號。 它是一個空字符集。
在您的示例中a|\\epsilon
等效於(a|)
或只是a?
。 之后, $
必須匹配字符串的結尾。
我不完全確定match如何在python中工作,但我認為您可能需要在您的RE中添加^ .... $。 RegExp匹配通常匹配子字符串,並且在p.match('aa')為“ a”(可能是第一個)的情況下找到最大的匹配項。 ^ ... $確保您匹配整個字符串,我相信這是您想要的。
理論/標准正則表達式假定您始終匹配整個字符串,因為您使用它來定義匹配的字符串語言,而不是在輸入字符串中找到子字符串。
之所以匹配,是因為您的正則表達式匹配任何標本文本的任何零寬度段。 您需要錨定正則表達式。 這是一種使用零寬度超前斷言的方法:
re.compile(r'^(a(?!a)|b)*$')
據我所知,您的第二個回答應該是epsilon的合適替代品,盡管我以前從未在正則表達式中見過epsilon。
無論值多少,您的模式都匹配“ a”。 也就是說,它是匹配的:
b
”(選擇零) (abb*)
”(選擇零) a
”或單詞結尾(選擇a)。 正如喬納森·費恩伯格(Jonathan Feinberg)指出的那樣,如果要確保整個字符串匹配,則必須錨定正則表達式的開頭( '^'
)和結尾( '$'
)。 每當在python中構造正則表達式時,也應使用原始字符串:r'my regex'。 這樣可以防止過多的反斜杠避免混淆。
表達式的問題在於它與空字符串匹配,這意味着如果您這樣做:
>>> p = re.compile('b*(abb*)*(a|)')
>>> p.match('c').group(0)
''
並且由於re.match嘗試匹配字符串的開頭,因此您必須告訴它匹配它直到字符串的結尾。 只需使用$
>>> p = re.compile(r'b*(abb*)*(a|)$')
>>> print p.match('c')
None
>>> p.match('ababababab').group(0)
'ababababab'
ps-您可能已經注意到,我在此處更多使用r'pattern'而不是'pattern'(第一段)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.