正则表达式分词器:将文本拆分为单词、数字、标点符号和空格(不要删除任何内容)

8
我几乎在这个主题中(samplebias的答案)找到了这个问题的答案;然而我需要把短语分成单词、数字、标点符号以及空格/制表符。我还需要保留每个元素出现的顺序(那个主题中的代码已经做到了这一点)。
因此,我找到了像这样的东西:
    from nltk.tokenize import *
    txt = "Today it's   07.May 2011. Or 2.999."
    regexp_tokenize(txt, pattern=r'\w+([.,]\w+)*|\S+')
    ['Today', 'it', "'s", '07.May', '2011', '.', 'Or', '2.999', '.']

但这是我需要生成的列表类型:
    ['Today', ' ', 'it', "'s", ' ', '\t', '07.May', ' ', '2011', '.', ' ', 'Or', ' ', '2.999', '.']

正则表达式一直是我薄弱的部分,经过几个小时的研究,我仍然摸不着头脑。谢谢!


1
为什么'07.May'没有被展开成'07', '.', 'May' - Andrew Clark
F.J,我其实不确定,这是从另一个线程借鉴过来的行为。然而,我希望保留这种行为,因为我希望像“伪科学”这样的输入仍然作为单个词单位存在。 - floer32
3个回答

4

我认为这样的东西对你应该有用。这个正则表达式可能比需要的要多一些,但是你的要求有点模糊,并且与你提供的预期输出不完全匹配。

>>> txt = "Today it's \t07.May 2011. Or 2.999."
>>> p = re.compile(r"\d+|[-'a-z]+|[ ]+|\s+|[.,]+|\S+", re.I)
>>> slice_starts = [m.start() for m in p.finditer(txt)] + [None]
>>> [txt[s:e] for s, e in zip(slice_starts, slice_starts[1:])]
['Today', ' ', "it's", ' ', '\t', '07', '.', 'May', ' ', '2011', '.', ' ', 'Or', ' ', '2', '.', '999', '.']

好的,这看起来相当安全,谢谢。但是我们有没有办法保留“it's”或“isn't”这些词?我想它就不应该在内部撇号上分割单词了吧? - floer32
1
修改了正则表达式,使其不再在撇号或连字符上分割,但目前尚未检查它们是否为内部。如果这是一个问题,我可以尝试进行修改。 - Andrew Clark
太棒了,这太好了。抱歉我回复慢了,学校刚开始开学。 - floer32

0

根据您提供的预期输出,结果并不完全符合要求。如果问题中提供更多细节将会有所帮助,但无论如何:

>>> txt = "Today it's   07.May 2011. Or 2.999."
>>> regexp_tokenize(txt, pattern=r"\w+([.',]\w+)*|[ \t]+")
['Today', ' ', "it's", ' \t', '07.May', ' ', '2011', ' ', 'Or', ' ', '2.999']

0
在正则表达式\w+([.,]\w+)*|\S+中, \w+([.,]\w+)* 捕获单词,\S+捕获其他非空格字符。

为了捕获空格和制表符,请尝试这个: \w+([.,]\w+)*|\S+|[ \t]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接