不考虑 PHP 顺序的字符串比较

Posted

技术标签:

【中文标题】不考虑 PHP 顺序的字符串比较【英文标题】:String comparison regardless of the PHP order 【发布时间】:2019-09-30 11:23:56 【问题描述】:

想知道有没有办法通过一些php的方法进行比较,验证两条链不分先后顺序是一样的,

例如:

     $string1 = "Pedro Perez";$string2 = "Perez Pedro";

所以我的问题是如何在比较中制作这个TRUE。显然,您的订单与众不同。


我问这个问题是因为我正在开发搜索,并且我希望将 $string1$string2 的比较视为相同的值,无论它们的顺序如何,只要字符串具有相同的单词

【问题讨论】:

||?为什么要同时检查 1 是否为真并满足您的条件? o.O 试试 $string1==$string2 你可以检查字符串是否有多个单词。然后将 then 添加到一个数组中,然后检查该数组是否包含相同的值 如果您正在开发搜索 - 您可以使用 Natural language search 将其放入 FULLTEXT 索引并让 mysql 处理它... 【参考方案1】:

你按空间分解它并按如下方式与两个数组相交并检查它的计数

$string1 = "Pedro Perez";
$string2 = "Perez Pedro";
$s1 = array_unique(explode(" ", $string1));
$s2 = array_unique(explode(" ", $string2));
$temp = array_intersect($s1, $s2);
var_dump(count($temp) == count($s1) && count($temp) == count($s2));

编辑

这里多两个字就是sn-p,

$string1 = "Perez Perez Pedro";
$string2 = "Perez Pedro Perez";
list($s1,$s2) = [explode(" ", $string1), explode(" ", $string2)];
sort($s1);sort($s2);
var_dump($s1 === $s2);

工作demo。

【讨论】:

很棒的方法。 如果数组包含两次元素,这将产生错误的结果:test case 是否可以,取决于要求。 'Perez Perez Pedro''Perez Pedro Pedro' 将在 array_unique 之后产生 true,根据问题,这似乎不正确。 @Namoshek 我进行了更改。请检查 不幸的是,由于与 == 而不是 === 的不安全类型比较,这仍然会产生数字输入问题:test case【参考方案2】:

你可以试试这个。

    通过按空格分割将字符串转换为数组。 对数组进行排序。 将数组转换回字符串。 比较两者。

用简单的方式,给你...

<?php
  $string1 = "Pedro Perez";
  $string2 = "Perez Pedro";
  $string1 = explode(" ", $string1);
  $string2 = explode(" ", $string2);
  // Update: You don't save the output of sort, as it's by reference.
  sort($string1);
  sort($string2);
  $string1 = implode(" ", $string1);
  $string2 = implode(" ", $string2);
  var_dump($string1 === $string2);
?>

【讨论】:

我不认为implode 部分是必要的。如果数组包含相同顺序的相同元素,则与=== 的严格数组比较将产生true。并且检查甚至是类型安全的,不会尝试转换类型。【参考方案3】:

另一种方法

$string1 = "Pedro Perez";
$string2 = "Perez Pedro";
$s1 = explode(" ", $string1);
$s2 = explode(" ", $string2);
$comp = empty( array_diff($s1, $s2) ) ? true : false;

【讨论】:

如果数组包含两次元素,这也会产生错误的结果:test case【参考方案4】:

最简单的部分是将字符串拆分为单词并按大小比较数组。如果大小不一样,字符串就不能一样:

function str_equals_ignore_word_order(string $str1, string $str2): bool

    $words1 = explode(' ', $str1);
    $words2 = explode(' ', $str2);

    if (count($words1) !== count($words2)) 
        return false;
    

    // Here comes one of the following or already suggested solutions.

有了这些,我们有很多可能的解决方案来实际比较两个单词数组,预计它们的顺序不同。

已建议编号。 1

排序和比较(没有implode的简化):

sort($words1);
sort($words2);

return $words1 === $words2;

这样做是安全的,并且不会更改输入,因为字符串在传递给函数时会被复制,我们甚至在使用 explode 时将字符串复制到多个部分。

构建字典

计算每个单词的出现次数并考虑单词计数可以防止其他解决方案在输入字符串中出现两次的单词出现问题。此解决方案还允许选择不同的字典比较:

$words1 = array_count_values($words1);
$words2 = array_count_values($words2);

// Comparison 1
$intersect = array_intersect_assoc($words1, $words2);
return count($intersect) === count($words1) && count($words1) === count($words2);

// Comparison 2
$diff = array_diff_assoc($words1, $words2);
return empty($diff);

值得注意

如果预计输入包含拼写错误,例如紧接在另一个 ' ' 之后的两个空格,您应该在两个单词数组上使用 array_filter($words1) 以确保没有匹配的 NULL 单词。

【讨论】:

【参考方案5】:

一个有趣的简短函数,必要时不排序。

比较拆分字符串字数, 排序单词数组, 比较字数组。
// Split the sentences, compare word count, sort words, compare sorted words
function compare_words($a, $b)  
  return count($a = explode(' ', $a)) == count($b = explode(' ', $b)) 
    && sort($a) 
    && sort($b) 
    && $a === $b;
;

【讨论】:

以上是关于不考虑 PHP 顺序的字符串比较的主要内容,如果未能解决你的问题,请参考以下文章

字符串的字典比较[不区分大小写]

如何在 PHP 中按字母顺序比较 2 个字符串?

Oracle函数以无序方式比较字符串

PHP中国际化的字符串比较对象

strcmp函数怎么用?

比较2个字符串而不考虑Python中的重音[重复]