当前位置: 首页> 最新文章列表> levenshtein 函数能和正则表达式一起用吗?PHP 模糊匹配新思路

levenshtein 函数能和正则表达式一起用吗?PHP 模糊匹配新思路

gitbox 2025-06-27

在 PHP 中,levenshtein 函数是一个用于计算两个字符串之间的编辑距离的函数,通常用于实现模糊匹配。它通过计算从一个字符串转换到另一个字符串所需的插入、删除和替换操作的最少次数来评估相似性。虽然 levenshtein 函数本身非常有用,但在一些复杂的字符串匹配场景中,我们可能会想要将它与正则表达式结合使用,以便在实现灵活的模糊匹配时,获得更强大的能力。

什么是 levenshtein 函数?

levenshtein 函数的基本语法如下:

<span><span><span class="hljs-keyword">int</span></span><span> </span><span><span class="hljs-title function_ invoke__">levenshtein</span></span><span> ( </span><span><span class="hljs-keyword">string</span></span><span> </span><span><span class="hljs-variable">$str1</span></span><span> , </span><span><span class="hljs-keyword">string</span></span><span> </span><span><span class="hljs-variable">$str2</span></span><span> [, </span><span><span class="hljs-keyword">int</span></span><span> &amp;</span><span><span class="hljs-variable">$cost_ins</span></span><span> = </span><span><span class="hljs-number">1</span></span><span> , </span><span><span class="hljs-keyword">int</span></span><span> &amp;</span><span><span class="hljs-variable">$cost_rep</span></span><span> = </span><span><span class="hljs-number">1</span></span><span> , </span><span><span class="hljs-keyword">int</span></span><span> &amp;</span><span><span class="hljs-variable">$cost_del</span></span><span> = </span><span><span class="hljs-number">1</span></span><span> ] )
</span></span>
  • $str1$str2 是要进行比较的两个字符串。

  • 可选的 $cost_ins$cost_rep$cost_del 分别表示插入、替换和删除操作的费用(默认都是 1)。

函数的返回值是一个整数,表示将字符串 $str1 转换为 $str2 所需的最小操作数。例如,levenshtein('kitten', 'sitting') 会返回 3,因为“kitten”到“sitting”的转变需要三次操作:替换“k”为“s”、替换“e”为“i”、以及添加“g”。

正则表达式在 PHP 中的作用

正则表达式(RegEx)是用来匹配字符串模式的强大工具。在 PHP 中,常用的正则匹配函数有 preg_matchpreg_match_allpreg_replace 等。正则表达式可以用于模式匹配、查找、替换等操作,特别适合处理复杂的字符串匹配问题。

如何将 levenshtein 和正则表达式结合使用?

尽管 levenshtein 和正则表达式是两个功能强大的工具,但它们并不是天然“结合”的。levenshtein 是计算两个字符串之间的距离,而正则表达式是用于匹配模式。它们可以在某些情况下互相补充。

示例 1:用 levenshtein 进行模糊匹配

假设我们要从一个包含若干个单词的字符串中找到与用户输入的单词最相似的单词。我们可以通过 levenshtein 函数计算每个单词与用户输入的字符串之间的相似度,从而选择最接近的单词。

<span><span><span class="hljs-variable">$words</span></span><span> = [</span><span><span class="hljs-string">"apple"</span></span><span>, </span><span><span class="hljs-string">"banana"</span></span><span>, </span><span><span class="hljs-string">"orange"</span></span><span>, </span><span><span class="hljs-string">"grape"</span></span><span>, </span><span><span class="hljs-string">"kiwi"</span></span><span>];
</span><span><span class="hljs-variable">$user_input</span></span><span> = </span><span><span class="hljs-string">"applw"</span></span><span>; </span><span><span class="hljs-comment">// 用户输入的模糊单词</span></span><span>

</span><span><span class="hljs-variable">$closest_match</span></span><span> = </span><span><span class="hljs-string">""</span></span><span>;
</span><span><span class="hljs-variable">$min_distance</span></span><span> = PHP_INT_MAX;

</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$words</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$word</span></span><span>) {
    </span><span><span class="hljs-variable">$distance</span></span><span> = </span><span><span class="hljs-title function_ invoke__">levenshtein</span></span><span>(</span><span><span class="hljs-variable">$user_input</span></span><span>, </span><span><span class="hljs-variable">$word</span></span><span>);
    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$distance</span></span><span> &lt; </span><span><span class="hljs-variable">$min_distance</span></span><span>) {
        </span><span><span class="hljs-variable">$min_distance</span></span><span> = </span><span><span class="hljs-variable">$distance</span></span><span>;
        </span><span><span class="hljs-variable">$closest_match</span></span><span> = </span><span><span class="hljs-variable">$word</span></span><span>;
    }
}

