You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP中如何实现检测两字符串仅单个字符差异的函数?

判断两个字符串差异是否恰好为1个字符的PHP实现

Alright, let's break down how to solve this problem. The built-in levenshtein() function works great for the first three scenarios you mentioned, but it falls short for the ASTRING / STRINGB case because the edit distance here is 2 (remove 'A' from the start and add 'B' to the end). If we want to consider this scenario as a valid "single character difference" (since they share the core substring STRING with one extra character on each end), we need a custom function that checks both the edit distance and this edge case.

自定义函数实现

Here's a PHP function that covers all your required scenarios:

function isSingleCharDifference(string $str1, string $str2): bool {
    $len1 = strlen($str1);
    $len2 = strlen($str2);

    // 长度差超过1的直接排除
    if (abs($len1 - $len2) > 1) {
        return false;
    }

    // 长度相同的情况:检查是否只有一个字符不同,或是首尾各多一个匹配核心的情况
    if ($len1 === $len2) {
        $diffCount = 0;
        for ($i = 0; $i < $len1; $i++) {
            if ($str1[$i] !== $str2[$i]) {
                $diffCount++;
                // 超过一个差异直接退出循环
                if ($diffCount > 1) {
                    break;
                }
            }
        }
        if ($diffCount === 1) {
            return true;
        }
        // 检查是否去掉其中一个的首字符等于另一个去掉尾字符
        return substr($str1, 1) === substr($str2, 0, $len2 - 1) || substr($str2, 1) === substr($str1, 0, $len1 - 1);
    }

    // 长度差1的情况:检查较长字符串是否是较短字符串插入一个字符得到的
    $longer = $len1 > $len2 ? $str1 : $str2;
    $shorter = $len1 > $len2 ? $str2 : $str1;

    for ($i = 0; $i < strlen($shorter); $i++) {
        if ($longer[$i] !== $shorter[$i]) {
            // 从差异位置开始,较长字符串剩余部分是否和较短字符串剩余部分匹配
            return substr($longer, $i + 1) === substr($shorter, $i);
        }
    }
    // 如果循环结束都没差异,说明额外字符在较长字符串的末尾
    return true;
}

测试场景验证

Let's test this function against your specific cases:

  • isSingleCharDifference("STRIN1G", "STRIN2G") → true(单个字符替换)
  • isSingleCharDifference("ONE TOO THREE", "ONE TWO THREE") → true(单个字符替换:'O'→'W')
  • isSingleCharDifference("NATALI", "NATALIE") → true(末尾多一个字符)
  • isSingleCharDifference("ASTRING", "STRINGB") → true(符合首尾各带一个额外字符但核心匹配的边缘场景)

为什么不只用levenshtein?

The levenshtein($str1, $str2) === 1 check works for the first three scenarios because each only requires one edit (replace, insert, delete). However, for ASTRING and STRINGB, it takes two edits (remove 'A', add 'B'), so levenshtein returns 2. Our custom function adds a check for this specific edge case where the two strings share a core substring with one extra character on opposite ends.

内容的提问来源于stack exchange,提问作者Dino Cagalj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:24:15