2017-01-25 34 views
0

鑑於字符串:如何拆分多個Unicode分隔符,但仍然保持列表中的分隔符?

老師說:「你們要記住國父說的『青年要立志做大事,不要做大官』這句話。」 

任務是分割基於一組定界符標點的串,即

puncts = [u'!', u'"', u'#', u'$', u'%', u'&', u"'", u'(', u')', u'*', u'+', u',', u'-', u'.', u'/', u':', u';', u'<', u'=', u'>', u'?', u'@', u'[', u'\\', u']', u'^', u'_', u'`', u'{', u'|', u'}', u'~', u'\u2022', u'\u2026', u'\u3001', u'\u3002', u'\u300a', u'\u300b', u'\u300c', u'\u300d', u'\u300e', u'\u300f', u'\uff01', u'\uff08', u'\uff09', u'\uff0c', u'\uff1a', u'\uff1b', u'\uff1f'] 

所需的輸出是:

[u'\u8001\u5e2b\u8aaa', u'\uff1a', u'\u300c', u'\u4f60\u5011\u8981\u8a18\u4f4f\u570b\u7236\u8aaa\u7684', u'\u300e', u'\u9752\u5e74\u8981\u7acb\u5fd7\u505a\u5927\u4e8b', u'\uff0c', u'\u4e0d\u8981\u505a\u5927\u5b98', u'\u300f', u'\u9019\u53e5\u8a71', u'\u3002', u'\u300d'] 

I」我看了Python: Split string with multiple delimiters,使用re.split的解決方案非常整齊:

>>> x = u'\u8001\u5e2b\u8aaa\uff1a\u300c\u4f60\u5011\u8981\u8a18\u4f4f\u570b\u7236\u8aaa\u7684\u300e\u9752\u5e74\u8981\u7acb\u5fd7\u505a\u5927\u4e8b\uff0c\u4e0d\u8981\u505a\u5927\u5b98\u300f\u9019\u53e5\u8a71\u3002\u300d' 
>>> [i for i in re.split(u"[{}]".format("|".join(puncts)), x, re.U)] 
[u'\u8001\u5e2b\u8aaa', None, u'', None, u'\u4f60\u5011\u8981\u8a18\u4f4f\u570b\u7236\u8aaa\u7684', None, u'\u9752\u5e74\u8981\u7acb\u5fd7\u505a\u5927\u4e8b', None, u'\u4e0d\u8981\u505a\u5927\u5b98', None, u'\u9019\u53e5\u8a71', None, u'', None, u''] 

注:對不起,由於某種原因,SO認爲,打印字符串是垃圾郵件,所以你必須用字節數=(

但是從re.split結果裸露扔掉了分隔符是需要。

Is there a way to keep the delimiters from `re.split`? 

Are there other ways to split the string using the `puncts` list as multiple delimiters and achieved the desired output? 

我也試着先墊用空格所有標點,然後分裂基於空間:

>>> y = x 
>>> for p in puncts: 
...  y = y.replace(p, u' {} '.format(p)) 
... 
>>> y 
u'\u8001\u5e2b\u8aaa \uff1a  \u300c \u4f60\u5011\u8981\u8a18\u4f4f\u570b\u7236\u8aaa\u7684 \u300e \u9752\u5e74\u8981\u7acb\u5fd7\u505a\u5927\u4e8b \uff0c \u4e0d\u8981\u505a\u5927\u5b98 \u300f \u9019\u53e5\u8a71 \u3002  \u300d ' 
>>> y.split() 
[u'\u8001\u5e2b\u8aaa', u'\uff1a', u'\u300c', u'\u4f60\u5011\u8981\u8a18\u4f4f\u570b\u7236\u8aaa\u7684', u'\u300e', u'\u9752\u5e74\u8981\u7acb\u5fd7\u505a\u5927\u4e8b', u'\uff0c', u'\u4e0d\u8981\u505a\u5927\u5b98', u'\u300f', u'\u9019\u53e5\u8a71', u'\u3002', u'\u300d'] 

有沒有一種簡單的方法來達到同樣的期望的輸出?

回答

1

你可以在你的puncts列表轉換成正則表達式來分割上進行如下:

import re 

text = u"老師說:「你們要記住國父說的『青年要立志做大事,不要做大官』這句話。」" 
puncts = [u'!', u'"', u'#', u'$', u'%', u'&', u"'", u'(', u')', u'*', u'+', u',', u'-', u'.', u'/', u':', u';', u'<', u'=', u'>', u'?', u'@', u'[', u'\\', u']', u'^', u'_', u'`', u'{', u'|', u'}', u'~', u'\u2022', u'\u2026', u'\u3001', u'\u3002', u'\u300a', u'\u300b', u'\u300c', u'\u300d', u'\u300e', u'\u300f', u'\uff01', u'\uff08', u'\uff09', u'\uff0c', u'\uff1a', u'\uff1b', u'\uff1f'] 
puncts = [re.escape(x) for x in puncts] 
my_re = re.compile(u'({})'.format(u'|'.join(puncts))) 

print [x for x in my_re.split(text) if len(x)] 

給你:

[u'\u8001\u5e2b\u8aaa', u'\uff1a', u'\u300c', u'\u4f60\u5011\u8981\u8a18\u4f4f\u570b\u7236\u8aaa\u7684', u'\u300e', u'\u9752\u5e74\u8981\u7acb\u5fd7\u505a\u5927\u4e8b', u'\uff0c', u'\u4e0d\u8981\u505a\u5927\u5b98', u'\u300f', u'\u9019\u53e5\u8a71', u'\u3002', u'\u300d'] 

最終列表理解用於刪除任何空的匹配項。

0

Document

>>> re.split('(\W+)', 'Words, words, words.') 
['Words', ', ', 'words', ', ', 'words', '.', '']