Perl 中的正则表达式不匹配 Unicode 字符串
Regex in Perl not matching a Unicode String
我正在尝试使用 Perl 正则表达式匹配 Unicode 字符串。如果我将字符串输出到 STDOUT,该字符串似乎毫发无损地到达了我的模块:“Asuncion, Distrito Capital de Paraguay, Región Oriental, Paraguay.”
但是,它在 Regex 中不匹配。奇怪的是,如果我将脚本的输出复制到一个变量中并对其进行评估,那么 does 在同一个正则表达式中匹配:
use v5.12;
use utf8;
my $placeString = $main::FORM{'placeString'}; # Coming from a different module.
say STDOUT $placeString;
utf8::upgrade($placeString); # Using this or removing this seems to make no difference.
# If I manually copy the output of STDOUT (above) in BASH and set the string, it works:
$placeString2 = "Asuncion, Distrito Capital de Paraguay, Región Oriental, Paraguay";
if ($placeString =~ /^([\w\s\,\.\-\']+)$/) {
# This is evaluated as false.
say STDERR "Accepted placename.";
}
if ($placeString2 =~ /^([\w\s\,\.\-\']+)$/) {
# This is evaluated as true.
say STDERR "Accepted placename.";
}
However, it won't match in Regex.
从评论中可以清楚地看出该值是 UTF-8 编码的字符串。您需要在进行匹配之前对值进行解码:
use Encode qw(decode_utf8);
$placeString = decode_utf8($placeString);
$placeString2
是一串解码后的文本。您也可以将其称为一串 Unicode 代码点,因为它的每个字符都是这样。
52.65.67.69.F3.6E Unicode Code Points for "Región".
这些 UCP 中的每一个都适合一个字节,但情况并非总是如此。
49.2665.53.4F Unicode Code Points for "I♥SO".
$placeString
是一串编码文本。它的每个字符都是一个字节。
52.65.67.69.C3.B3.6E "Región" encoded using UTF-8.
49.E2.99.A5.53.4F "I♥SO" encoded using UTF-8.
解码输入,编码输出。
\w
和 \s
期望匹配 Unicode 代码点。但是正如我们已经确定的那样,$::FORM{placeString}
的值是这些代码点的编码。您需要对其进行解码。
my $placeString = $::FORM{placeString};
utf8::decode($placeString)
or warn(...);
或
use Encode qw( decode_utf8 );
my $placeString = decode_utf8($::FORM{placeString});
如果字符串来自文件句柄,则最好为句柄添加解码层。
我正在尝试使用 Perl 正则表达式匹配 Unicode 字符串。如果我将字符串输出到 STDOUT,该字符串似乎毫发无损地到达了我的模块:“Asuncion, Distrito Capital de Paraguay, Región Oriental, Paraguay.”
但是,它在 Regex 中不匹配。奇怪的是,如果我将脚本的输出复制到一个变量中并对其进行评估,那么 does 在同一个正则表达式中匹配:
use v5.12;
use utf8;
my $placeString = $main::FORM{'placeString'}; # Coming from a different module.
say STDOUT $placeString;
utf8::upgrade($placeString); # Using this or removing this seems to make no difference.
# If I manually copy the output of STDOUT (above) in BASH and set the string, it works:
$placeString2 = "Asuncion, Distrito Capital de Paraguay, Región Oriental, Paraguay";
if ($placeString =~ /^([\w\s\,\.\-\']+)$/) {
# This is evaluated as false.
say STDERR "Accepted placename.";
}
if ($placeString2 =~ /^([\w\s\,\.\-\']+)$/) {
# This is evaluated as true.
say STDERR "Accepted placename.";
}
However, it won't match in Regex.
从评论中可以清楚地看出该值是 UTF-8 编码的字符串。您需要在进行匹配之前对值进行解码:
use Encode qw(decode_utf8);
$placeString = decode_utf8($placeString);
$placeString2
是一串解码后的文本。您也可以将其称为一串 Unicode 代码点,因为它的每个字符都是这样。
52.65.67.69.F3.6E Unicode Code Points for "Región".
这些 UCP 中的每一个都适合一个字节,但情况并非总是如此。
49.2665.53.4F Unicode Code Points for "I♥SO".
$placeString
是一串编码文本。它的每个字符都是一个字节。
52.65.67.69.C3.B3.6E "Región" encoded using UTF-8.
49.E2.99.A5.53.4F "I♥SO" encoded using UTF-8.
解码输入,编码输出。
\w
和 \s
期望匹配 Unicode 代码点。但是正如我们已经确定的那样,$::FORM{placeString}
的值是这些代码点的编码。您需要对其进行解码。
my $placeString = $::FORM{placeString};
utf8::decode($placeString)
or warn(...);
或
use Encode qw( decode_utf8 );
my $placeString = decode_utf8($::FORM{placeString});
如果字符串来自文件句柄,则最好为句柄添加解码层。