我需要帮助替换 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