2009-09-03 66 views
22

有沒有一種方法可以找出Python中的字符串中有多少匹配正則表達式?例如,如果我有字符串"It actually happened when it acted out of turn."找出在Python中的字符串匹配正則表達式的次數

我想知道"t a"在字符串中出現了多少次。在該字符串中,"t a"出現兩次。我希望我的功能告訴我它出現了兩次。這可能嗎?

+0

您是否需要計算重疊匹配?在字符串「朋友的朋友的朋友」中,正則表達式是「朋友的朋友」一次還是兩次? – 2009-09-03 16:52:02

+0

我需要重疊。 – Dan 2009-09-03 18:20:16

+2

你需要重疊?所以,如果匹配模式是「aa」並且源字符串是「aaaa」,那麼正確答案是3? – steveha 2009-09-03 19:20:38

回答

16

現有解決方案的基礎上findall的數量都很好,不重疊的比賽(和可能除了比賽的數量龐大無疑最佳),儘管sum(1 for m in re.finditer(thepattern, thestring))等替代方案(爲了避免在您關心的所有人都在計數時實現列表)也很有可能。有些特質將使用subn並忽略生成的字符串...:

def countnonoverlappingrematches(pattern, thestring): 
    return re.subn(pattern, '', thestring)[1] 

後者想法的唯一真正好處會來,如果你只關心數(比如說)多達100場比賽;那麼,re.subn(pattern, '', thestring, 100)[1]可能是實際的(返回100是否有100個匹配,或1000,或甚至更大的數字)。

計數重疊匹配需要您編寫更多代碼,因爲所討論的內置函數都集中在非重疊匹配上。還有一個定義問題,例如模式爲'a+',字符串爲'aa',你會認爲這只是一個匹配,或三個(第一個a,第二個,他們兩個),還是......?

假設例如你想可能重疊比賽開始在字符串在踩點(然後將給出的例子兩場比賽在上段):

def countoverlappingdistinct(pattern, thestring): 
    total = 0 
    start = 0 
    there = re.compile(pattern) 
    while True: 
    mo = there.search(thestring, start) 
    if mo is None: return total 
    total += 1 
    start = 1 + mo.start() 

注意,你做必須在這種情況下將模式編譯爲RE對象:函數re.search不接受start參數(搜索的起始位置)方法方法search確實如此,因此您必須在切換時切入字符串 - 絕對比下一次搜索更努力在下一個可能的不同的起點,這是我在做這個功能。

6

你有沒有試過?

len(pattern.findall(source)) 
+1

它是findall雖然 – cobbal 2009-09-03 16:24:33

+0

感謝您修復它! – 2009-09-03 16:42:20

+0

這是否重疊?他表示需要支持這一點。 (看起來好像很難執行) – 2009-09-03 19:20:20

30
import re 
len(re.findall(pattern, string_to_search)) 
+0

偉大的工作!!!謝謝 – 2016-03-30 16:09:00

0
import re 
print len(re.findall(r'ab',u'ababababa')) 
9

我知道這是一個關於正則表達式的問題。我只是想如果有人想要一個非正則表達式的解決方案,我會提及count方法供將來參考。

>>> s = "It actually happened when it acted out of turn." 
>>> s.count('t a') 
2 

這回不重疊出現的子

5

您可以通過使用非捕獲子模式重疊的匹配:

def count_overlapping(pattern, string): 
    return len(re.findall("(?=%s)" % pattern, string)) 
0

要避免創建匹配的列表中的一個也可以使用re.sub與可呼叫作爲替代品。它將在每場比賽中被調用,遞增內部計數器。

class Counter(object): 
    def __init__(self): 
     self.matched = 0 
    def __call__(self, matchobj): 
     self.matched += 1 

counter = Counter() 
re.sub(some_pattern, counter, text) 

print counter.matched