查找列表中的哪个字符串最接近字符

find which string in a list is closest to a character

我有一个 pdf 文档,我已经将其解析为一个列表,比如:

listTxt = ['met een motor, losse delen van caravans, losse delen van ',
           'aanhangwagens die in uw woonhuis, schuur of garage op ',
           'hetzelfde adres staan tot maximaal € 1.250,-.',
           ' ',
           ' horen deze losse delen bij een bedrijf? Of zijn ze bedoeld ',
           'aanhangwagens die niet kapot zijn verzekerd',  '• Schade door grondwater dat onverwacht het woonhuis ',
           'binnenstroomt door afvoerleidingen en apparaten die daarop ',
           'zijn aangesloten.',
           '• Schade door water dat uit een aquarium stroomt als het ',
           'aquarium onverwacht kapot is gegaan. We betalen ook voor de ',
           'inhoud van het aquarium tot maximaal € 1.250,-.',
           '• Schade door water dat uit een waterbed stroomt. Maar alleen als ',
           'het waterbed onverwacht kapot is gegaan.']

现在我想要 return 最接近(距离)欧元符号 (€) 的字符串。我看过各种算法,比如 levenshtein 距离等,但我的任务其实很简单,这个距离可以仅仅是字符数。

循环使用一种条件:

for t in list:
    if 'aanhangwagens' and '€' in t:
        print(t)

结果:

hetzelfde adres staan tot maximaal € 1.250,-.
inhoud van het aquarium tot maximaal € 1.250,-.

但我希望 listTxt [1] 中的 'aanhangwagens' 非常接近下一个文本 listTxt [2](带有 €),因此所需的输出是:

'aanhangwagens die in uw woonhuis, schuur of garage op ', 'hetzelfde adres staan tot maximaal € 1.250,-.'

对于短语 aquarium,它工作正常,因为 aquarium 和 € 在同一个字符串中,即 listTxt[11]

'hetzelfde adres staan tot maximaal € 1.250,-.'

根据你的定义,我写了一些东西来寻找包含特定字符的封闭行。 首先,您需要计算两个列表 "resa" 和 "rese"。它们会告诉您给定的字符串是否包含在您的列表中。例如,如果您在列表 ["abc"、"ccd"、"efg"、"agf"] 中查找 "a",结果列表将是 [1,0,0 ,1]。 您需要为 'aanhangwagens' 和欧元符号计算这些。 使用这些列表,您可以检查欧元列表中的 1 和 'aanhangwagens' 列表中的 1 之间的距离。

在您的示例中,搜索 'aanhangwagens' 会给出: [0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0] 欧元给出: [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]

我写的算法保留最接近的字符串,但是如果两个字符串的距离相同,它会将它们都放在结果列表中。 请在使用此代码之前 运行 进行一些测试,我无法向您保证它在任何情况下都能正常工作。

resa=[]
rese=[]
for t in listTxt:
    if 'aanhangwagens' in t:
        resa.append(1)
    else:
        resa.append(0)
    if '€' in t:
        rese.append(1)
    else:
        rese.append(0)

def close_line(aliste, alista, alistTxt):
    all_closest_lines=[]
    for i in range(len(aliste)):
        if(aliste[i]==0):
            continue
        else:
            closest_line=[]
            amin=max(len(aliste), len(alista))
            for j in range(len(alista)):
                if(alista[j]==0):
                    continue
                else:
                    if(abs(i-j)<amin):
                        amin=abs(i-j)
                        closest_line=[]
                        closest_line.append([alistTxt[j], "Closest to € in position{}".format(i)])
                    elif(abs(i-j)==amin):
                        closest_line.append([alistTxt[j], "Closest to € in position{}".format(i)])
            all_closest_lines+=closest_line
    return(all_closest_lines)

print(close_line(rese, resa, listTxt))

结果:

[['aanhangwagens die in uw woonhuis, schuur of garage op ', 'Closest to € in position2'], ['aanhangwagens die niet kapot zijn verzekerd', 'Closest to € in position11']]

您可以尝试为每个句子生成一个分数,然后找到与有用句子组相对应的分数组。然后你会得到每个 'match' 的总分。下面我做了一个粗略的实现。

import numpy as np


listTxt = ['met een motor, losse delen van caravans, losse delen van ',
           'aanhangwagens die in uw woonhuis, schuur of garage op ',
           'hetzelfde adres staan tot maximaal € 1.250,-.',
           ' ',
           ' horen deze losse delen bij een bedrijf? Of zijn ze bedoeld ',
           'aanhangwagens die niet kapot zijn verzekerd',  '• Schade door grondwater dat onverwacht het woonhuis ',
           'binnenstroomt door afvoerleidingen en apparaten die daarop ',
           'zijn aangesloten.',
           '• Schade door water dat uit een aquarium stroomt als het ',
           'aquarium onverwacht kapot is gegaan. We betalen ook voor de ',
           'inhoud van het aquarium tot maximaal € 1.250,-.',
           '• Schade door water dat uit een waterbed stroomt. Maar alleen als ',
           'het waterbed onverwacht kapot is gegaan.']

euro = np.array([string.count('€') for string in listTxt])
ahw = np.array([string.count('aanhangwagen') for string in listTxt])

all_values = np.add(euro,ahw)


score = []
matches = []
for i, value in enumerate(all_values):
    if value > 0:
        score.append(value)
        matches.append(listTxt[i])
    elif score:
        print(sum(score), matches)
        score = []
        matches = []

它计算每个句子中“€”或 'aanhangwagen' 出现的次数,然后对结果求和。然后做一个小循环,找到零之间的 'close' 值组。

通过这种方式,您可以获得不同(组)句子的排名,并在它们旁边显示您的搜索词在这些句子中出现的次数。

在这种情况下,结果是:

2 ['aanhangwagens die in uw woonhuis, schuur of garage op ', 'hetzelfde adres staan tot maximaal € 1.250,-.']
1 ['aanhangwagens die niet kapot zijn verzekerd']
1 ['inhoud van het aquarium tot maximaal € 1.250,-.']

这就是你想要的!