Модераторы: korob2001, ginnie

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема с кодировками. Регулярные выражения. UTF-8. 
:(
    Опции темы
antananarivu
Дата 25.6.2010, 16:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 25.6.2010

Репутация: нет
Всего: нет



Недавно работаю в Perl.
Возникла проблема, не знаю, как подступиться.

С помощью Perl обрабатываю строку вида "=?koi8-r?B?7sHLzMHEzsHRIzU2mjc3NV/u5evz9Ozh6u4ueGxz?=" она находится в $arrayt[$xx].

Код

($b,$s) = split(/\?B\?/,$arrayt[$xx]); #отрубаем служебную информацию вида =?koi8-r?B?
my $indt = index $b,"=?";
substr($b,0,$indt) = ""; #убираем =?
($st,$rest) = split(/\?=/,$s); #отрубаем окончание строки ?=
$encoded_attname = decode_base64($st); # получаем результат
 $conv = Text::Iconv->new($b, "UTF8");
 $encoded_attname=$conv->convert($encoded_attname); # преобразование в UTF8


В результате в  $encoded_attname получаем строку следующего вида: "Накладная#56 775_НЕКСТЛАЙН.xls"

А теперь мне необходимо избавится в строке от всех символов кроме букв, цифр, знаков препинания и пробела и я пишу регулярное выражение:
Код

$encoded_attname =~ s/[^\ A-Za-z0-9\а\б\в\г\д\е\ё\ж\з\и\й\к\л\м\н\о\п\р\с\т\у\ф\х\ц\ч\ш\щ\ъ\ы\ь\э\ю\я\А\Б\В\Г\Д\Е\Ё\Ж\З\И\Й\К\Л\М\Н\О\П\Р\С\Т\У\Ф\Х\Ч\Ц\Ш\Щ\Ъ\Ы\Ь\Э\Ю\Я\.\,\;\:\(\)\*\&\^\%\$\#\@\!\+\=\_\-\?\№]//g;


В результате, почемуто получаем строку такого вида: "Накладная#56�775_НЕКСТЛАЙН.xls".

То есть по какой-то неведомой мне причине появляется некорректно отображаемый символ. Природу которого я не могу понять. Из-за него не получается ни корректно передать строку, не склеить ее с другой подстрокой. 
И собственно 2 вопроса: почему так происходит? Кто нибудь сталкивался с таким?
И второй подвопрос: почему в регулярном выражении не работают корректно [А-Яа-я] Когда я попытался употребить их в таком виде получалась вообще какая-то каша. Половину букв удалялась, половина оставалась.

Если это важно в программе использую 
use bytes;

Заранее спасибо.



PM MAIL   Вверх
arto
Дата 25.6.2010, 20:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

Репутация: 38
Всего: 40



# perl -MData::Dumper -MMIME::Words=:all -le 'print Dumper decode_mimewords ($ARGV[0])' "=?koi8-r?B?7sHLzMHEzsHRIzU2mjc3NV/u5evz9Ozh6u4ueGxz?="
$VAR1 = [
          'Накладная#56 775_НЕКСТЛАЙН.xls',
          'koi8-r'
        ];
#
PM MAIL ICQ   Вверх
antananarivu
Дата 26.6.2010, 08:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 25.6.2010

Репутация: нет
Всего: нет



А можно поподробнее?
Я не вижу, где здесь происходит удаление всех символов, кроме букв, цифр, знаков препинания и пробела. 
PM MAIL   Вверх
arto
Дата 26.6.2010, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

Репутация: 38
Всего: 40



perldoc MIME::Words
PM MAIL ICQ   Вверх
antananarivu
Дата 28.6.2010, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 25.6.2010

Репутация: нет
Всего: нет



Спасибо. Использовал. Все получилось. Но проблема не исчезла. 
Пример.
Строка  ($sp) - "По документу Снятие заказа № 10 146 от 07.06.2010 19:35:19 сняты следующие  позиции....  ". Явным видом в utf-8.

Код

my $sp = decode_mimewords($subject);
my $charset = Lingua::DetectCharset::Detect($sp);
$sp = Convert::Cyrillic::cstocs($charset, 'UTF8', $sp);


Если вставить строку в WORD видно, что между 10 и 146 есть неразравный пробел. При попытке вот такого кода:
Код

$encoded_attname =~ s/[^\ A-Za-z0-9\а\б\в\г\д\е\ё\ж\з\и\й\к\л\м\н\о\п\р\с\т\у\ф\х\ц\ч\ш\щ\ъ\ы\ь\э\ю\я\А\Б\В\Г\Д\Е\Ё\Ж\З\И\Й\К\Л\М\Н\О\П\Р\С\Т\У\Ф\Х\Ч\Ц\Ш\Щ\Ъ\Ы\Ь\Э\Ю\Я\.\,\;\:\(\)\*\&\^\%\$\#\@\!\+\=\_\-\?\№]//g;

Строка перестает восприниматься корректно. Не конкатенируется, не выводится на экран.
Очень нужна помощь.


Более общий вопрос. Мне нужно строку (в ютф-8), корректно очистить от всех символов кроме букв (латинских русских, цифр, пробела и знаков . , ; : ( ) * & ^ % $ # @ ! + = _ - ? №

Это сообщение отредактировал(а) antananarivu - 28.6.2010, 12:25
PM MAIL   Вверх
arto
Дата 28.6.2010, 12:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

Репутация: 38
Всего: 40



для utf8 смотреть классы символов.
perldoc perlunicode etc.
PM MAIL ICQ   Вверх
antananarivu
Дата 28.6.2010, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 25.6.2010

Репутация: нет
Всего: нет



Я понимаю, что напрашиваюсь на грубость. Но в том то и дело что с английским у меня очень плохо. читал. много непонятных вещей. жаль тратить неделю а то  больше на все тонкости, поэтому и обращаюсь к спецам. ведь в общем-то нужна всего 1 конкретная задача.
строку текста в ютэфной кодировке избавить от всех символов, кроме приведенных выше. 1 строка кода. 
заранее спасибо.
PM MAIL   Вверх
arto
Дата 28.6.2010, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

Репутация: 38
Всего: 40



дайте закодированную строку.
PM MAIL ICQ   Вверх
antananarivu
Дата 28.6.2010, 17:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 25.6.2010

Репутация: нет
Всего: нет



Строка($sp) - "=?utf-8?B?0J/QviDQtNC+0LrRg9C80LXQvdGC0YMg0KHQvdGP0YLQuNC1INC30LA=?=
    =?utf-8?B?0LrQsNC30LAg4oSWIDEwwqAxMjUg0L7RgiAwNy4wNi4yMDEwIDE3OjEyOjIwINGB?=
    =?utf-8?B?0L3Rj9GC0Ysg0YHQu9C10LTRg9GO0YnQuNC1ICDQv9C+0LfQuNGG0LjQuC4uLi4=?=
    =?utf-8?B?ICA=?=
"

После 

Код

my $sp = decode_mimewords($subject);
my $charset = Lingua::DetectCharset::Detect($sp);
$sp = Convert::Cyrillic::cstocs($charset, 'UTF8', $sp);


Получаем строку: 

"По документу Снятие заказа № 10 125 от 07.06.2010 17:12:20 сняты следующие  позиции....  
"

Во избежании нахождения в строке всяких управляющих символов, возврата каретки, конца строки и т.д. пытаюсь сделать отчистку строки от всех символов не нужных мне:

Код

$sp=~ s/[^\ A-Za-z0-9\а\б\в\г\д\е\ё\ж\з\и\й\к\л\м\н\о\п\р\с\т\у\ф\х\ц\ч\ш\щ\ъ\ы\ь\э\ю\я\А\Б\В\Г\Д\Е\Ё\Ж\З\И\Й\К\Л\М\Н\О\П\Р\С\Т\У\Ф\Х\Ч\Ц\Ш\Щ\Ъ\Ы\Ь\Э\Ю\Я\.\,\;\:\(\)\*\&\^\%\$\#\@\!\+\=\_\-\№\?]//g;


После чего $sp не конкатенируется, на экран не выводится. То есть продолжать корректно работать со строкой становится невозможно!
Если же вывести строку в файл то между "№ 10"  и "125" видны некий нечитаемый символ (квадратик). Если же строку "По документу Снятие заказа № 10 125 от 07.06.2010 17:12:20 сняты следующие  позиции.... " скопипастить в Word то на этом самом месте мы увидим символ неразравного пробела. Не знаю важно это или нет, говорю как понимаю ситуацию. 

Ну и собствено вопрос, почему регулярное выражение некорректно работает. 

Это сообщение отредактировал(а) antananarivu - 28.6.2010, 17:41
PM MAIL   Вверх
ginnie
Дата 28.6.2010, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



antananarivu, возможно, проблема в use bytes. Попробуйте use Devel::Peek; и Dump($sp) до и после удаления лишних символов. Кстати, попробуйте еще 
Код

{
    no bytes;
    $sp=~ s/[^\ A-Za-z0-9\а\б\в\г\д\е\ё\ж\з\и\й\к\л\м\н\о\п\р\с\т\у\ф\х\ц\ч\ш\щ\ъ\ы\ь\э\ю\я\А\Б\В\Г\Д\Е\Ё\Ж\З\И\Й\К\Л\М\Н\О\П\Р\С\Т\У\Ф\Х\Ч\Ц\Ш\Щ\Ъ\Ы\Ь\Э\Ю\Я\.\,\;\:\(\)\*\&\^\%\$\#\@\!\+\=\_\-\№\?]//g;
}  



--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
krypt3r
Дата 29.6.2010, 06:34 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 9.6.2009

Репутация: 2
Всего: 16



use bytes уберите, в ней проблема. И добавьте use utf8
PM MAIL   Вверх
arto
Дата 29.6.2010, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

Репутация: 38
Всего: 40



[^ \p{S}\p{L}\p{N}\p{P}]+ ?
PM MAIL ICQ   Вверх
antananarivu
Дата 29.6.2010, 11:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 25.6.2010

Репутация: нет
Всего: нет



делал 
no bytes - тогда убивает и русские буквы тоже. 
use utf-8 или use Devel::Peek - кривой символ остается, строка не выводится на экран. 

Код

$spasss=~ s/[^ \p{S}\p{L}\p{N}\p{P}]+ ?//g; 


тот же результат - некий кривой символ остается. 

Это сообщение отредактировал(а) antananarivu - 29.6.2010, 11:37
PM MAIL   Вверх
antananarivu
Дата 29.6.2010, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 25.6.2010

Репутация: нет
Всего: нет



Может быть я вообще не верно формулирую проблему. 
после того как я отчистил переменную $sp
я делаю следующее:
Код

my $tt2 = "select dbmail_properties.mytest('insert into dbmail_properties.log(namen,fromn,date,subject,kolvo,files,result,muid) values (''".$supplier."'',''".$from."'',''".$date."'',''".$sp."'',''".$nooatt."'',''".$filestr."'',''".$result."'',''".$muid."'');') as val;";
my $rv2 = spi_exec_query($tt2);
my $nname2 = $rv2->{rows}[0]->{val};


если я не отчищаю переменную $sp все корректно отрабатывает - если отчищаю строка $tt2 не выводится на печать и insert не срабатывает.



Это сообщение отредактировал(а) antananarivu - 29.6.2010, 11:48
PM MAIL   Вверх
ginnie
Дата 29.6.2010, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



Цитата(antananarivu @  29.6.2010,  11:32 Найти цитируемый пост)
no bytes - тогда убивает и русские буквы тоже.

А русские символы в регулярном выражении в скрипте у Вас в какой кодировке?

Цитата(antananarivu @  29.6.2010,  11:32 Найти цитируемый пост)
use Devel::Peek - кривой символ остается, строка не выводится на экран

Что выводит Dump($sp)?


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0645 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.