我需要帮助替换 Perl 中的俄语短语 Windows
I need help replacing a russian phrase in Perl Windows
perl -pi -e "s/\x22message\x22\s+\x22Боже, ты посмотри вокруг, что происходит!\x22/\x22message\x22 \x22\x22/g;" "D:\Sav\scripts\chat_wheel.txt"
除了我要删除的俄语文本部分外,此命令没有任何问题
Боже, ты посмотри вокруг, что происходит!
当我 运行 它在 cmd.exe 时,我收到以下错误消息。
Nested quantifiers in regex; marked by <-- HERE in
m/\x22message\x22\s+\x22??? <-- HERE ?, ?? ???????? ??????, ???
??????????!\x22/ at -e line 1.
那么,如何在将命令保持为一行的同时替换俄语短语?有可能吗?
我的控制台使用 CP 65001 (UTF-8)。 [来自 Win32::GetConsoleCP()
]
我的活动代码页 (ACP) 是 1252 [来自 Win32::GetACP()
]。
我的文件使用 UTF-8 编码。
Б
正在被 ?
取代。这是因为它不受控制台代码页、活动代码页或两者的支持。
您的控制台代码页设置为 65001 或 UTF-8。因此,您的控制台可以处理 Unicode 字符集中的任何字符。问题显然不在这里。
每个 Windows 处理字符串的系统调用有两种。使用 UTF-16le 的“W”ide 变体,以及使用活动代码页的“A”NSI 变体。如果 Perl 使用“W”接口获取其命令行参数,我们就不会遇到这个问题。 Perl 对此(以及所有其他)系统调用使用“A”接口。
这意味着 Perl 只能接受 command-line 个可以由活动代码页表示的参数。在您的情况下,它是 1252,并且 cp1252 字符集不包含任何西里尔字符。
假设我们不想用转义替换每个字符(就像您如何将 double-quotes 替换为 "
),我们将需要做一些不同的事情。
由于我们无法使用参数传递脚本,因此我们需要使用文件而不是使用 -e
来提供ide它。或者通过管道。
echo s/"message"\s+"\KБоже(?=")// | perl -i -p - file.txt
更好但更彻底的解决方案是 change Perl's ACP 到 65001。
还有第二个问题。
Perl 期望其源代码使用(8 位干净的)ASCII 编码,除非您提供 ide use utf8;
。因此,虽然您认为自己超过了 s/...Боже...//
,但实际上您已经超过了 s/...\xD0\x91\xD0\xBE\xD0\xB6\xD0\xB5...//
。
结果没问题,部分原因是您也没有解码输入文件。但它可能会带来意外。例如,"Б" =~ /^[Бж]\z/
("\xD0\x91" =~ /^[\xD0\x91\xD0\xB6]\z/
) 会 return false!
要在脚本中解决这个问题,您需要使用
use utf8; # Source code is using UTF-8.
use open ':std', ':encoding(UTF-8)'; # Terminal provides & expects UTF-8.
-C
会在这里做。
echo s/"message"\s+"\KБоже(?=")// | perl -i -C -p - file.txt
perl -pi -e "s/\x22message\x22\s+\x22Боже, ты посмотри вокруг, что происходит!\x22/\x22message\x22 \x22\x22/g;" "D:\Sav\scripts\chat_wheel.txt"
除了我要删除的俄语文本部分外,此命令没有任何问题
Боже, ты посмотри вокруг, что происходит!
当我 运行 它在 cmd.exe 时,我收到以下错误消息。
Nested quantifiers in regex; marked by <-- HERE in m/\x22message\x22\s+\x22??? <-- HERE ?, ?? ???????? ??????, ??? ??????????!\x22/ at -e line 1.
那么,如何在将命令保持为一行的同时替换俄语短语?有可能吗?
我的控制台使用 CP 65001 (UTF-8)。 [来自 Win32::GetConsoleCP()
]
我的活动代码页 (ACP) 是 1252 [来自 Win32::GetACP()
]。
我的文件使用 UTF-8 编码。
Б
正在被 ?
取代。这是因为它不受控制台代码页、活动代码页或两者的支持。
您的控制台代码页设置为 65001 或 UTF-8。因此,您的控制台可以处理 Unicode 字符集中的任何字符。问题显然不在这里。
每个 Windows 处理字符串的系统调用有两种。使用 UTF-16le 的“W”ide 变体,以及使用活动代码页的“A”NSI 变体。如果 Perl 使用“W”接口获取其命令行参数,我们就不会遇到这个问题。 Perl 对此(以及所有其他)系统调用使用“A”接口。
这意味着 Perl 只能接受 command-line 个可以由活动代码页表示的参数。在您的情况下,它是 1252,并且 cp1252 字符集不包含任何西里尔字符。
假设我们不想用转义替换每个字符(就像您如何将 double-quotes 替换为 "
),我们将需要做一些不同的事情。
由于我们无法使用参数传递脚本,因此我们需要使用文件而不是使用 -e
来提供ide它。或者通过管道。
echo s/"message"\s+"\KБоже(?=")// | perl -i -p - file.txt
更好但更彻底的解决方案是 change Perl's ACP 到 65001。
还有第二个问题。
Perl 期望其源代码使用(8 位干净的)ASCII 编码,除非您提供 ide use utf8;
。因此,虽然您认为自己超过了 s/...Боже...//
,但实际上您已经超过了 s/...\xD0\x91\xD0\xBE\xD0\xB6\xD0\xB5...//
。
结果没问题,部分原因是您也没有解码输入文件。但它可能会带来意外。例如,"Б" =~ /^[Бж]\z/
("\xD0\x91" =~ /^[\xD0\x91\xD0\xB6]\z/
) 会 return false!
要在脚本中解决这个问题,您需要使用
use utf8; # Source code is using UTF-8.
use open ':std', ':encoding(UTF-8)'; # Terminal provides & expects UTF-8.
-C
会在这里做。
echo s/"message"\s+"\KБоже(?=")// | perl -i -C -p - file.txt