我想标记化
s = ("mary went to garden. where is mary? "
"mary is carrying apple and milk. "
"what mary is carrying? apple,milk")
进入
['mary', 'went', 'to', 'garden', '.',
'where', 'is', 'mary', '?',
'mary', 'is', 'carrying', 'apple', 'and', 'milk', '.',
'what', 'mary', 'is', 'carrying', '?', 'apple,milk']
请注意,我希望将'apple,milk'
保留为一个单词。
我的代码是:
from nltk.tokenize import RegexpTokenizer
tokenizer = RegexpTokenizer('\w+[\]|\w+[\,]\w+|\.|\?')
s = "mary went to garden. where is mary? mary is carrying apple and milk. what mary is carrying? apple,milk"
tokenizer.tokenize(s)
结果是:
['mary', 'went', 'garden', '.',
'where', 'mary', '?',
'mary', 'carrying', 'apple', 'and', 'milk', '.',
'what', 'mary', 'carrying', '?', 'apple,milk']
但是,'is'
和'to'
丢失了。如何保留它们?
答案 0 :(得分:1)
您的正则表达式模式根本无法捕获丢失的单词。
你可以看到这是一个正则表达式工具,或者使用带有附加参数的RegexpTokenizer('\w+[\]|\w+[\,]\w+|\.|\?', True)
来显示间隙而不是令牌(doc)。
更新:
这是一个模式,可以找到您指定的所有标记:
\w+[\,]\w+|\w+|\.|\?
备注:使用正则表达式替代方法时,按长度(通常从最长到最短)对它们进行排序非常重要。 [\]
对我来说没有意义,语法上也不正确。
答案 1 :(得分:1)
RegexpTokenizer
只根据https://github.com/nltk/nltk/blob/develop/nltk/tokenize/regexp.py#L78
re.findall
函数
def tokenize(self, text):
self._check_regexp()
# If our regexp matches gaps, use re.split:
if self._gaps:
if self._discard_empty:
return [tok for tok in self._regexp.split(text) if tok]
else:
return self._regexp.split(text)
# If our regexp matches tokens, use re.findall:
else:
return self._regexp.findall(text)
基本上,你正在做:
>>> import re
>>> rg = re.compile(r'\w+[\]|\w+[\,]\w+|\.|\?')
>>> sent = "mary went to garden. where is mary? mary is carrying apple and milk. what mary is carrying? apple,milk"
>>> rg.findall(sent)
['mary', 'went', 'garden', '.', 'where', 'mary', '?', 'mary', 'carrying', 'apple', 'and', 'milk', '.', 'what', 'mary', 'carrying', '?', 'apple,milk']
查看正则表达式的解释\w+[\]|\w+[\,]\w+|\.|\?
:https://regex101.com/r/ail12t/1/
正则表达式有3种选择:
\w+[\]|\w+[\,]\w+
:
\w+
匹配任何单词字符(等于[a-zA-Z0-9_])无限次[\]|\w+[\,]
,匹配\w+
范围内的任何字词以及]
,|
,[
或,
字符\w+
匹配任何单词字符(等于[a-zA-Z0-9_])无限次 \.
:找到.
符号并将其匹配
\?
:: TF ?
符号并与之匹配
两个字符单词的原因是" gobbled" up是因为w+w+w+
正则表达式的第一个替代中的多个\w+[\]|\w+[\,]\w+
。这意味着正则表达式只捕获/找到所有具有最小值> = 3个字符的单词。
实际上,我认为正则表达式可以进一步简化,您可以轻松地将其分解为小单位并将其拼凑起来。
使用\w+
,它只会匹配所有字词并排除标点符号:
>>> rg = re.compile(r'\w+')
>>> sent = "mary went to garden. where is mary? mary is carrying apple and milk. what mary is carrying? apple,milk"
>>> rg.findall(sent)
['mary', 'went', 'to', 'garden', 'where', 'is', 'mary', 'mary', 'is', 'carrying', 'apple', 'and', 'milk', 'what', 'mary', 'is', 'carrying', 'apple', 'milk']
然后要捕捉标点符号[[\]\,\-\|\.]
,只需将它们添加为由|
分隔的替代项,即
>>> rg = re.compile(r'\w+|[[\]\,\-\|\.]')
>>> rg.findall(sent)
['mary', 'went', 'to', 'garden', '.', 'where', 'is', 'mary', 'mary', 'is', 'carrying', 'apple', 'and', 'milk', '.', 'what', 'mary', 'is', 'carrying', 'apple', ',', 'milk']