繁体   English   中英

preg_match()和多字节字符

[英]preg_match() and multibyte characters

我正在尝试使用preg_match处理波兰语字符,但有些事情是非常错误的。

这些是我的尝试:

  1. 没有u修饰符:

     preg_match("@^[0-9A-ZĄąĆćĘꣳÓ󯿏źŃńŚś\\-\\.\\, ]{5,35}$@i", $valuesId) 
  2. 使用u修饰符:

     preg_match("@^[0-9A-ZĄąĆćĘꣳÓ󯿏źŃńŚś\\-\\.\\, ]{5,35}$@iu", $valuesId) 

但是像ŻółkiewskiZielona GóraRównina这样的词语不能不过去。

有没有人知道如何正确处理它而不改变服务器设置?

你的正则表达式按预期工作。 但只有当角色以UTF-8 您是否正在使用字符编码设置为ISO-8859-2 (中欧ISO拉丁文2)的系统,这是波兰字符的ISO标准字符集? 看看我放在一起的这个示例/调试代码。 注意我尝试了mb_detect_encoding以及mb_convert_encoding但不清楚这是否有帮助或mb_convert_encoding 如果它变得令人困惑,请随意注释掉那部分代码:

// Set a test array.
$test_array = array();
$test_array[] = 'Żółkiewski';
$test_array[] = 'Zielona Góra';
$test_array[] = 'Równina';

// Get the contenst of the URL via file_get_contents.
if (file_exists('zzz_polish.txt')) {
  $test_file_array = file('zzz_polish.txt');
}

// Set the header for debugging output.
header('Content-Type: text/plain; charset=utf-8');

// Roll through the test array.
foreach ($test_file_array as $valuesId) {

  // Run a regex to detect Polish UTF-8 characters.
  preg_match("@^[0-9A-ZĄąĆćĘꣳÓ󯿏źŃńŚś\-\.\, ]{5,35}$@i", $valuesId, $matches);

  // Set the character encoding to be UTF-8 if it is not already UTF-8.
  if (mb_detect_encoding($valuesId) != 'UTF-8') {
    $valuesId = mb_convert_encoding($valuesId, 'UTF-8', array('ISO-8859-2'));
  }

  // Dump the matches for debugging.
  print_r($matches);

}

现在,如果将其放在带有.php扩展名的UTF-8编码文本文件中,结果如下:

Array
(
    [0] => Żółkiewski
)
Array
(
    [0] => Zielona Góra
)
Array
(
    [0] => Równina
)

这是预期的。 但我已经能够重新创建一个条件,它将失败,表面上看似数据放在名为zzz_polish.txt的文件中,如下所示:

Żółkiewski
Zielona Góra
Równina

现在,如果我使用正确的UTF-8编码保存该文件,它就像其中包含测试数组的示例一样。 但是如果我通过简单地将文件编码改为UTF-16而导致它失败,那么它在屏幕上的所有内容都是相同的,但输出结果如下:

Array
(
)
Array
(
)
Array
(
)

所以我的猜测是在你的数据链中某处发生了一些文本编码混淆。 你的正则表达式效果不错。

这些字符真的是多字节的吗?

如此在线演示所示,以下代码三次返回1TRUE值):

$regex = "@^[0-9A-ZĄąĆćĘꣳÓ󯿏źŃńŚś., -]{5,35}$@i";
echo preg_match($regex,"Żółkiewski")."\n";
echo preg_match($regex,"Zielona Góra")."\n";
echo preg_match($regex,"Równina")."\n";

因此问题不在于正则表达式,而是正则表达式所在的脚本编码与正则表达式输入的输入之间不匹配。 例如,您的脚本可能正在使用Windows或ISO东欧编码之一......在这种情况下,它们可能根本不是多字节的。 许多IDE和编辑器都能够转换文本文件的编码。

面向未来的最佳选择是确保系统的每个组件都能说明utf-8:

  • 脚本的编码
  • 脚本发送的标头
  • 元标记
  • 与数据库的连接
  • 数据库中的数据

等等。 解决如何实现所有这些问题是书籍章节的主题,超出了本问题的范围。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM