如何将句子字符串拆分为单词,还使标点符号成为一个单独的元素

时间:2019-07-30 05:03:28

标签: python nlp token

我目前正在尝试使用Python标记某些语言数据,并且很好奇是否有一种有效或内置的方法将句子字符串拆分为单独的单词和标点符号。例如:

'Hello, my name is John. What's your name?'

如果我在这句话上使用split(),那么我会得到

['Hello,', 'my', 'name', 'is', 'John.', "What's", 'your', 'name?']

我想要得到的是:

['Hello', ',', 'my', 'name', 'is', 'John', '.', "What's", 'your', 'name', '?']

我尝试使用诸如搜索字符串,查找标点符号,存储它们的索引,从字符串中删除它们,然后拆分字符串以及相应地插入标点符号之类的方法,但是这种方法似乎效率太低,尤其是在处理大型字符串时语料库。

有人知道是否有更有效的方法吗?

谢谢。

5 个答案:

答案 0 :(得分:2)

您可以做个把戏:

text = "Hello, my name is John. What's your name?"
text = text.replace(",", " , ") # Add an space before and after the comma
text = text.replace(".", " . ") # Add an space before and after the point
text = text.replace("  ", " ") # Remove possible double spaces
mListtext.split(" ") # Generates your list

或者仅输入以下内容:

mList = input().replace(",", " , ").replace(".", " . ")replace("  ", " ").split(" ")

答案 1 :(得分:1)

这是一种使用re.finditer的方法,该方法至少似乎可以处理您提供的示例数据:

inp = "Hello, my name is John. What's your name?"
parts = []
for match in re.finditer(r'[^.,?!\s]+|[.,?!]', inp):
    parts.append(match.group())

print(parts)

输出:

['Hello', ',', 'my', 'name', 'is', 'John', '.', "What's", 'your', 'name', '?']

这里的想法是匹配以下两种模式之一:

[^.,?!\s]+    which matches any non punctuation, non whitespace character
[.,?!]        which matches a single punctuation character

大概不是空格或标点符号的任何内容都应该是句子中匹配的单词/术语。

请注意,解决此问题的真正好方法是尝试对标点或空格进行正则表达式拆分。但是,re.split不支持在零宽度环顾四周时进行拆分,因此我们不得不尝试使用re.finditer

答案 2 :(得分:0)

您可以使用re.sub来替换string.punctuation中定义的所有字符,后跟一个空格,最后一个空格,最后可以使用str.split来分割单词

>>> s = "Hello, my name is John. What's your name?"
>>> 
>>> import string, re
>>> re.sub(fr'([{string.punctuation}])\B', r' \1', s).split()
['Hello', ',', 'my', 'name', 'is', 'John', '.', "What's", 'your', 'name', '?']

在python2中

>>> re.sub(r'([%s])\B' % string.punctuation, r' \1', s).split()
['Hello', ',', 'my', 'name', 'is', 'John', '.', "What's", 'your', 'name', '?']

答案 3 :(得分:0)

单词分词不是听起来那么简单。先前使用正则表达式或字符串替换的答案并不总是会处理首字母缩写词或缩写(例如a.mp.m.N.Y.D.I.Y,{{ 1}},A.D.B.C.e.g.etc.i.e.Mr.Ms.)。除非您编写更复杂的模式来处理此类情况,否则这些方法将通过这些方法将它们分成单独的标记(例如Dr.B.C)总是令人讨厌的例外)。您还必须决定如何处理其他标点符号,例如."'$,例如电子邮件地址和URL,数字序列(例如%5,000.99),连字符(例如33.3%pre-processing),包括标点符号(例如avant-garde),收缩(例如{{1} },O'Neillaren't),英语所有格标记(can't)等,等等。

我建议使用NLP库来执行此操作,因为应该将它们设置为为您解决大多数此类问题(尽管它们仍然会产生“错误”,您可以尝试解决)。参见:

前三个是完整的工具包,除了令牌化外,还具有许多功能。最后一个是词性标记器,用于标记文本。这些只是其中的一些,还有其他选择,因此请尝试一下,看看哪种最适合您。他们都会以不同的方式标记您的文本,但是在大多数情况下(不确定TreeTagger),您可以修改其标记化决策以纠正错误。

答案 4 :(得分:0)

来自nltk的

TweetTokenizer也可以用于此。.

from nltk.tokenize import TweetTokenizer

tokenizer = TweetTokenizer()
tokenizer.tokenize('''Hello, my name is John. What's your name?''')

#op
['Hello', ',', 'my', 'name', 'is', 'John', '.', "What's", 'your', 'name', '?']