在PHP中,我们可以使用mb_check_encoding()
来判断一个字符串是否是有效的UTF-8,但这不是一个可移植的解决方案,因为它需要编译并启用mbstring扩展。此外,它不会告诉我们 * 哪个 * 字符是无效的。
是否有正则表达式(或其他100%可移植的方法)可以匹配给定字符串中的无效UTF-8字节?
这样,如果需要的话,这些字节可以被替换(保留二进制信息,例如当构建一个包含二进制数据的测试输出XML文件时)。因此,将字符转换为UTF-8会丢失信息。因此,我们可能需要转换:
"foo" . chr(128) . chr(255)
进入
"foo<128><255>"
因此,仅仅“检测”字符串还不够好,我们需要能够检测哪些字符是无效的。
4条答案
按热度按时间ruarlubt1#
这对我检测Unicode字符,链接表情符号,俄语或中文工作:
7cjasjjr2#
你可以使用这个PCRE正则表达式来检查字符串中是否有不是有效UTF-8的字节序列。如果正则表达式匹配,则字符串包含无效字节序列。它是100%可移植的,因为它不依赖于PCRE_UTF8来编译。
我们可以通过创建一些文本变体来测试它:
等等。
事实上,由于这与无效字节匹配,因此可以在preg_replace中使用它来替换它们:
ktca8awb3#
假设PHP是用PCRE编译的,那么它通常也会启用UTF-8。因此,正如问题中明确要求的那样,这个非常简单的正则表达式可以检测无效的UTF-8字符串,因为这些字符串不匹配:
然后,您可以争辩说
u
修饰符(PCRE_UTF8)并不总是可用的,这是真的,可能会发生如下问题所示的情况:u
flag dependent on?然而,在我实际的开发人员生活中,这从来不是一个问题。更重要的问题是PCRE扩展根本不可用,这将使任何包含PCRE的答案都变得无用(甚至我在这里)。但大多数情况下,这个问题更多的是过去的问题,直到今天再减去几年。
在这个不知何故重复的问题中,给出了一个类似于这个问题的更长的答案:
因此,我认为这个问题应该强调建议答案带来的更多好处。
guicsvcw4#
The W3C has a page (titled Multilingual form encoding),它列出了与有效UTF-8字符串匹配的以下Perl正则表达式。
(Note这与此SO问题的另一个答案中列出的正则表达式相反,后者匹配 * invalid* UTF-8字符串。)