2013-05-10 12 views
7

我想分割使用-+====+作爲分隔符的字符串,而空白。我想保留分隔符,除非它是空格。Python的正則表達式 - 多餘的匹配數

我試着用下面的代碼來實現這一目標:

def tokenize(s): 
    import re 
    pattern = re.compile("(\-|\+\=|\=\=|\=|\+)|\s+") 
    return pattern.split(s) 

print(tokenize("hello-+==== =+ there")) 

我預計輸出爲

['hello', '-', '+=', '==', '=', '=', '+', 'there'] 

但是我

['hello', '-', '', '+=', '', '==', '', '=', '', None, '', '=', '', '+', '', None, 'there'] 

這幾乎什麼我想要的,除了有很多無關的None和空字符串。

爲什麼這樣做,我該如何改變它以得到我想要的?

+0

空的字符串是因爲你有兩個匹配的字符彼此相鄰,所以當拆分時,他們之間有一個「'」。這有點不直觀,在混合 – jozefg 2013-05-10 18:51:25

回答

3

re.split默認返回是在匹配之間串的比特的陣列:(作爲@Laurence貢薩爾維斯注意到,這是它的主要用途。)

['hello', '', '', '', '', '', '', '', 'there'] 

注意在-之間的空字符串和+=+===

由於文檔解釋了,因爲你正在使用捕獲組(即,因爲您使用(\-|\+\=|\=\=|\=|\+)代替(?:\-|\+\=|\=\=|\=|\+),即捕獲小組賽穿插位:

['hello', '-', '', '+=', '', '==', '', '=', '', None, '', '=', '', '+', '', None, 'there'] 

None對應於在\s+一半的格局被匹配;在這些情況下,捕獲小組一無所獲。

從查看re.split的文檔,我沒有看到一個簡單的方法來讓它在匹配之間丟棄空字符串,雖然簡單的列表理解(或者如果您願意,可以很容易地丟棄)None s和空字符串:

def tokenize(s): 
    import re 
    pattern = re.compile("(\-|\+\=|\=\=|\=|\+)|\s+") 
    return [ x for x in pattern.split(s) if x ] 

最後一個音符:對於到目前爲止你所描述的東西,這將正常工作,但根據您的項目進展的方向,你可能想切換到合適的解析庫。 The Python wiki對這裏的一些選項有很好的概述。

+0

注意,返回在中間位是那種「主行爲」,類似的以str.split。捕捉的東西是一種額外的功能。 – 2013-05-10 19:00:00

1

這種模式更符合你想要什麼:

\s*(\-|\+\=|\=\=|\=|\+)\s* 

你仍然會得到一個空字符串每個分割間,不過,因爲你應該期望。

+0

捕捉組,不會打破「你好」到兩個標記,我相信這是OP的意圖使用空格作爲分隔符。 – rici 2013-05-10 18:53:57

2

它爲什麼這樣表現?

根據re的文檔。拆分:

如果在模式中使用捕獲括號,則模式中所有組的文本也會作爲結果列表的一部分返回。

這實際上是正確的:如果使用捕獲圓括號,則返回所有組的文本,無論它們是否匹配任何內容;那些不匹配的東西會返回None

一如既往與split,兩個連續的分隔符被視爲單獨空字符串,那麼你會得到空字符串穿插。

我怎麼可能會改變它來得到我想要的東西?

最簡單的辦法是濾除輸出:

filter(None, pattern.split(s)) 
0

試試這個:

def tokenize(s): 
    import re 
    pattern = re.compile("(\-|\+\=|\=\=|\=|\+)|\s+") 
    x = pattern.split(s) 
    result = [] 
    for item in x: 
    if item != '' and item != None: 
     result.append(item) 
    return result 

print(tokenize("hello-+==== =+ there")) 
2

也許re.findall會更適合你?

>>> re.findall(r'-|\+=|==|=|\+|[^-+=\s]+', "hello-+==== =+ there") 
['hello', '-', '+=', '==', '=', '=', '+', 'there'] 
+0

一個問題我有你的解決方案是,後來我想,以支持更多的分隔符(如'*',''&&),我怕'[^ - + = \ s] +'的一部分模式將變得更加複雜。 – math4tots 2013-05-10 19:15:58

+0

是否有關於非分隔符標記的任何規則?也許你可以使用例如。 '\ w +'而不是'[^ - + = \ s] +'。 – 2013-05-10 19:21:12