Perl 5 中填充正则表达式量词的 Unicode 字符
Unicode characters stuffing regex quantifiers in perl 5
我是 perl 的新手,在使用 perl 5 的多字节 unicode 字符 (utf-8) 上使用正则表达式量词时遇到问题,我希望它们只计算一个字符,但它们计算组成它们的字节数。
例如,我希望 .{1}
匹配 é
而 .{2}
不匹配,但我看到了:
$ echo 'begin é end' | perl -wnl -e '/begin .{1} end/s and print'
$ echo 'begin é end' | perl -wnl -e '/begin .{2} end/s and print'
begin é end
这显然是因为“é”是一个多字节字符,因为当我用一个简单的“e”替换它时,我得到了我期望的结果:
$ echo 'begin e end' | perl -wnl -e '/begin .{1} end/s and print'
begin e end
$ echo 'begin e end' | perl -wnl -e '/begin .{2} end/s and print'
使用一些 character set modifier(/d /u /a 和 /l)不会改变任何东西。
当我使用另一个 PCRE 正则表达式工具时,它起作用了:
- regex101 : https://regex101.com/r/a1Lb9g/1/
- php 7(使用
u
修饰符启用 unicode 支持):
$ echo 'begin é end' | php7 -r 'var_dump(preg_match("/begin .{1} end/su", file_get_contents("php://stdin")));'
Command line code:1:
int(1)
我的 TTY 使用 UTF-8 字符集,“é”被编码 c3a9
:
$ echo 'begin é end' | xxd
00000000: 6265 6769 6e20 c3a9 2065 6e64 0a begin .. end.
$ echo 'begin é end' | base64
YmVnaW4gw6kgZW5kCg==
我已经在几个 OS 和 perl 版本上进行了测试,我发现到处都是相同的行为:
This is perl 5, version 22, subversion 1 (v5.22.1) built for i686-msys-thread-multi-64int (Windows 7)
This is perl 5, version 26, subversion 1 (v5.26.1) built for x86_64-msys-thread-multi (Windows 10)
This is perl 5, version 22, subversion 1 (v5.22.1) built for x86_64-linux-gnu-thread-multi (Ubuntu 16.04)
如何使 perl 正则表达式量词将 unicode 字符计数为一个?
您需要告诉 Perl 输入是用 UTF-8 编码的。这是由 -CI
完成的。添加 O
以对输出进行编码:
echo 'begin é end' | perl -CIO -wnl -e '/begin .{1} end/s and print'
begin é end
我是 perl 的新手,在使用 perl 5 的多字节 unicode 字符 (utf-8) 上使用正则表达式量词时遇到问题,我希望它们只计算一个字符,但它们计算组成它们的字节数。
例如,我希望 .{1}
匹配 é
而 .{2}
不匹配,但我看到了:
$ echo 'begin é end' | perl -wnl -e '/begin .{1} end/s and print'
$ echo 'begin é end' | perl -wnl -e '/begin .{2} end/s and print'
begin é end
这显然是因为“é”是一个多字节字符,因为当我用一个简单的“e”替换它时,我得到了我期望的结果:
$ echo 'begin e end' | perl -wnl -e '/begin .{1} end/s and print'
begin e end
$ echo 'begin e end' | perl -wnl -e '/begin .{2} end/s and print'
使用一些 character set modifier(/d /u /a 和 /l)不会改变任何东西。
当我使用另一个 PCRE 正则表达式工具时,它起作用了:
- regex101 : https://regex101.com/r/a1Lb9g/1/
- php 7(使用
u
修饰符启用 unicode 支持):
$ echo 'begin é end' | php7 -r 'var_dump(preg_match("/begin .{1} end/su", file_get_contents("php://stdin")));'
Command line code:1:
int(1)
我的 TTY 使用 UTF-8 字符集,“é”被编码 c3a9
:
$ echo 'begin é end' | xxd
00000000: 6265 6769 6e20 c3a9 2065 6e64 0a begin .. end.
$ echo 'begin é end' | base64
YmVnaW4gw6kgZW5kCg==
我已经在几个 OS 和 perl 版本上进行了测试,我发现到处都是相同的行为:
This is perl 5, version 22, subversion 1 (v5.22.1) built for i686-msys-thread-multi-64int (Windows 7)
This is perl 5, version 26, subversion 1 (v5.26.1) built for x86_64-msys-thread-multi (Windows 10)
This is perl 5, version 22, subversion 1 (v5.22.1) built for x86_64-linux-gnu-thread-multi (Ubuntu 16.04)
如何使 perl 正则表达式量词将 unicode 字符计数为一个?
您需要告诉 Perl 输入是用 UTF-8 编码的。这是由 -CI
完成的。添加 O
以对输出进行编码:
echo 'begin é end' | perl -CIO -wnl -e '/begin .{1} end/s and print'
begin é end