[英]matching all characters in any order in regex
我是一個正則表達式新手,但我理解如何按順序匹配正則表達式查詢中的任何字符(例如[abc]將匹配a,b或c中的任何一個。另外,我相信“abc”將完全匹配abc)。
但是,如何構造一個匹配所有字符abc的正則表達式查詢? 例如,我希望它匹配“cab”或“bracket”。 我使用Python作為我的腳本語言(不確定這是否重要)。
在Python中,我不會為此目的使用regualar表達式,而是使用set:
>>> chars = set("abc")
>>> chars.issubset("bracket")
True
>>> chars.issubset("fish")
False
>>> chars.issubset("bad")
False
正則表達式很有用,但有些情況下不同的工具更合適。
這可以通過先行斷言來完成:
^(?=.*a)(?=.*b)(?=.*c)
如果您的字符串包含至少一個a
, b
和c
匹配項,則匹配。
但正如你所看到的,那並不是正則表達式所擅長的。
我會做的:
if all(char in mystr for char in "abc"):
# do something
檢查速度:
>>> timeit.timeit(stmt='chars.issubset("bracket");chars.issubset("notinhere")',
... setup='chars=set("abc")')
1.3560583674019995
>>> timeit.timeit(stmt='all(char in "bracket" for char in s);all(char in "notinhere" for char in s)',
... setup='s="abc"')
1.4581878714681409
>>> timeit.timeit(stmt='r.match("bracket"); r.match("notinhere")',
... setup='import re; r=re.compile("(?=.*a)(?=.*b)(?=.*c)")')
1.0582279123082117
嘿,看,正則表達勝利! 這甚至適用於較長的搜索字符串:
>>> timeit.timeit(stmt='chars.issubset("bracketed");chars.issubset("notinhere")',
... setup='chars=set("abcde")')
1.4316702294817105
>>> timeit.timeit(stmt='all(char in "bracketed" for char in s);all(char in "notinhere" for char in s)',
... setup='s="abcde"')
1.6696223364866682
>>> timeit.timeit(stmt='r.match("bracketed"); r.match("notinhere")',
... setup='import re; r=re.compile("(?=.*a)(?=.*b)(?=.*c)(?=.*d)(?:.*e)")')
1.1809254199004044
import re
def using_lookahead(text):
pat=re.compile(r'^(?=.*a)(?=.*b)(?=.*c)')
return pat.search(text)
def using_set(text):
chars=set('abc')
return chars.issubset(text)
對於小字符串, issubset
可能會稍快一點:
% python -mtimeit -s'import test' "test.using_set('bracket')"
100000 loops, best of 3: 2.63 usec per loop
% python -mtimeit -s'import test' "test.using_lookahead('bracket')"
100000 loops, best of 3: 2.87 usec per loop
對於長字符串,正則表達式顯然更快:
比賽來晚了:
% python -mtimeit -s'import test' "test.using_set('o'*1000+'bracket')" 10000 loops, best of 3: 49.7 usec per loop % python -mtimeit -s'import test' "test.using_lookahead('o'*1000+'bracket')" 100000 loops, best of 3: 6.66 usec per loop
比賽來得早:
% python -mtimeit -s'import test' "test.using_set('bracket'+'o'*1000)" 10000 loops, best of 3: 50 usec per loop % python -mtimeit -s'import test' "test.using_lookahead('bracket'+'o'*1000)" 100000 loops, best of 3: 13.9 usec per loop
(要回答評論中的問題:) r'^(?=.*a)(?=.*b)(?=.*c)'
可用於表示匹配:
In [40]: pat=re.compile(r'^(?=.*a)(?=.*b)(?=.*c)')
In [41]: pat.search('bracket')
Out[41]: <_sre.SRE_Match object at 0x9f9a6b0>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.