2016-10-30 5 views
1

В Perl'е, я работаю с текстом utf8:как decode_entities в utf8

my $string = 'a 3.9 kΩ resistor and a 5 µF capacitor'; 

Однако, когда я запускаю следующее:

decode_entities('a 3.9 kΩ resistor and a 5 µF capacitor'); 

Я получаю

a 3.9 kΩ resistor and a 5 µF capacitor 

Значок успешно декодирован, но символ µ теперь имеет тарабарщину перед ним.

Как я могу использовать decode_entities, убедившись, что некодированные символы utf-8 (например, µ) не преобразуются в тарабарщину?

ответ

1

Вы используете библиотеку Encode CPAN. Если это правда, вы можете попробовать это ...

my $string = "..."; 
$string = decode_entities(decode('utf-8', $string)); 

Это может показаться нелогичным. Если Perl является собственно UTF-8, зачем вам нужно декодировать строку UTF-8? Это просто еще один способ сообщить Perl, что у вас есть значение UTF-8, которое нужно интерпретировать как изначально UTF-8.

Повреждение, которое вы видите, это когда значение UTF-8 не имеет признанных байтов прав (оно отображается «0xC1 0xAF» при использовании Dumpered, после этого изменения должно отображаться «0x1503» или аналогичное concat'ed bytes).

Существует множество настроек, которые могут повлиять на это в perl. Вышеупомянутое, скорее всего, является правильной комбинацией изменений, которые вам нужны для данных настроек. В противном случае некоторые проблемы (своп-кодировка с декодированием («latin1», ...) и т. Д.) Выше должны решить проблему.

+0

Это сработало для меня, спасибо. Я отвечу, когда смогу, через несколько минут. Как ни странно, когда я теперь запускаю 'url_encode ($ string)' позже в скрипте, теперь я получаю предупреждение «широкий символ». Но я полагаю, что это совершенно новый вопрос. –

+1

@Hello World: Попробуйте url_encode_utf8(). знак равно – HoldOffHunger

2

Это не очень хорошо сформулированный вопрос. Вы не сказали нам, откуда приходит ваша функция decode_entities(), и вы не дали простой пример, который мы могли бы просто запустить, чтобы воспроизвести вашу проблему.

Но я был в состоянии воспроизвести проблему с этим кодом:

#!/usr/bin/perl 

use strict; 
use warnings; 
use 5.010; 

use HTML::Entities; 

say decode_entities('a 3.9 kΩ resistor and a 5 µF capacitor'); 

Проблема здесь состоит в том, что по умолчанию, Perl интерпретирует исходный код (и, следовательно, любые строки, включенные в нее), как ISO -8859-1. Поскольку ваша строка находится в UTF8, вам просто нужно указать Perl интерпретировать исходный код как UTF8, добавив use utf8 к вашему коду.

#!/usr/bin/perl 

use strict; 
use warnings; 
use 5.010; 

use utf8; # Added this line 

use HTML::Entities; 

say decode_entities('a 3.9 kΩ resistor and a 5 µF capacitor'); 

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

Широкий характер, скажет

Это потому, что слой IO Perl ожидает однобайтовые символов по умолчанию, и любой попытке отправить многобайтный персонажу через это рассматривается как потенциальная проблема. Вы можете исправить это, указав Perl, что STDOUT должен принимать символы UTF8. Есть много способов сделать это. Проще всего, вероятно, добавить -CS к линии shebang.

#!/usr/bin/perl -CS 

use strict; 
use warnings; 
use 5.010; 

use utf8; 

use HTML::Entities; 

say decode_entities('a 3.9 kΩ resistor and a 5 µF capacitor'); 

У Perl есть большая поддержка Unicode, но с этим может быть сложно начать работу. Я рекомендую прочитать perlunitut, чтобы узнать, как все это работает.

Смежные вопросы