不区分大小写的string比较
我想比较两个variables,看它们是否相同,但我希望这种比较是不区分大小写的。
例如,这将是区分大小写的:
if($var1 == $var2){ ... }
但我希望这是不区分大小写的,我将如何处理这个?
这很简单, 你只需要在两个variables上调用strtolower()
。
如果您需要处理Unicode或国际字符集,则可以使用mb_strtolower()
。
请注意,其他答案build议使用strcasecmp()
– 该函数不处理多字节字符,所以任何UTF-8string的结果将是假的。
如果string是相同的(除了大小写变化), strcasecmp()
返回0,所以你可以使用:
if (strcasecmp($var1, $var2) == 0) { }
如果你的string是单字节编码,那很简单:
if(strtolower($var1) === strtolower($var2))
如果您的string是UTF-8,则必须考虑Unicode的复杂性:小写和大写不是双射函数,即如果您有小写字符,则将其转换为大写字母,然后转换它回到小写,你可能不会结束了相同的代码点(如果你以大写字母开头,也是如此)。
例如
- “İ”(
Latin Capital Letter I with Dot Above, U+0130
带点Latin Capital Letter I with Dot Above, U+0130
)是一个大写字母,以“i”(Latin Small Letter I, U+0069
)作为小写字母变体 – 和“i”的大写字母变体是“我”(Latin Capital Letter I, U+0049
)。 - “
Latin Small Letter Dotless I, U+0131
”(Latin Small Letter Dotless I, U+0131
)是一个小写字母,“I”(Latin Capital Letter I, U+0049
)作为其大写变体 – 而“I”的小写变体是“我”(Latin Small Letter I, U+0069
)
所以mb_strtolower('ı') === mb_strtolower('i')
返回false,即使他们有相同的大写字符。 如果您确实需要不区分大小写的string比较函数,则必须将其与大写字母和小写字母版本进行比较:
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中有一个解决scheme: 规范化 ! 有四种不同的forms:NFC,NFD,NFKC,NFKD。 对于string比较,NFC和NFD是等价的,NFKC和NFKD是等价的。 我认为NFKC比NFKD短,而“ff”( Latin Small Ligature ff, U+FB00
)会变成两个正常的“f”(但是25也会扩大到25 …)。
由此产生的function变成:
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); }
请注意:
- 您需要用于Normalizer的intl包
- 你应该优化这个function,首先检查它们是否等于^^
- 你可能想使用NFC而不是NFKC,因为NFKC为你的口味删除了太多的格式化区分
- 你必须自己决定,如果你真的需要所有的复杂性,或者如果你喜欢这个函数的更简单的变种
if(strtolower($var1) == strtolower($var2)){ }
使用strcasecmp 。
为什么不:
if(strtolower($var1) == strtolower($var2)){ }