【问题标题】:Comparing text blocks for similar content比较相似内容的文本块
【发布时间】:2010-09-23 08:49:21
【问题描述】:

我有两个包含公司名称的文本块。两者都包含数百家公司的名称,较新的列表有更多公司。如何从两个列表中删除重复的公司名称,以便只留下新名称? 示例文本块一:

Company Name One, Address line 1, line 2, phone, email
..
Random text 
..

Company Name Two 
Address, Phone,email
..
Random text 
..
Company Name 3 
Address, Phone,email

示例文本块二:

..Random Text..
M/s Company Name One Extra Random Text, Address line 1, line 2, phone, 
..random text...
M/s Company Name Two 
Address, Phone
...

公司名称、地址等相似不一样。第二个块在所有公司名称前都有 M/s 字样。 我想在 php 中执行此操作,也许使用正则表达式。

我想输出匹配的公司名称,例如。在上面给出的示例中,我想输出公司名称:公司名称一,公司名称二对于两个测试块都是通用的。

更新:感谢@Wrikken,我有两个字符串中的文本。我可以使用 M/s 炸开第二个方块,并得到一个数组。然后如何检查该数组中的每个项目以匹配第一个长字符串的文本块?

虽然,我已经手动完成了这项工作,但我仍然想知道如何比较两个文本块的相似性以及赏金。

更新:@Joyce Babu 代码的输出

..Random Text.. ..Random Text.. ..Random Text.. ..Random Text.. ..Random Text.. ..Random Text.. ..Random Text.. ..Random Text.. ..Random Text.. ..Random Text.. M/s Company Name One Extra Random Text, Address line 1, line 2, phone, M/s Company Name One Extra Random Text, Address line 1, line 2, phone, M/s Company Name One Extra Random Text, Address line 1, line 2, phone, M/s Company Name One Extra Random Text, Address line 1, line 2, phone, M/s Company Name One Extra Random Text, Address line 1, line 2, phone, M/s Company Name One Extra Random Text, Address line 1, line 2, phone, M/s Company Name One Extra Random Text, Address line 1, line 2, phone, M/s Company Name One Extra Random Text, Address line 1, line 2, phone, M/s Company Name One Extra Random Text, Address line 1, line 2, phone, M/s Company Name One Extra Random Text, Address line 1, line 2, phone, M/s Company Name One Extra Random Text, Address line 1, line 2, phone, ..random text... ..random text... ..random text... ..random text... ..random text... ..random text... ..random text... ..random text... ..random text... ..random text... M/s Company Name Two M/s Company Name Two M/s Company Name Two M/s Company Name Two M/s Company Name Two M/s Company Name Two M/s Company Name Two M/s Company Name Two M/s Company Name Two M/s Company Name Two Address, Phone Address, Phone Address, Phone Address, Phone Address, Phone Address, Phone Address, Phone Address, Phone Address, Phone Address, Phone ... ... ... ... ... ... ... ... ... ... ... ... 

@nikic 的输出

array(2) { [0]=>  string(17) "..Random Text.. " [4]=>  string(16) "Address, Phone " } 

@Joyce Babu 第二篇文章的输出

andom Text..andom Text..andom Text..andom Text..andom Text..andom Text..andom Text..andom Text..andom Text..andom Text..Company Name One Extra Random Text, Address line 1, line 2, phone,Company Name One Extra Random Text, Address line 1, line 2, phone,Company Name One Extra Random Text, Address line 1, line 2, phone,Company Name One Extra Random Text, Address line 1, line 2, phone,Company Name One Extra Random Text, Address line 1, line 2, phone,Company Name One Extra Random Text, Address line 1, line 2, phone,Company Name One Extra Random Text, Address line 1, line 2, phone,Company Name One Extra Random Text, Address line 1, line 2, phone,Company Name One Extra Random Text, Address line 1, line 2, phone,Company Name One Extra Random Text, Address line 1, line 2, phone,Company Name One Extra Random Text, Address line 1, line 2, phone,andom text...andom text...andom text...andom text...andom text...andom text...andom text...andom text...andom text...andom text...Company Name TwoCompany Name TwoCompany Name TwoCompany Name TwoCompany Name TwoCompany Name TwoCompany Name TwoCompany Name TwoCompany Name TwoCompany Name Tworess, Phoneress, Phoneress, Phoneress, Phoneress, Phoneress, Phoneress, Phoneress, Phoneress, Phoneress, Phone

@Joyce Babu 最终代码

