正则表达式不匹配字符串末尾的整个单词(二元组),仅在开头和中间

Regex not matching a whole word (bigram) at the end of a string, only at the beginning and middle

我想取一个二元语法,看看它是否存在于两个片段(字符串)中,称为源和目标(就像将一种源语言翻译成目标语言一样)。 例如,“星球大战”,出现在“星球大战电影”和“星球大战电影”中。这意味着“星球大战”是未翻译的。我正在使用正则表达式,以便匹配整个单词而不是子字符串。它适用于上面的两个片段,但当“星球大战”位于第二个字符串的末尾时它不起作用,例如“电影星球大战”。

二元语法是从每行包含一个二元语法的文件中读取的,我正在删除末尾的换行符:

topword = input_file0.readline().lower().replace('\n', "")

正在从文件中读取源和目标段,我正在删除末尾的换行符:

srcsegm = input_file1.readline().lower().replace('\n', "")
tgtsegm = input_file2.readline().lower().replace('\n', "")

匹配的正则表达式是:

regex_match = re.compile(rf'\b{re.escape(topword)}\b')

我测试源中是否匹配:

has_match_src = re.search(regex_match,srcsegm)

如果有匹配项,我会在目标中测试匹配项:

has_match_tgt = re.search(regex_match,tgtsegm)

如果两者都是正确的,我将其标记为“未翻译”术语,因为它在源语言和目标语言中是相同的。

我正在打印结果以查看发生了什么,如:

print(topword,"untr:",srcsegm,"=====",tgtsegm)
print(topword,"translated:",srcsegm,"=====",tgtsegm)

但是当“blu ray”在字符串的开头或中间时,下面的结果是正确的:

blu ray  untr: blu ray rar ===== blu ray rar
blu ray  untr: soul blu ray disney ===== soul blu ray disney

当蓝光在字符串的末尾时错误:

blu ray  translated: sony blu ray player ===== sony odtwarzacz blu ray

应该说“untr”,因为我们可以在源片段和目标片段中看到“blu ray”。 问题是:为什么它没有在字符串末尾产生匹配项?

这是代码:

topword = input_file0.readline().lower().replace('\n', "") # for ngrams, do not use strip and replace the newline
count_untr = 0
count_tr = 0

while len(topword)>0:   # looping the topword
    count_untr = 0
    count_tr = 0
    srcsegm = input_file1.readline().lower().replace('\n', "")
    tgtsegm = input_file2.readline().lower().replace('\n', "")
    regex_match = re.compile(rf'\b{re.escape(topword)}\b')
 
    while len(srcsegm)>0:     # looping the src and tgt segments for a topword
        has_match_src = re.search(regex_match,srcsegm) 
        if has_match_src != None:
            has_match_tgt = re.search(regex_match,tgtsegm)
            if has_match_tgt != None:
                count_untr += 1
                print(topword,"untr:",srcsegm,"=====",tgtsegm)
            else:
                count_tr += 1
                print(topword,"translated:",srcsegm,"=====",tgtsegm)

提前致谢。

例如,如果您要在字符串中查找 'star wars',我们希望在两个单词之间允许任意空格(例如换行符)并且这些单词必须出现在单词边界上,那么实际您想要使用的正则表达式是:

\bstar\s+\wars\b

考虑到这一点,您应该将 topword 分成两个组成词,并通过单独转义每个词并在它们之间使用空格来构建搜索正则表达式:

import re

#topword =  input_file0.readline().lower().strip()
topword = 'star wars'

#srcsegm = input_file1.readline().lower().strip()
srcsegm = 'i just saw star wars and loved it!'

#tgtsegm = input_file2.readline().lower().strip()
# newline between star and wars and its at the end of the string:
tgtsegm = 'tomorrow I am planning on seeing star\nwars'

# allow for arbitrary white space between words:
split_words = topword.split()
regex_search = re.compile(rf'\b{re.escape(split_words[0])}\s+{re.escape(split_words[1])}\b')

if regex_search.search(srcsegm) and regex_search.search(tgtsegm):
    print('match in both')

打印:

match in both