【发布时间】:2021-06-28 15:16:27
【问题描述】:
我编写了这个函数findTokenOffset,它在预先标记的文本中找到给定单词的偏移量(作为间隔单词列表或根据某个标记器)。
导入re,json
def word_regex_ascii(word):
return r"\b{}\b".format(re.escape(word))
def findTokenOffset(text,tokens):
seen = {} # map if a token has been see already!
items=[] # word tokens
my_regex = word_regex_ascii
# for each token word
for index_word,word in enumerate(tokens):
r = re.compile(my_regex(word), flags=re.I | re.X | re.UNICODE)
item = {}
# for each matched token in sentence
for m in r.finditer(text):
token=m.group()
characterOffsetBegin=m.start()
characterOffsetEnd=characterOffsetBegin+len(m.group()) - 1 # LP: star from 0
found=-1
if word in seen:
found=seen[word]
if characterOffsetBegin > found:
# store last word has been seen
seen[word] = characterOffsetEnd
item['index']=index_word+1 #// word index starts from 1
item['word']=token
item['characterOffsetBegin'] = characterOffsetBegin
item['characterOffsetEnd'] = characterOffsetEnd
items.append(item)
break
return items
当标记是单个单词时,此代码可以正常工作
text = "George Washington came to Washington"
tokens = text.split()
offsets = findTokenOffset(text,tokens)
print(json.dumps(offsets, indent=2))
但是,应该有像这里这样具有多令牌方式的令牌:
text = "George Washington came to Washington"
tokens = ["George Washington", "Washington"]
offsets = findTokenOffset(text,tokens)
print(json.dumps(offsets, indent=2))
由于在不同的标记中重复单词,偏移量无法正常工作:
[
{
"index": 1,
"word": "George Washington",
"characterOffsetBegin": 0,
"characterOffsetEnd": 16
},
{
"index": 2,
"word": "Washington",
"characterOffsetBegin": 7,
"characterOffsetEnd": 16
}
]
如何添加对多令牌和重叠令牌正则表达式匹配的支持(感谢 cmets 中对这个确切问题名称的建议)?
【问题讨论】:
-
您的预期输出是什么?这与重叠的正则表达式匹配有关吗?
-
一次性完成。你的词汇量有多大(
tokens的数量)? -
嘿@Aaron 是的,这是一个“令牌重叠”正则表达式匹配,正确。
-
如果您需要在生成的 JSON 中包含令牌索引,这种方法可能会变得非常混乱,请参阅ideone.com/jMEtRb。看起来不错,但您无法获取有关匹配令牌的信息。
-
令牌边界是什么?
Washington.com中的Washington是一个完整的单词,因为n和.之间存在单词边界。给定要求,这是一个有效的匹配。如果你想在一个单词后面有一个.并且右边有一个单词char的情况下匹配失败,你可以使用re.compile(fr'(?<!\w)(?:{"|".join(sorted(map(re.escape, tokens), key=len, reverse=True))})\b(?!\.\b)', re.I ),见demo。
标签: python tokenize stringtokenizer