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

问题描述 投票:0回答:7

我想比较两个变量以查看它们是否相同,但我希望此比较不区分大小写。

例如,这将区分大小写:

if($var1 == $var2){
   ...
}

但我希望不区分大小写,我该如何处理?

php if-statement case-insensitive
7个回答
146
投票

这相当简单;您只需对两个变量调用

strtolower()
即可。

如果需要处理Unicode或国际字符集,可以使用

mb_strtolower()

请注意,其他答案建议使用

strcasecmp()
- 该函数不处理多字节字符,因此任何 UTF-8 字符串的结果都将是伪造的。


77
投票
如果字符串相同(除了大小写变化),

strcasecmp()
返回 0,因此您可以使用:

if (strcasecmp($var1, $var2) == 0) {
}

22
投票

如果您的字符串采用单字节编码,那就很简单:

if(strtolower($var1) === strtolower($var2))

如果您的字符串是 UTF-8,则必须考虑 Unicode 的复杂性:to-lower-case 和 to-upper-case 不是双射函数,即如果您有小写字符,请将其转换为大写,然后将其转换回小写,您可能不会得到相同的代码点(如果您以大写字符开头,情况也是如此)。

例如

  • “й” (
    Latin Capital Letter I with Dot Above, U+0130
    ) 是一个大写字符,“i”(
    Latin Small Letter I, U+0069
    ) 是其小写变体 – 而“i”的大写变体是“I”(
    Latin Capital Letter I, U+0049
    )。
  • “ı” (
    Latin Small Letter Dotless I, U+0131
    ) 是小写字符,“I”(
    Latin Capital Letter I, U+0049
    ) 是其大写变体 – “I”的小写变体是“i”(
    Latin Small Letter I, U+0069
    )

因此

mb_strtolower('ı') === mb_strtolower('i')
返回 false,即使它们具有相同的大写字符。如果你真的想要一个不区分大小写的字符串比较函数,你必须比较大写版本和小写版本:

if(mb_strtolower($string1) === mb_strtolower($string2)
  || mb_strtoupper($string1) === mb_strtoupper($string2))

我已经从 https://codepoints.net (https://dumps.codepoints.net) 对 Unicode 数据库运行了查询,并且找到了 180 个代码点,当我发现这些代码点时,我发现了不同的字符采用小写字符的大写字母的小写字母,以及在采用大写字符的小写字母的大写字母时发现不同字符的 8 个代码点

但情况变得更糟:用户看到的同一个字素簇可能有多种编码方式:“ä”可能表示为

Latin Small Letter a with Diaeresis (U+00E4)
Latin Small Letter A (U+0061)
Combining Diaeresis (U+0308)
- 如果你比较它们在字节级别,这不会返回 true!

但是 Unicode 中有一个解决方案:标准化!有四种不同的形式:NFC、NFD、NFKC、NFKD。对于字符串比较,NFC 和 NFD 是等效的,NFKC 和 NFKD 是等效的。我会选择 NFKC,因为它比 NFKD 短,并且“ff”(

Latin Small Ligature ff, U+FB00
) 将转换为两个正常的“f”(但 2⁵ 也会扩展为 25...)。

结果函数变为:

function mb_is_string_equal_ci($string1, $string2) {
    $string1_normalized = Normalizer::normalize($string1, Normalizer::FORM_KC);
    $string2_normalized = Normalizer::normalize($string2, Normalizer::FORM_KC);
    return mb_strtolower($string1_normalized) === mb_strtolower($string2_normalized)
            || mb_strtoupper($string1_normalized) === mb_strtoupper($string2_normalized);
}

请注意:

  • 您需要 Normalizerintl
  • 您应该通过首先检查它们是否相等来优化此函数^^
  • 您可能想使用 NFC 而不是 NFKC,因为 NFKC 根据您的口味删除了太多格式差异
  • 您必须自己决定,您是否真的需要所有这些复杂性,或者您是否更喜欢此功能的更简单变体

2
投票
if(strtolower($var1) == strtolower($var2)){
}

0
投票

为什么不:

if(strtolower($var1) == strtolower($var2)){
}

0
投票

使用strcasecmp


0
投票
// to return boolean "are input strings equal?"
function mb_strcasecmp($s1,$s2): bool {
  return mb_strlen($s1) == mb_strlen($s2) && 0 === mb_stripos($s1,$s2);
}
© www.soinside.com 2019 - 2024. All rights reserved.