为什么在单行内的 perl 替换和匹配(m)运算符中使用 utf8 模式不起作用?
Why using utf8 patterns within perl substitute(s) and match(m) operators within one-liners does not work?
我在使用 Perl 的单行代码替换文件中的一些 utf8 文本时发现了这个问题。
我知道 How to handle utf8 on the command line (using Perl or Python)? 上的黑客攻击。他们不适用于这种情况。 OS是linux,locate设置为utf8
# make file to contain pattern
$echo Текст на юникоде>file
$cat file
Текст на юникоде
# also grep finds it
$grep "Текст на юникоде" file
Текст на юникоде
# different perl hacks mentioned at reference question don't work:
$perl -C63 -n -e "print if m{Текст на юникоде}" file
# does not show anything
$perl -Mutf8 -n -e "print if m{Текст на юникоде}" file
# does not show anything
# although it handles parameters correctly
$perl -e 'print "$ARGV[0]\n"' "Текст на юникоде"
Текст на юникоде
# and inside -e options as well
$perl -e 'print "Текст на юникоде\n"'
Текст на юникоде
# when create perl script to find the pattern, it works:
echo "while (<>) {print if m{Текст на юникоде}}">find.pl
$cat find.pl
while (<>) {print if m{Текст на юникоде}}
$perl find.pl file
Текст на юникоде
# and even this strange way it works:
perl -ne '$m="Текст на юникоде";print if m{$m}' file
Текст на юникоде
所以这是我的问题:是否有任何更简单的解决方案来使用 utf8 模式形成 m 和 s 运算符以及 perl 单行代码,为什么简单的方法不起作用?
谢谢!
以防万一:
$uname -a
Linux ubuntu16-pereval 4.4.0-190-generic #220-Ubuntu SMP Fri Aug 28 23:02:15 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
$locale
LANG=en_US.UTF-8
LANGUAGE=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=en_US.UTF-8
perl -C63 -n -e "print if m{Текст на юникоде}" file
-C63
应用各种标志来告诉 Perl 输入和输出文件是 UTF8。
perl -C63 -n -e "print if m{Текст на юникоде}" file
-Mutf8
告诉 Perl 编译器您的源代码是 UTF8。
-C63
影响 Perl 如何查看 file
中的数据。 -Mutf8
影响 Perl 如何查看您的 -e
选项中的代码。为了让 Perl 理解输入文件和源代码都应该被解释为 UTF8,您需要这两个选项。
$ perl -Mutf8 -C63 -n -e "print if m{Текст на юникоде}" file
Текст на юникоде
更新:哦,我应该补充一点,最简单的选项也可以(但出于所有错误的原因!)
$ perl -n -e "print if m{Текст на юникоде}" file
Текст на юникоде
在这种情况下,它起作用是因为 Perl 将输入和源代码解释为由 single-byte Latin-1 字符组成。请不要这样做:-)
我在使用 Perl 的单行代码替换文件中的一些 utf8 文本时发现了这个问题。 我知道 How to handle utf8 on the command line (using Perl or Python)? 上的黑客攻击。他们不适用于这种情况。 OS是linux,locate设置为utf8
# make file to contain pattern
$echo Текст на юникоде>file
$cat file
Текст на юникоде
# also grep finds it
$grep "Текст на юникоде" file
Текст на юникоде
# different perl hacks mentioned at reference question don't work:
$perl -C63 -n -e "print if m{Текст на юникоде}" file
# does not show anything
$perl -Mutf8 -n -e "print if m{Текст на юникоде}" file
# does not show anything
# although it handles parameters correctly
$perl -e 'print "$ARGV[0]\n"' "Текст на юникоде"
Текст на юникоде
# and inside -e options as well
$perl -e 'print "Текст на юникоде\n"'
Текст на юникоде
# when create perl script to find the pattern, it works:
echo "while (<>) {print if m{Текст на юникоде}}">find.pl
$cat find.pl
while (<>) {print if m{Текст на юникоде}}
$perl find.pl file
Текст на юникоде
# and even this strange way it works:
perl -ne '$m="Текст на юникоде";print if m{$m}' file
Текст на юникоде
所以这是我的问题:是否有任何更简单的解决方案来使用 utf8 模式形成 m 和 s 运算符以及 perl 单行代码,为什么简单的方法不起作用?
谢谢!
以防万一:
$uname -a
Linux ubuntu16-pereval 4.4.0-190-generic #220-Ubuntu SMP Fri Aug 28 23:02:15 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
$locale
LANG=en_US.UTF-8
LANGUAGE=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=en_US.UTF-8
perl -C63 -n -e "print if m{Текст на юникоде}" file
-C63
应用各种标志来告诉 Perl 输入和输出文件是 UTF8。
perl -C63 -n -e "print if m{Текст на юникоде}" file
-Mutf8
告诉 Perl 编译器您的源代码是 UTF8。
-C63
影响 Perl 如何查看 file
中的数据。 -Mutf8
影响 Perl 如何查看您的 -e
选项中的代码。为了让 Perl 理解输入文件和源代码都应该被解释为 UTF8,您需要这两个选项。
$ perl -Mutf8 -C63 -n -e "print if m{Текст на юникоде}" file
Текст на юникоде
更新:哦,我应该补充一点,最简单的选项也可以(但出于所有错误的原因!)
$ perl -n -e "print if m{Текст на юникоде}" file
Текст на юникоде
在这种情况下,它起作用是因为 Perl 将输入和源代码解释为由 single-byte Latin-1 字符组成。请不要这样做:-)