NLTK - nltk.tokenize.RegexpTokenizer - 正则表达式未按预期工作

NLTK - nltk.tokenize.RegexpTokenizer - regex not working as expected

我正在尝试使用 RegexpTokenizer 对文本进行标记化。

代码:

from nltk.tokenize import RegexpTokenizer
#from nltk.tokenize import word_tokenize

line = "U.S.A Count U.S.A. Sec.of U.S. Name:Dr.John Doe J.Doe 1.11 1,000 10--20 10-20"
pattern = '[\d|\.|\,]+|[A-Z][\.|A-Z]+\b[\.]*|[\w]+|\S'
tokenizer = RegexpTokenizer(pattern)

print tokenizer.tokenize(line)
#print word_tokenize(line)

输出:

['U', '.', 'S', '.', 'A', 'Count', 'U', '.', 'S', '.', 'A', '.', 'Sec', '.', 'of', 'U', '.', 'S', '.', 'Name', ':', 'Dr', '.', 'John', 'Doe', 'J', '.', 'Doe', '1.11', '1,000', '10', '-', '-', '20', '10', '-', '20']

预期输出:

['U.S.A', 'Count', 'U.S.A.', 'Sec', '.', 'of', 'U.S.', 'Name', ':', 'Dr', '.', 'John', 'Doe', 'J.', 'Doe', '1.11', '1,000', '10', '-', '-', '20', '10', '-', '20']

为什么 tokenizer 也会泄露我预期的标记 "U.S.A" , "U.S."? 我该如何解决这个问题?

我的正则表达式:https://regex101.com/r/dS1jW9/1

如果你mod你的正则表达式

pattern = '[USA\.]{4,}|[\w]+|[\S]'

然后

pattern = '[USA\.]{4,}|[\w]+'
tokenizer = RegexpTokenizer(pattern)
print (''+str(tokenizer.tokenize(line)))

你得到你想要的输出

['U.S.A', 'Count', 'U.S.A.', 'Sec', '.', 'of', 'U.S.', 'Name', ':', 'Dr', '.', 'John', 'Doe', 'J', '.', 'Doe', '1', '.', '11', '1', ',', '000', '10', '-', '-', '20', '10', '-', '20']

重点是你的 \b 是退格符,你需要使用原始字符串文字。此外,字符 classes 中的文字管道也会弄乱你的输出。

这按预期工作:

>>> pattern = r'[\d.,]+|[A-Z][.A-Z]+\b\.*|\w+|\S'
>>> tokenizer = RegexpTokenizer(pattern)
>>> print(tokenizer.tokenize(line))

['U.S.A', 'Count', 'U.S.A.', 'Sec', '.', 'of', 'U.S.', 'Name', ':', 'Dr', '.', 'John', 'Doe', 'J.', 'Doe', '1.11', '1,000', '10', '-', '-', '20', '10', '-', '20']

请注意,将单个 \w 放入字符 class 中是没有意义的。此外,您不需要转义字符 class 中的每个非单词字符(如点),因为它们在那里大多被视为文字字符(仅 ^]-\需要特别注意)。