【问题标题】:Best way to identify similar text inside strings?识别字符串中相似文本的最佳方法?
【发布时间】:2020-08-03 20:28:46
【问题描述】:

我有一个短语列表,实际上它是一个 Excel 文件,但如果需要,我可以提取每一行。 我需要找到非常相似的行,例如一行可以是:

ANTIBRATING SSPIRING JOINT (type 2) mod. GA160 (temp.max60°)

在我之后的某行可以有同一行或这一行:

ANTIBRATING SSPIRING JOINT (type 2) mod. GA200 (temp.max60°)

就像你可以看到这两条线几乎一样,在这种情况下不相等,但在 98% 主要问题是我必须处理大约 45k 行,因此我正在寻找一种快速且可能是可视化的方式来完成此操作。 我想到的第一件事就是将第一行与第二行进行比较,然后将第三行进行比较直到最后,依此类推,将第二行和第三行进行比较直到最新-1,然后得出一种分数,例如第 1 行是 100% 与第 42 行,99% 与第 522 行 ... 21% 与第 22142 行等... 但这只是一种想法,也许不是最好的。

可能外面已经有不错的程序/脚本/在线服务/程序了,我搜了没找到,所以最后在这里问了。

任何人都知道实现此目的的好方法(如果可能的话)或脚本或在线服务?

【问题讨论】:

    标签: string text compare comparison


    【解决方案1】:

    您可以做的一件事是编写一个脚本,其作用如下:

    从 csv 文件中提取数据
    定义一个可以得出相似性的正则表达式,python示例可以是:

    [\w\s]+\([\w]+\)[\w\s]+\([\w°]+\)
    

    或者这样,请参考documentation

    【讨论】:

    • 您好,感谢您的建议,我使用正则表达式查找相邻的重复项,但现在我必须找到相似的行。
    【解决方案2】:

    你遇到的问题是你不是在寻找一个完全匹配的,而是一个类似的。 这是一个即使数据库也从未解决过的问题,并且会导致全表扫描。 所以我们不太可能解决它。

    但是,我想建议您考虑替代方案:

    1. 您可以决定将差异限制为特定字符集。 在上面的示例中,您忽略了数字,但尊重了字母。 如果我们可以假设这条规则永远成立,那么我们可以对字符串执行文本替换。
    ANTIBRATING SSPIRING JOINT (type 2) mod. GA160 (temp.max60°) ==> ANTIBRATING SSPIRING JOINT (type _) mod. GA_ (temp.max_°)
    

    现在,我们可以通过执行精确的字符串比较来解决这个问题。这可以通过散列来完成。最简单的方法是在您将存储此调整后的文本的列上提供散列图/散列集或具有散列索引的数据库。

    1. 您可以决定用时间换取空间。 例如,您可以将字符串提供给服务,该服务将在您的字符串上构建许多不同的索引变体。例如,将您的数据提供给 elasticsearch,然后对其执行分析查询。

    【讨论】:

    • 你说得对,但我必须处理大量文本,而且与我发布的字符串并不完全相同。如果我为每组字符串分配一个数值,例如从 A 到 G -> 值 1,从 H 到 L -> 值 2 等等,空格和 .是值 0 ...最后我可以比较总数。坏主意?
    • 不确定这对您有什么帮助。这取决于您将数字转换为数字后如何处理这些数字,坦率地说,我怀疑它最终会成为另一个代理哈希函数,这意味着中间某处的单个字母差异会导致非常不同的数字。跨度>
    【解决方案3】:

    模糊搜索是关键。 我找到了几个项目和想法,但我使用的一个是tree-agrep,我知道它很老,但在这种情况下对我有用,我创建了这个小脚本来帮助我创建差异列表,所以我可以手动用我的文件检查一下

    #!/bin/bash
    
    ########## CONFIGURATIONS ##########
    original_file=/path/jjj.txt
    t_agrep_bin="$(command -v tre-agrep)"
    destination_file=/path/destination_file.txt
    distance=1
    ########## CONFIGURATIONS ##########
    
    lines=$(grep "" -c "$original_file")
    
    if [[ -s "$destination_file" ]]; then
        rm -rf "$destination_file"
    fi
    
    start=1
    while IFS= read -r line; do
        echo "Checking line $start/$lines"
        lista=$($t_agrep_bin -$distance -B --colour -s -n -i "$line" $original_file)
        echo "$lista" | awk -F ':' '{print $1}' ORS=' ' >> "$destination_file"
        echo >> "$destination_file"
        start=$((start+1))
    done < "$original_file"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-11
      • 1970-01-01
      • 2017-05-10
      • 2023-03-06
      • 2015-10-09
      • 1970-01-01
      • 2011-05-11
      • 2016-04-19
      相关资源
      最近更新 更多