如果我正确地理解了这个问题,一种解决方案是展望下一个单词标记并检查双字母是否在列表中。
import re
import string
regex_pattern = re.compile("([%s \n])" % string.punctuation)
def find_next_word(tokens, idx):
nonword = string.punctuation + " \n"
for i in range(idx+1, len(tokens)):
if tokens[i] not in nonword:
return (tokens[i], i)
return (None, -1)
def highlighter(content, terms, bigrams):
tokens = regex_pattern.split(content)
idx = 0
while idx < len(tokens):
token = tokens[idx]
(next_word, nw_idx) = find_next_word(tokens, idx)
if token.lower() in terms:
print('*' + token + '*', end="")
idx += 1
elif next_word and (token.lower(), next_word.lower()) in bigrams:
concat = "".join(tokens[idx:nw_idx+1])
print('-' + concat + '-', end="")
idx = nw_idx + 1
else:
print(token, end="")
idx += 1
terms = ['man', 'the']
bigrams = [('once', 'upon'), ('i','was')]
text = 'Once upon a time, as I was walking to the city, I met a man. As I was tired, I did not look once... upon this man.'
highlighter(text, terms, bigrams)
调用时,这给:
-Once upon- a time, as -I was- walking to *the* city, I met a *man*. As -I was- tired, I did not look -once... upon- this *man*.
请注意:
- 这是一个贪心算法,它将匹配它找到的第一个两字。因此,例如,您检查
yellow banana
和banana boat
,yellow banana boat
始终突出显示为-yellow banana- boat
。如果你想要另一种行为,你应该更新测试逻辑。
- 你可能也需要更新逻辑来管理,其中一个字既是
terms
和二元
- 我没有测试所有的特殊情况的第一部分的情况下,一些事情可能会破坏/可能有围栏-post错误
- 如果必要的话,您可以优化性能:
- 建设的两字的第一个单词的列表,并检查是否一个词在它做先行到下一个单词之前
- 和/或使用先行的结果一步处理两个之间的所有非单词记号字(实现这一步,应该足以确保线性性能)
希望这有助于。
你能提供一个例子,你的'highlighter'函数按预期工作,*不符合预期?提示:“顺序出现的单词”是什么样子的? – blacksite
你可以先将文本分割成一个列表,然后迭代该列表(类似你已经做过的那样)。然后,通过该列表并检查当前元素和下一个元素是否是有效的二元组,如果是这样,则将单词“突出显示”推入单独的列表中。否则,你可以将其“unhighlighted”推入列表中。确保始终检查前一个bigram是否已经突出显示当前项目(新列表)。 –
@not_a_robot他可能在寻找单词bigrams,这意味着连续两个单词。他试图突出几个词,如果他们在一个bigrams列表。这会导致重叠问题。 –