GOOGLE ADS

среда, 13 апреля 2022 г.

Мне нужна помощь в замене русской фразы в Perl Windows

perl -pi -e "s/\x22message\x22\s+\x22Боже, ты посмотри вокруг, что происходит!\x22/\x22message\x22 \x22\x22/g;" "D:\Sav\scripts\chat_wheel.txt"

В этой команде нет ничего плохого, кроме русской текстовой части, которую я хочу удалить.

Боже, ты посмотри вокруг, что происходит!

Когда я запускаю его в cmd.exe, я получаю следующее сообщение об ошибке.

Вложенные квантификаторы в регулярном выражении; отмечен <-- ЗДЕСЬ в m/\x22message\x22\s+\x22??? <-- ЗДЕСЬ?,?????????????????,?????????????!\x22/ at -e строка 1.

Итак, как мне заменить русскую фразу, сохранив команду в виде одной строки? это вообще возможно?

Моя консоль использует CP 65001 (UTF-8). [От Win32::GetConsoleCP()]
Моя активная кодовая страница (ACP) — 1252 [От Win32::GetACP()].
Мой файл закодирован с использованием UTF-8.


Решение проблемы

Бзаменяется на ?. Это связано с тем, что она не поддерживается кодовой страницей консоли, активной кодовой страницей или и тем, и другим.

Кодовая страница вашей консоли установлена ​​на 65001 или UTF-8. Таким образом, ваша консоль может обрабатывать любые символы из набора символов Unicode. Проблема явно не здесь.

Каждый системный вызов Windows, работающий со строками, бывает двух видов. Разновидность "Wide", использующая UTF-16le, и разновидность "A"NSI, использующая активную кодовую страницу. Если бы Perl использовал интерфейс «W» для получения параметров командной строки, у нас не было бы этой проблемы. Вместо этого Perl использует интерфейс «A» для этого (и всех других) системных вызовов.

Это означает, что Perl может принимать только аргументы командной строки, которые могут быть представлены активной кодовой страницей. В вашем случае это 1252, а набор символов cp1252 не включает символы кириллицы.

Предполагая, что мы не хотим заменять каждый символ escape-символом (например, как вы заменили двойные кавычки на "), нам нужно будет сделать что-то другое.

Поскольку мы не можем передать скрипт с помощью аргумента, нам нужно предоставить его с помощью файла, а не с помощью -e. Или через трубу.

echo s/"message"\s+"\KБоже(?=")// | perl -i -p - file.txt

Лучшим, но более радикальным решением было бы изменить ACP Perl на 65001.

Есть вторая проблема.

Perl ожидает, что его исходный код будет закодирован с использованием (8-битного чистого) ASCII, если вы не предоставите use utf8;. Так что пока вы думаете, что проходите s/...Боже...//, на самом деле вы проходите s/...\xD0\x91\xD0\xBE\xD0\xB6\xD0\xB5...//.

Это работает нормально, отчасти потому, что вы также не декодируете свой входной файл. Но это может привести к неожиданностям. Например, "Б" =~ /^[Бж]\z/( "\xD0\x91" =~ /^[\xD0\x91\xD0\xB6]\z/) вернет 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

Комментариев нет:

Отправить комментарий

Laravel Datatable addColumn returns ID of one record only

Я пытаюсь использовать Yajra Datatable для интеграции DataTable на свой веб-сайт. Я смог отобразить таблицу, но столкнулся с проблемой. В по...