Perl Regexp tr/// utf8 - как сделать?
2012-Apr-22, Sunday 12:38![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
После не лучшим образом сделанного преобразования html-ек из православной кодировки КОИ8-R в не менее православную ныне UTF-8 (на некоторых страницах мемориального зеркала Свиридова) потребовалось совершить:
perl -p -i.scrback -e 'use utf8; tr/√┘╚╩/—…«»/'
UPD3: Вот так работает. Спасибо коллеге shaplov
tr же строго побайтовый и не работает. Консоль UTF-8
Принимаю помощь зала как:
- правильно
- проще всего
UPD2: Теперь я вполне понимаю, почему perl как массовый язык программирования на вебе ушёл в прошлое, уступив намного более ублюдочному по сути PHP. Проблемы с переходом на UTF-8 оказались непреодолимы для большинства разработчиков. :(
UPD1: про мои ОС и перл:
perl -p -i.scrback -e 'use utf8; tr/√┘╚╩/—…«»/'
UPD3: Вот так работает. Спасибо коллеге shaplov
cat vskon-orig.htm | perl -e '
binmode STDIN, ":utf8";
binmode STDOUT, ":utf8";
use utf8;
while(my $a=<STDIN>) {
$a=~tr/√┘╚╩/—…«»/;
print $a
}' >vskon-result.htm
tr же строго побайтовый и не работает. Консоль UTF-8
Принимаю помощь зала как:
- правильно
- проще всего
UPD2: Теперь я вполне понимаю, почему perl как массовый язык программирования на вебе ушёл в прошлое, уступив намного более ублюдочному по сути PHP. Проблемы с переходом на UTF-8 оказались непреодолимы для большинства разработчиков. :(
UPD1: про мои ОС и перл:
# perl -v This is perl, v5.10.1 (*) built for i386-freebsd-64int Copyright 1987-2009, Larry Wall Perl may be copied only under the terms of either the Artistic License or the GNU General Public License, which may be found in the Perl 5 source kit. Complete documentation for Perl, including FAQ lists, should be found on this system using "man perl" or "perldoc perl". If you have access to the Internet, point your browser at http://www.perl.org/, the Perl Home Page. # uname -a FreeBSD 8.2-RELEASE-p3 FreeBSD 8.2-RELEASE-p3 #0: Tue Sep 27 18:07:27 UTC 2011 root@i386-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC i386 # locale LANG=ru_RU.UTF-8 LC_CTYPE="ru_RU.UTF-8" LC_COLLATE="ru_RU.UTF-8" LC_TIME="ru_RU.UTF-8" LC_NUMERIC="ru_RU.UTF-8" LC_MONETARY="ru_RU.UTF-8" LC_MESSAGES="ru_RU.UTF-8" LC_ALL=ru_RU.UTF-8
no subject
Date: 2012-Apr-22, Sunday 08:48 (UTC)no subject
Date: 2012-Apr-22, Sunday 09:06 (UTC)$text=~ s/√/—/g;
$text=~ s/┘/…/g;
и т.п.
C tr вечно встречаются проблемы с уникодом...
Правда последнюю проблему которую встречал проявлялась в 5.8. и только если процесс пошел в тред.
Но для одно раза проче юзать s/// он точно работает
no subject
Date: 2012-Apr-22, Sunday 09:14 (UTC)no subject
Date: 2012-Apr-22, Sunday 09:15 (UTC)не заменяет.
no subject
Date: 2012-Apr-22, Sunday 09:23 (UTC)no subject
Date: 2012-Apr-22, Sunday 09:29 (UTC)Ругается:
Wide character in print at -e line 1, line 189.
Wide character in print, line 189.
no subject
Date: 2012-Apr-22, Sunday 09:31 (UTC)binmode STDOUT, ":utf8";
ругаться не будет.
no subject
Date: 2012-Apr-22, Sunday 09:32 (UTC)Должон заменять...
no subject
Date: 2012-Apr-22, Sunday 09:32 (UTC)конвенты были организованы под Харьковом (╚Чугункон╩) под Нижним Новгородом
(╚ВОЛК╩, Волжский Конвент), в Питере (Фестиваль Ролевого Костюма) и Самаре
(╚СОК╩, самарский открытый конвент). У суровых реконструкторов, главным
событием стал минский турнир-фестиваль ╚Белый Замок╩, и наконец,
текст программы:
'binmode STDIN, ":utf8"; use utf8; my $a=; $a=~tr/√┘╚╩/—…«»/; print $a'
результат:
конвенты были организованы под Харьковом (╚Чугункон╩) под Нижним Новгородом
событием стал минский турнир-фестиваль «Белый Замок», и наконец,
no subject
Date: 2012-Apr-22, Sunday 09:35 (UTC)no subject
Date: 2012-Apr-22, Sunday 09:39 (UTC)Я не умею однострочники писать :-)
Это как-то компактнее можно выразить....
no subject
Date: 2012-Apr-22, Sunday 09:42 (UTC)no subject
Date: 2012-Apr-22, Sunday 09:51 (UTC)просто в этом комменте (на который ты отвечаешь) случайно вставил старый вариант
no subject
Date: 2012-Apr-22, Sunday 09:50 (UTC)Ну можно не в одну строку:
'
binmode STDOUT, ":utf8";
binmode STDIN, ":utf8";
use utf8;
while (my $x=) { $x=~tr/√┘╚╩/—…«»/; print $x}
'
Всё равно ж херня получается - строки тасуются в выдаче - см. мой коммент ниже.
no subject
Date: 2012-Apr-22, Sunday 09:53 (UTC)Пришли тогда мне файл на n -at- shaplov dot ru чтоли...
no subject
Date: 2012-Apr-22, Sunday 09:54 (UTC)Посмотри что с последовательностью строк в выдаче.
no subject
Date: 2012-Apr-22, Sunday 09:57 (UTC)Поэтому я сначала хотел бы получить оригинальный файл, чтобы через копипаст ничего не терялось, а потом если ты не будешь против, оригинальный шелл (или аналогичный оригинальному). Потому как у меня с порядком строк -- все в порядке...
no subject
Date: 2012-Apr-22, Sunday 10:18 (UTC)результат: http://gfns.net/asw/vskon-result.htm
первая строка оригинала оказалась в конце результата.
в шелле:
cat vskon-orig.htm | perl -p -e '
binmode STDIN, ":utf8";
binmode STDOUT, ":utf8";
use utf8;
while(my $a=<STDIN>) {
$a=~tr/√┘╚╩/—…«»/;
print $a
}' >vskon-result.htm
no subject
Date: 2012-Apr-22, Sunday 10:28 (UTC)no subject
Date: 2012-Apr-22, Sunday 10:31 (UTC)no subject
Date: 2012-Apr-22, Sunday 09:44 (UTC)оригинал:
результат:
^M - это возвраты каретки. :)
no subject
Date: 2012-Apr-22, Sunday 09:50 (UTC)Последний отправленный мной пример считывает весь файл.
У меня с точностью до nbsp; все им конвертнулось...
no subject
Date: 2012-Apr-22, Sunday 09:57 (UTC)no subject
Date: 2012-Apr-22, Sunday 10:13 (UTC)http://gfns.net/asw/vskon-orig.htm
и
http://gfns.net/asw/vskon-result.htm
(это чтобы include virtual не примешивалось)
no subject
Date: 2012-Apr-22, Sunday 09:17 (UTC)Для этого есть хороший модуль Devel::Peek;
если ты это берешь со стандартного вывода, и не предпринимаешь особых усилий чтобы оно стало :utf8, то тогда оно считается байтовым, и замена utf8 символов внутри него не работает.
no subject
Date: 2012-Apr-22, Sunday 09:22 (UTC)преобразования из:
- имеем программу, текст ея в кодировке KOI8-R
- имеем исходные данные в кодировке KOI8-R
- имеем выход в кодировке KOI8-R
в:
- имеем ту же программу, текст ея в кодировке UTF-8
- имеем исходные данные в кодировке UTF-8
- имеем выход в кодировке UTF-8
нет.
есть только извращённые, с переписыванием каждой строки работы с регекспами?
no subject
Date: 2012-Apr-22, Sunday 09:25 (UTC)Правильно работающий пример -- выше. Если речь идет о посимвольной замене уникодных символов приходящих на stdin
no subject
Date: 2012-Apr-22, Sunday 09:36 (UTC)Имеем потерю двух строк и непреобразование части искомых символов.
no subject
Date: 2012-Apr-22, Sunday 09:29 (UTC)Да, каждое открытие файла надо будет явно обозначать как открытие файла с уникодным контентом.
Увы.
no subject
Date: 2012-Apr-22, Sunday 15:55 (UTC)Для ввода-вывода 'use open qw/:utf8/; use open qw/:std :utf8/;'
Твой начальный пример это у меня чинит. Правда, только в файле скрипта, с -e почему-то не работает. Но с -e еще проще, там perl -C можно.
no subject
Date: 2012-Apr-22, Sunday 09:49 (UTC)no subject
Date: 2012-Apr-22, Sunday 10:02 (UTC)1. Именно банальный iconv и превратил кавычки, тире и многоточие в псевдографику, а так как это было только на очень малой доле страниц сайта, я этого долго не замечал.
2. Мысль преобразовать обратно и снова туда, конечно, прекрасна. Однако в том и дело, что нужное мне действие - рутинная задача, тривиально решавшаяся "пока кодировки были однобайтовыми" стандартным способом. Я столкнулся с тем, что теперь, при "православной" кодировке UTF-8, перлом она должна решаться с вывертами.
no subject
Date: 2012-Apr-22, Sunday 11:32 (UTC)no subject
Date: 2012-Apr-22, Sunday 19:31 (UTC)Как админ хостингового сервера я застал массовое программирование на Перле и на PHP
Массового применения питона и Руби не наблюдал.
Из имеющихся у меня (400), а также переезжавших ко мне или от меня (около 300) хостов:
Единичные случаи - Питона. То ли 2, то ли 4 - смотря как считать, по клиентам или по хостам.
4 случая серверной Явы
Ни одного - Руби
no subject
Date: 2012-Apr-23, Monday 04:34 (UTC)no subject
Date: 2012-Apr-23, Monday 05:25 (UTC)в PHP + MySQL перевод с windows-1251 на utf-8 в подавляющем большинстве даже очень ракообразных самописных движков, с которыми я имел дело на серверах, сводился к максимум 4-м действиям:
- перекодировать iconv и перезалить дамп базы, проставив ему в начало set names utf8;
- перекодировать iconv файлы php
- проставить set names utf8 после mysql_connect
- убрать из .htaccess упоминания о кодировках, если были (они там, порой, оставались со времён "русского апача").
Ни одной ситуации вида "перестали работать регекспы" или "эта функция только побайтовая" не наблюдал. Одна ситуация вида "в cgi варианте работаем - в апаче нет" явно по причине перекодированных строк.
no subject
Date: 2012-Apr-23, Monday 14:28 (UTC)no subject
Date: 2012-Apr-23, Monday 14:38 (UTC)no subject
Date: 2012-Apr-23, Monday 16:19 (UTC)no subject
Date: 2012-Apr-22, Sunday 11:38 (UTC)Беда perl'а в том, что на нём неудобно программировать методом cut/paste.
no subject
Date: 2012-Apr-22, Sunday 19:33 (UTC)no subject
Date: 2012-Apr-22, Sunday 22:41 (UTC)Впрочем читать тут.
no subject
Date: 2012-Apr-23, Monday 05:28 (UTC)