我开始了在PHP中使用的preg_replace一些疯狂的失败和煮沸下来的问题的情况下使用土耳其虚线“i”和undotted“I”一起具有多于一个字符类的。下面是一个简单的测试案例在PHP:

<?php
    echo 'match single normal i: ';
    $str = 'mi';
    echo (preg_match('!m[ıi]!', $str)) ? "ok\n" : "fail\n";

    echo 'match single undotted ı: ';
    $str = 'mı';
    echo (preg_match('!m[ıi]!', $str)) ? "ok\n" : "fail\n";

    echo 'match double normal i: ';
    $str = 'misir';
    echo (preg_match('!m[ıi]s[ıi]r!', $str)) ? "ok\n" : "fail\n";

    echo 'match double undotted ı: ';
    $str = 'mısır';
    echo (preg_match('!m[ıi]s[ıi]r!', $str)) ? "ok\n" : "fail\n";
?>
在Perl

和相同的测试案例再次:

#!/usr/bin/perl

$str = 'mi';
$str =~ m/m[ıi]/ && print "match single normal i\n";

$str = 'mı';
$str =~ m/m[ıi]/ && print "match single undotted ı\n";

$str = 'misir';
$str =~ m/m[ıi]s[ıi]r/ && print "match double normal i\n";

$str = 'mısır';
$str =~ m/m[ıi]s[ıi]r/ && print "match double undotted ı\n";

在第一三个测试工作正常。最后一个不匹配。

为什么这工作精细的字符类一次,但不是在同一表达在第二时间?我怎样写一个表达式匹配的词像这样的需求,无论什么组合的字母它与写相匹配?

修改语言问题我试图程序。

修改2:添加use utf8;指令确实固定perl的版本。由于我原来的问题是用PHP程序,我只切换到Perl来看看它是否是在PHP中的错误,不帮我一大堆。的没有任何人知道的指示,使PHP在此不呛?

有帮助吗?

解决方案

多字节序列不会做你在括号字符类想要什么,如果UTF-8被误解释为8位字节序列。想想吧。如果[nñm]没有作为三个逻辑字符,但作为四个物理字节misconstructed,你只匹配其代码点是6E或C3或B1或6D的字符。

出于某些目的,你也许可以侥幸逃脱重写[nñm](?:n|ñ|m)。这只是取决于你在做什么。套管东西,将无法正常工作。

此外,Unicode有用于土耳其无点我特殊壳体的规则。

像PHP声音只是没有足够的现代化。叹息。

其他提示

您可能需要告诉Perl源文件包含UTF8字符。尝试:

#!/usr/bin/perl

use utf8;   # **** Add this line

$str = 'mısır';
$str =~ m/m[ıi]s[ıi]r/ && print "match double undotted ı\n";

这不利于你用PHP,但有可能在PHP中的类似指令。否则,请尝试使用某种形式的转义序列,以避免把文字字符在你的源代码。我什么都不知道关于PHP,所以我不能与帮助。

<强> 修改 结果 我读的是PHP没有Unicode支持。因此,传递给它的输入的unicode很可能视为字节,该unicode被编码为字符串。

如果你可以放心,您的输入在为UTF-8,然后可以匹配针对ı的UTF-8序列来这是\xc4 \xb1如:

$str = 'mısır';  # Make sure this source-file is encoded as utf-8 or this match will fail
echo (preg_match('!m(i|\xc4\xb1)s(i|\xc4\xb1)r!', $str)) ? "ok\n" : "fail\n";

运作的?

修改再次:结果 我可以解释为什么你的前三个测试通过。让我们假设你的编码,ı被编码为ABCDE。然后PHP看到以下情况:

echo 'match single normal i: ';
$str = 'mi';
echo (preg_match('!m[ABCDEi]!', $str)) ? "ok\n" : "fail\n";

echo 'match single undotted ABCDE: ';
$str = 'mABCDE';
echo (preg_match('!m[ABCDEi]!', $str)) ? "ok\n" : "fail\n";

echo 'match double normal i: ';
$str = 'misir';
echo (preg_match('!m[ABCDEi]s[ABCDEi]r!', $str)) ? "ok\n" : "fail\n";

echo 'match double undotted ABCDE: ';
$str = 'mABCDEsABCDEr';
echo (preg_match('!m[ABCDEi]s[ABCDEi]r!', $str)) ? "ok\n" : "fail\n";

这使得它明显为什么前三个测试通过,最后一个失败。如果您使用的开始/结束锚^...$我想你会发现只有第一个测试通过。

scroll top