</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"最相似的单词是: <span class="hljs-subst">$closest_match</span></span></span><span>";
</span></span>

在这个例子中,我们遍历了所有单词,使用 levenshtein 函数计算与用户输入的单词的距离,并最终选出了最相似的单词。

示例 2:结合正则表达式和 levenshtein 进行复杂的模糊匹配

在某些情况下,您可能希望首先通过正则表达式匹配一些基本的模式,再通过 levenshtein 进行更精确的匹配。例如,如果用户输入了一个大致的模式(如前缀或后缀),您可以用正则表达式来过滤出潜在的匹配项,然后再使用 levenshtein 来找到最相似的结果。

<span><span><span class="hljs-variable">$words</span></span><span> = [</span><span><span class="hljs-string">"apple"</span></span><span>, </span><span><span class="hljs-string">"banana"</span></span><span>, </span><span><span class="hljs-string">"orange"</span></span><span>, </span><span><span class="hljs-string">"grape"</span></span><span>, </span><span><span class="hljs-string">"kiwi"</span></span><span>];
</span><span><span class="hljs-variable">$user_input</span></span><span> = </span><span><span class="hljs-string">"applw"</span></span><span>; </span><span><span class="hljs-comment">// 用户输入的模糊单词</span></span><span>
</span><span><span class="hljs-variable">$pattern</span></span><span> = </span><span><span class="hljs-string">"/^ap/"</span></span><span>; </span><span><span class="hljs-comment">// 正则表达式,匹配以 "ap" 开头的单词</span></span><span>

</span><span><span class="hljs-comment">// 使用正则过滤出符合模式的单词</span></span><span>
</span><span><span class="hljs-variable">$matches</span></span><span> = </span><span><span class="hljs-title function_ invoke__">preg_grep</span></span><span>(</span><span><span class="hljs-variable">$pattern</span></span><span>, </span><span><span class="hljs-variable">$words</span></span><span>);

</span><span><span class="hljs-variable">$closest_match</span></span><span> = </span><span><span class="hljs-string">""</span></span><span>;
</span><span><span class="hljs-variable">$min_distance</span></span><span> = PHP_INT_MAX;

</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$matches</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$match</span></span><span>) {
    </span><span><span class="hljs-variable">$distance</span></span><span> = </span><span><span class="hljs-title function_ invoke__">levenshtein</span></span><span>(</span><span><span class="hljs-variable">$user_input</span></span><span>, </span><span><span class="hljs-variable">$match</span></span><span>);
    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$distance</span></span><span> &lt; </span><span><span class="hljs-variable">$min_distance</span></span><span>) {
        </span><span><span class="hljs-variable">$min_distance</span></span><span> = </span><span><span class="hljs-variable">$distance</span></span><span>;
        </span><span><span class="hljs-variable">$closest_match</span></span><span> = </span><span><span class="hljs-variable">$match</span></span><span>;
    }
}

</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"最相似的单词是: <span class="hljs-subst">$closest_match</span></span></span><span>";
</span></span>

在这个例子中,我们首先通过正则表达式过滤出所有以“ap”开头的单词,然后使用 levenshtein 来进一步找到最相似的单词。这种方法特别适用于当你知道一些匹配条件(例如前缀、后缀或特定的字符模式)时,通过正则表达式过滤掉不必要的选项,从而提高效率。

使用正则与 levenshtein 的优势

  1. 提高匹配准确性:通过正则表达式,你可以预先筛选出符合一定条件的字符串,再通过 levenshtein 精细地计算最接近的字符串。

  2. 优化性能:如果你的数据集很大,通过正则表达式提前筛选匹配项,可以避免对所有字符串都进行 levenshtein 计算,从而提高性能。

  3. 灵活性:正则表达式可以处理复杂的模式匹配,比如区分大小写、匹配某些特定字符集等,而 levenshtein 可以用于进一步对筛选出的字符串进行精细的相似度比较。

总结

虽然 levenshtein 和正则表达式看似是两个独立的工具,但在实际开发中,它们的结合可以为 PHP 提供更强大的模糊匹配能力。通过正则表达式先行筛选,接着用 levenshtein 精确计算,可以有效提升匹配的准确度与效率。根据需求不同,可以灵活选择这两者的组合方式,从而更好地满足特定的应用场景。