2016-09-25 26 views
5

我想分割我提供的任何分隔符組合上的字符串。例如,如果字符串是:如何分割多個分隔符的字符串,但只捕獲一些?

s = 'This, I think,., کباب MAKES , some sense ' 

而且分隔符\.,\s。但是,我想要捕獲除空格\s之外的所有分隔符。輸出應該是:

['This', ',', 'I', 'think', ',.,', 'کباب', 'MAKES', ',', 'some', 'sense'] 

我的解決方案迄今使用re模塊:

pattern = '([\.,\s]+)' 
re.split(pattern, s) 

然而,這種捕捉空白也是如此。我曾嘗試使用其他模式,如[(\.)(,)\s]+,但它們不起作用。

編輯:@PadraicCunningham做了精明的觀察。對於像Some text ,. , some more text這樣的分隔符,我只想從,. ,中刪除前導空格和尾部空格,而不是內部空白。

+0

你能不能刪除' \ s'最初? – eavidan

+0

從捕獲的結果中刪除字符串中的空白字符怎麼樣?這不是問題的一般化解決方案,由於正則表達式的簡單性,它應該在這裏「工作」。 – user2864740

+0

@eavidan但它不會在空白處分割。這樣我就不得不在第一次拆分返回列表的每個元素上運行're.split('\ s',...)'。 – hazrmard

回答

5

下面的方法是最簡單的一種,我想...

s = 'This, I think,., کباب MAKES , some sense ' 
pattern = '([\.,\s]+)' 
splitted = [i.strip() for i in re.split(pattern, s) if i.strip()] 

輸出:基於OP的最後編輯

['This', ',', 'I', 'think', ',.,', 'کباب', 'MAKES', ',', 'some', 'sense'] 
+1

'if i.strip()'足以檢查一個空字符串 –

+0

@PadraicCunningham,正好在分割後產生結果:'...',','some','','sense ',''。單個空格和尾部空格應該被濾除 – RomanPerekhrest

+0

'strip()不會刪除嵌入在其他分隔符之間的空格。我想你必須通過類似'[i for in [re.sub(r'\ s','',i)for i in re.split(r'([,。\ s] +) ',s)] if len(i)> 0]' –

0

更新

的Python 3 *:

list(filter(None, re.split('([.,]+(?:\s+[.,]+)*)|\s', s))) 

輸出:

['This', ',', 'I', 'think', ',.,', 'کباب', 'MAKES', ',', 'some', 'sense'] 
0

我相信這是關於記憶的最有效的選擇,而真正有效的有關計算時間:

import re 
from itertools import chain 
from operator import methodcaller 

input_str = 'This, I think,., ???? MAKES , some sense ' 

iterator = filter(None, # Filter out all 'None's 
        chain.from_iterable( # Flatten the tuples into one long iterable 
        map(methodcaller("groups"), # Take the groups from each match. 
         re.finditer("(.*?)(?:([\.,]+)|\s+|$)", input_str)))) 

# If you want a list: 
list(iterator) 
+0

''這,我想,。,,? MAKES,一些意義「,並打破,檢查OP的編輯。 –

+0

我不知道你可以在're.split()'中捕獲組。很高興知道。 – Bharel

+0

@PadraicCunningham修復了它。順便說一下,它在內存方面效率更高,因爲它佔用了接受解決方案的1/3。 – Bharel

3

注:根據有關這個問題的新的編輯,我改進了我的舊正則表達式。新的很長,但相信我,這是工作!

我建議以下的功能re.split()的分隔符的模式:

(?<![,\.\ ])(?=[,\.]+)|(?<=[,\.])(?![,\.\ ])|(?<=[,\.])\ +(?![,\.\ ])|(?<![,\.\ ])\ +(?=[,\.][,\.\ ]+)|(?<![,\.\ ])\ +(?![,\.\ ]) 

在這裏,我的解決方法不需要任何前/後空間修飾。使正則表達式工作的事情是關於如何使用or來訂購正則表達式。我的粗略策略是任何處理空間領先的模式都將在最後評估。

DEMO

附加

據@雷沃的評論,他提供我的一個又一個縮短版本,這是

\s+(?=[^.,\s])|\b(?:\s+|(?=[,.]))|(?<=[,.])\b 

DEMO

+0

仍然替代'某些文字,。 ,一些'。請參閱OP的編輯。 – Bharel

+0

@Bharel請檢查出來。 – fronthem

+1

@hazrmard另一個解決方法。 – fronthem

相關問題