RegEx Tokenizer:将文本拆分为单词、数字、标点和空格(不要删除任何内容)

Posted

技术标签:

【中文标题】RegEx Tokenizer:将文本拆分为单词、数字、标点和空格(不要删除任何内容)【英文标题】:RegEx Tokenizer: split text into words, digits, punctuation, and spacing (do not delete anything) 【发布时间】:2011-10-22 16:12:03 【问题描述】:

几乎在this thread(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', '.']

Regex 一直是我的弱点之一,所以经过几个小时的研究后,我仍然感到困惑。谢谢!!

【问题讨论】:

为什么'07.May'不扩展成'07', '.', 'May' F.J,我不确定,这是从另一个线程借来的行为。但是,我希望保留这种行为,因为我希望将“伪科学”之类的输入保留为单个单词单元。 【参考方案1】:

我认为这样的事情应该适合你。该正则表达式中的内容可能比实际需要的要多,但是您的要求有些模糊,并且与您提供的预期输出不完全匹配。

>>> 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', '.']

【讨论】:

好的,这看起来很安全,谢谢。但是有什么方法可以保留“它是”或“不是”这两个词吗?我想它不应该在内部撇号上分开一个词? 修改了正则表达式,使其不会在撇号或连字符上拆分,但它目前没有检查以确保它们是内部的。如果这是一个问题,我可以尝试修改它。 太棒了,这太棒了。抱歉,我反应迟钝,这里刚刚开学。【参考方案2】:

不完全符合您提供的预期输出,问题中的一些更多细节会有所帮助,但无论如何:

>>> 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']

【讨论】:

【参考方案3】:

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

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

【讨论】:

以上是关于RegEx Tokenizer:将文本拆分为单词、数字、标点和空格(不要删除任何内容)的主要内容,如果未能解决你的问题,请参考以下文章

将字符串拆分为单词并与其他数据重新连接

Hive with Regex SerDe 拆分行,每个单词成为一列

itextsharp:将文本块拆分为单词时单词被破坏

用空格(或任何字符)将文本单元格拆分为任意数量的单词,重复单词

JSFL 命令将文本字段拆分为单词 - Flash 数组顺序错误

如何使用 REGEX 将作者拆分为对象或数组 C#?