Python 如何将句子字符串拆分为单词,同时将标点符号作为单独的元素
我目前正在尝试使用Python对一些语言数据进行标记化,我很好奇是否有一种有效的或内置的方法可以将句子字符串拆分为单独的单词和单独的标点符号。例如:Python 如何将句子字符串拆分为单词,同时将标点符号作为单独的元素,python,nlp,token,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', '
'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', '?']
我尝试过使用一些方法,比如搜索字符串、查找标点、存储索引、从字符串中删除索引,然后拆分字符串,并相应地插入标点,但这种方法似乎效率太低,尤其是在处理大型语料库时
有人知道有没有更有效的方法
谢谢。以下是一种使用
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
。您可以做一个技巧:
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(" ")
您可以使用
re.sub
替换string.parantion
中定义的所有字符,后面跟一个空格,前面跟一个空格,最后可以使用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', '?']
单词标记化并不像听起来那么简单。以前使用正则表达式或字符串替换的答案并不总是涉及首字母缩略词或缩写(例如,
a.m
,p.m.
,N.Y.
,D.I.Y
,a.D.
,B.C.
,例如
,等
,即
,先生
,女士
,博士
。)。这些将被分割成单独的代币,,,,除非您编写更复杂的模式来处理此类情况(但总会有恼人的例外)。您还必须决定如何处理其他标点符号,如“
和”
,$
,%
,如电子邮件地址和URL,数字序列(例如5000.99
,33.3%
),连字符词(例如预处理
,前卫
),包括标点符号的名称(例如O'Neill
),缩略语(例如不是
,不能
,让我们
),英语所有格标记()等
我建议使用NLP库来执行此操作,因为它们应该被设置为可以为您处理大多数这些问题(尽管它们仍然会犯“错误”,您可以尝试修复)。请参阅:
- (特别是为了提高大型语料库的效率)
前三个是完整的工具包,除了标记化之外还有许多功能。最后一个是词性标记器,用于标记文本。这些只是少数,还有其他选项,所以请尝试一些,看看哪个最适合您。它们都会以不同的方式标记您的文本,但在大多数情况下(不确定TreeTagger)您可以修改他们的标记化决策以纠正错误。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', '?']
只是忘记了替换所有的“?”!希望你理解我的逻辑并这样做