Perl 1 liner:可以打印 unicode 输入但正则表达式不起作用;花哨的单词边界
Perl 1 liner: Can print unicode input but regex not working; fancy word boundaries
假设我有(在Bash):
txt="На берегу пустынных волн
Стоял он, дум великих полн,
И вдаль глядел."
如果我将其通过管道传递给 Perl,我可以毫无问题地打印:
$ echo "$txt" | perl -lnE 'say "$_"'
На берегу пустынных волн
Стоял он, дум великих полн,
И вдаль глядел.
但我对本文中的各种正则表达式有疑问。假设我添加新的 Fancy Word Boundaries:
$ echo "$txt" | perl -lnE 'while (/\b{wb}(.+?)\b{wb}/g) { print "\"\"" }'
"–"
"ù"
"–"
"∞"
" "
"–"
"±"
"–µ—"
"Ä"
...
# junk characters...
单词边界不起作用,输入的字符被更改。
(如果我将正则表达式更改为 /\b{wb}(.+)\b{wb}/g
,输出与第一个相同。(.+)
占用整行。)
我可以通过添加 -CASD 命令行开关来解决这些问题,并且花哨的单词边界按设计工作:
$ echo "$txt" | perl -CSAD -lnE 'while (/\b{wb}(.+?)\b{wb}/g) { print "\"\"" }'
"На"
" "
"берегу"
" "
"пустынных"
" "
"волн"
"Стоял"
" "
"он"
","
" "
"дум"
" "
"великих"
" "
"полн"
","
"И"
" "
"вдаль"
" "
"глядел"
"."
问题: perlrun 中的 -CASD
开关似乎暗示启用的 unicode 功能是针对 stdin
和 stdout
输入流。没有提到任何会改变正则表达式的内部差异。由于在第一种情况下我可以读取和打印 unicode,为什么添加 -CASD
会更改正则表达式?
$ perl -v
This is perl 5, version 28, subversion 0 (v5.28.0) built for darwin-thread-multi-2level
在第一种情况下,您不是在读取和打印 unicode,而是在读取和打印 UTF-8。对于 Perl,这些字符串由字节(八位字节)组成,而不是字符,因此它可以在多字节序列的中间找到单词边界。有关详细信息,请参阅 perlunicode。
Since I can read and print unicode in the first case, why does adding -CASD
change the regex?
该命令行选项只是让 perl 将传入数据解码为 UTF-8 编码,并将传出数据重新编码为 UTF-8
仅读取文本并使用相同的编码打印相同的文本不需要对流进行解码和重新编码,因为字节序列已经正确编码
如果输入是 Windows-1255 编码(希伯来语),而输出需要 UTF-8 编码,则数据需要 解码先是一个字符串然后编码到一个UTF-8字节序列
只有当输入和输出需要完全相同的编码,并且不需要将输入作为字符串处理时,才可以省去解码和编码
假设我有(在Bash):
txt="На берегу пустынных волн
Стоял он, дум великих полн,
И вдаль глядел."
如果我将其通过管道传递给 Perl,我可以毫无问题地打印:
$ echo "$txt" | perl -lnE 'say "$_"'
На берегу пустынных волн
Стоял он, дум великих полн,
И вдаль глядел.
但我对本文中的各种正则表达式有疑问。假设我添加新的 Fancy Word Boundaries:
$ echo "$txt" | perl -lnE 'while (/\b{wb}(.+?)\b{wb}/g) { print "\"\"" }'
"–"
"ù"
"–"
"∞"
" "
"–"
"±"
"–µ—"
"Ä"
...
# junk characters...
单词边界不起作用,输入的字符被更改。
(如果我将正则表达式更改为 /\b{wb}(.+)\b{wb}/g
,输出与第一个相同。(.+)
占用整行。)
我可以通过添加 -CASD 命令行开关来解决这些问题,并且花哨的单词边界按设计工作:
$ echo "$txt" | perl -CSAD -lnE 'while (/\b{wb}(.+?)\b{wb}/g) { print "\"\"" }'
"На"
" "
"берегу"
" "
"пустынных"
" "
"волн"
"Стоял"
" "
"он"
","
" "
"дум"
" "
"великих"
" "
"полн"
","
"И"
" "
"вдаль"
" "
"глядел"
"."
问题: perlrun 中的 -CASD
开关似乎暗示启用的 unicode 功能是针对 stdin
和 stdout
输入流。没有提到任何会改变正则表达式的内部差异。由于在第一种情况下我可以读取和打印 unicode,为什么添加 -CASD
会更改正则表达式?
$ perl -v
This is perl 5, version 28, subversion 0 (v5.28.0) built for darwin-thread-multi-2level
在第一种情况下,您不是在读取和打印 unicode,而是在读取和打印 UTF-8。对于 Perl,这些字符串由字节(八位字节)组成,而不是字符,因此它可以在多字节序列的中间找到单词边界。有关详细信息,请参阅 perlunicode。
Since I can read and print unicode in the first case, why does adding
-CASD
change the regex?
该命令行选项只是让 perl 将传入数据解码为 UTF-8 编码,并将传出数据重新编码为 UTF-8
仅读取文本并使用相同的编码打印相同的文本不需要对流进行解码和重新编码,因为字节序列已经正确编码
如果输入是 Windows-1255 编码(希伯来语),而输出需要 UTF-8 编码,则数据需要 解码先是一个字符串然后编码到一个UTF-8字节序列
只有当输入和输出需要完全相同的编码,并且不需要将输入作为字符串处理时,才可以省去解码和编码