我正在尝试将字符串拆分为单词和标点符号,将标点符号添加到拆分生成的列表中.
例如:
>>> c = "help, me" >>> print c.split() ['help,', 'me']
我真正希望列表看起来像是:
['help', ',', 'me']
所以,我希望字符串在空格中分割,并且从单词中分割出标点符号.
我试图先解析字符串,然后运行拆分:
>>> for character in c: ... if character in ".,;!?": ... outputCharacter = " %s" % character ... else: ... outputCharacter = character ... separatedPunctuation += outputCharacter >>> print separatedPunctuation help , me >>> print separatedPunctuation.split() ['help', ',', 'me']
这会产生我想要的结果,但在大文件上却很慢.
有没有办法更有效地做到这一点?
这或多或少是这样做的方式:
>>> import re >>> re.findall(r"[\w']+|[.,!?;]", "Hello, I'm a string!") ['Hello', ',', "I'm", 'a', 'string', '!']
诀窍是,不要考虑在哪里拆分字符串,而是要包含在令牌中的内容.
注意事项:
下划线(_)被认为是一个内部字符.如果您不想要,请替换\ w.
这不适用于字符串中的(单个)引号.
在正则表达式的右半部分放置要使用的任何其他标点符号.
在re中没有明确提到的任何内容都会被默默地删除.
这是一个支持Unicode的版本:
re.findall(r"\w+|[^\w\s]", text, re.UNICODE)
第一种方法是捕获单词字符序列(由unicode定义,因此"简历"不会变成['r', 'sum']
); 第二个捕获单个非单词字符,忽略空格.
请注意,与最佳答案不同,这会将单引号视为单独的标点符号(例如"我是" - > ['I', "'", 'm']
).这似乎是NLP的标准,所以我认为它是一个功能.
在perl样式的正则表达式语法中,\b
匹配单词边界.这对于进行基于正则表达式的拆分应该会派上用场.
编辑:我已经被hop告知,"空匹配"在Python的re模块的split函数中不起作用.我会把这个留在这里作为其他任何被这个"功能"困扰的人的信息.