2016-09-25 29 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

相关问题