比较PHP中的字符串,如果它们相似,则从数组中删除其中一个字符串

Cod*_*art 7 php function

假设我有一个这样的数组:

  • 马的乐队 - 有鬼吗
  • 马的乐队 - 没有人会爱你
  • 马的乐队 - 葬礼
  • 马的乐队 - 葬礼(中描述的歌词)
  • 马队 - 拉雷多
  • 马乐队 - 莱特多在莱特曼5.20.10
  • 马队 - "大盐湖"子流行唱片
  • 新人报道 - "没有人会爱你"
  • 马乐队在特罗姆瑟婚礼上演唱Marry Song
  • 马的乐队 - 没有人会爱你
  • Q电视上的Band of Horses的'Laredo'
  • 马的乐队,在我回家的路上
  • 马的乐队 - 香烟结婚戒指
  • 马队 - "香烟婚礼乐队"
  • 新人报道 - 我去谷仓因为我喜欢
  • 我们的剑 - 马的乐队
  • 马匹乐队 - "嫁给歌曲"
  • 马的乐队 - 怪物
  • 马的乐队 - 没有人会爱你

新阵列将具有:

  • 马的乐队 - 有鬼吗
  • 马的乐队 - 没有人会爱你
  • 马的乐队 - 葬礼
  • 马队 - 拉雷多
  • 马队 - "大盐湖"子流行唱片
  • 马的乐队,在我回家的路上
  • 马的乐队 - 香烟结婚戒指
  • 新人报道 - 我去谷仓因为我喜欢
  • 我们的剑 - 马的乐队
  • 马匹乐队 - "嫁给歌曲"
  • 马的乐队 - 怪物

你会如何去在PHP列表中的每个字符串比较所有其它字符串,如果它们是相似的,删除它们.

我认为这些相似:

  • 马的乐队 - 葬礼
  • Band of Horses - The Funeral(描述中的歌词)

另一个例子:

  • 马队 - 拉雷多
  • 马乐队 - 莱特多在莱特曼5.20.10

Pet*_*tai 13

你有多种选择.

对于每个选项,您可能应该在执行比较之前按下相册名称.您可以通过剥离标点符号,按字母顺序(在某些情况下)对专辑名称中的单词进行排序等来完成此操作.

在每种情况下,当您进行比较时,如果从阵列中删除其中一个相册名称,则您的比较是对订单敏感的,除非您对要删除的相册名称进行规则.因此,如果比较两个专辑名称并发现"相似",则总是删除较长的专辑名称可能是有意义的.

主要比较选项是

  1. 简单的子串比较.检查相册名称是否在另一个内.首先删除标点符号并对不区分大小写进行比较(请参阅下面的第二个代码段).

  2. 使用检查专辑名称相似性levenshtein().这种字符串比较更有效similar_text().你应该删除标点符号并按字母顺序排序.

  3. 使用检查专辑名称相似性similar_text().我用这种方法运气最好.事实上,我选择了您想要的确切专辑名称(请参阅下面的第一个代码段).

  4. 你可以使用各种其他字符串比较函数包括soundex()metaphone()

无论如何......这里有2个解决方案.

第一次使用similar_text()......但是只有在所有标点符号被剥离并且单词按字母顺序排列并且小写之后才会计算相似度......不足之处在于你必须使用阈值相似性...第二次使用在删除所有标点符号和空格后,进行简单的不区分大小写的子字符串测试.

两个代码片段的工作方式是它们用于在数组中的每个专辑上array_walk()运行该compare()函数.然后在compare()函数内部,我foreach()用来将当前专辑与所有其他专辑进行比较.有足够的空间来提高效率.

请注意,我应该使用第三个参数作为参考,array_walk有人可以帮我这样做吗?目前的解决方案是全局变量:


实例(69%相似度阈值)


function compare($value, $key)
{
    global $array; // Should use 3rd argument of compare instead

    $value = strtolower(preg_replace("/[^a-zA-Z0-9 ]/", "", $value));
    $value = explode(" ", $value);
    sort($value);
    $value = implode($value);
    $value = preg_replace("/[\s]/", "", $value); // Remove any leftover \s

    foreach($array as $key2 => $value2)
    {
        if ($key != $key2)
        {
            // collapse, and lower case the string            
            $value2 = strtolower(preg_replace("/[^a-zA-Z0-9 ]/", "", $value2));
            $value2 = explode(" ", $value2);
            sort($value2);
            $value2 = implode($value2);            
            $value2 = preg_replace("/[\s]/", "", $value2);

              // Set up the similarity
            similar_text($value, $value2, $sim);
            if ($sim > 69)
            {     // Remove the longer album name
                unset($array[ ((strlen($value) > strlen($value2))?$key:$key2) ]);
            }
        }
    }
}
array_walk($array, 'compare');
$array = array_values($array);
print_r($array);
Run Code Online (Sandbox Code Playgroud)

以上的输出是:

Array
(
    [0] => Band of Horses - Is There a Ghost
    [1] => Band Of Horses - No One's Gonna Love You
    [2] => Band of Horses - The Funeral
    [3] => Band of Horses - Laredo
    [4] => Band of Horses - "The Great Salt Lake" Sub Pop Records
    [5] => Band of Horses perform Marry Song at Tromso Wedding
    [6] => Band of Horses, On My Way Back Home
    [7] => Band of Horses - cigarettes wedding bands
    [8] => Band Of Horses - I Go To The Barn Because I Like The
    [9] => Our Swords - Band of Horses
    [10] => Band of Horses - Monsters
)
Run Code Online (Sandbox Code Playgroud)

请注意,Mary的歌曲的版本丢失了...所以它肯定是对其他东西的误报,因为长版本仍在列表中......但它们正是您想要的专辑名称.


子串方法:

实例


function compare($value, $key)
{
      // I should be using &$array as a 3rd variable.
      // For some reason couldn't get that to work, so I do this instead.
    global $array;   
      // Take the current album name and remove all punctuation and white space
    $value = preg_replace("/[^a-zA-Z0-9]/", "", $value);        
      // Compare current album to all othes
    foreach($array as $key2 => $value2)
    {
        if ($key != $key2)
        {

              // collapse the album being compared to
            $value2 = preg_replace("/[^a-zA-Z0-9]/", "", $value2);

            $subject = $value2;
            $pattern = '/' . $value . '/i';

              // If there's a much remove the album being compared to
            if (preg_match($pattern, $subject))
            {
                unset($array[$key2]);
            }
        }
    }
}
array_walk($array, 'compare');
$array = array_values($array);
echo "<pre>";
print_r($array);
echo "</pre>";
Run Code Online (Sandbox Code Playgroud)

对于您的示例字符串,上面的输出(它显示2您不想显示):

Array  
(  
    [0] => Band of Horses - Is There a Ghost  
    [1] => Band Of Horses - No One's Gonna Love You  
    [2] => Band of Horses - The Funeral  
    [3] => Band of Horses - Laredo  
    [4] => Band of Horses - "The Great Salt Lake" Sub Pop Records  
    [5] => Band of Horses perform Marry Song at Tromso Wedding      // <== Oops
    [6] => 'Laredo' by Band of Horses on Q TV                       // <== Oops  
    [7] => Band of Horses, On My Way Back Home  
    [8] => Band of Horses - cigarettes wedding bands  
    [9] => Band Of Horses - I Go To The Barn Because I Like The  
    [10] => Our Swords - Band of Horses  
    [11] => Band Of Horses - "Marry song"  
    [12] => Band of Horses - Monsters  
)
Run Code Online (Sandbox Code Playgroud)