<?php
set_time_limit(500);
$arOld = file('olddata.txt');
$arNew = file('newdata.txt');
$G=0;
    $c=0;

    foreach($arNew as $line){
    if(substr($line, 0, 4) == 'M/s '){
    $c++;   
    echo "<BR/>".$c.".)";
        $line = trim(substr($line, 4));
        foreach($arOld as $old){
            similar_text($line, $old, $percentage);
            if ($percentage > 80){
                continue;
            }
        }
        echo $line;
    }else{
    $G++;
    }
}
echo "<br/>".$G . " DID NOT MATCH";
?>

@Joyce Babu 的输出最终代码

1.)Company Name One Extra Random Text, Address line 1, line 2, phone,
2.)Company Name Two
4 DID NOT MATCH

【问题讨论】:

  • 这两个文本块看起来与您的示例文本中的完全一样吗?如果是这样,你想保留什么?你想删除什么?如果不是这种情况,我认为您应该发布一些与您的两个文本块完全相同的示例文本。如果你愿意,我也许可以帮助你。
  • @matsolof。我已经更新了问题
  • 每条记录一行?它们可以是两条记录之间的随机数据行吗?
  • 有些记录是多行的,没有顺序或统一性,文本块唯一的共同点是公司名称。
  • 块 1 中使用什么标记来指示公司名称的开始?你怎么知道这是公司名称而不是随机文本?

标签: php regex comparison diff


【解决方案1】:

试试这个

set_time_limit(500)
$arOld = file('olddata.txt');
$arNew = file('newdata.txt');
foreach($arNew as $line){
    if(substr($line, 0, 3) === 'M/s '){
        $line = trim(substr($line, 3));
        foreach($arOld as $old){
            similar_text($line, $old, $percentage);
            if ($percentage > 80){
                continue;
            }
        }
        echo $line;
    }
}

【讨论】:

  • 你能回答我对原始帖子的评论吗?
  • 更新了代码以仅检查以 M/S 开头的行。还修复了一个错误。
  • 新代码没有输出!我添加了一个回声“是”;第 5 行之后
  • ... 检查 'if cond' 是否匹配,即使在许多行的开头有一个 M/s
  • 糟糕! 'M/s' 是 4 个字符。您需要将 substr($line, 0, 3) 更改为 substr($line, 0, 4)
【解决方案2】:

创建一个包含两者的数组(可能使用file() 函数,具体取决于文本的格式,或者可能只是在内容上使用explode()),然后使用array_diff()

【讨论】:

    【解决方案3】:

    如果您只需要比较此列表一次,我建议您将文档转换为 txt,然后您就可以使用正则表达式进行比较。否则您将需要使用第三方软件来访问文档中的信息...比如这里可能是Reading/Writing a MS Word file in PHP

    【讨论】:

    • 不是公共应用。所以我很乐意将粘贴复制到表单中。
    【解决方案4】:
    $oldList = file('oldList.txt');
    $newList = file('newList.txt');
    $list = array_udiff($newList, $oldList, 'compare');
    
    function compare($new, $old) {
        similar_text($old, substr($new, 3), $percent);
        return $percent >= 80 ? 0 : 1;
    }
    

    这是我的基本想法。查找所有 80% 相似的文本并将它们从 $newList 中删除。您应该调整百分比以满足您的需要。 M/ssubstr($new, 3) 删除。

    【讨论】:

    • 感谢您的代码。比较两个块时我得到了 60 秒的超时(每个块大约 80kb)
    • 我添加了一个 var_dump($list);输出发布在原始问题中
    【解决方案5】:

    如果没有用于唯一标识记录的关键字段,我认为您将不得不使用 similar_textlevenshtein 之类的东西。

    $arOld = file('olddata.txt');
    $arNew = file('newdata.txt');
    foreach($arNew as $line){
       $line = trim(substr($line, 3));
       foreach($arOld as $old){
        similar_text($line, $old, $percentage);
        if ($percentage < 60){
            echo $line;
        }
       }
    }
    

    【讨论】:

    • 第 6 行新增未定义变量
    • 这是 $line,而不是 $new。对不起。
    • 我使用原始帖子中的示例运行脚本。输出发布在原始问题中
    • 再想一想,它是行不通的。它需要稍作修改才能工作。现在它会打印很多行。
    • 是的,它确实打印了很多行。原则是将一个文本块中的每个单词与第二个单词块的所有单词匹配,然后回显那些匹配的单词。但是公司名称是多个单词......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多