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 中的每个非单词字符(如点),因为它们在那里大多被视为文字字符(仅 ^
、]
、-
和\
需要特别注意)。
我正在尝试使用 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 中的每个非单词字符(如点),因为它们在那里大多被视为文字字符(仅 ^
、]
、-
和\
需要特别注意)。