Как я могу вывести строку в Perl, чтобы увидеть, есть ли какие-либо различия символов? - PullRequest
2 голосов
/ 16 марта 2012

У меня иногда возникали проблемы со слегка различающимися строками, в некоторых случаях utf8 :: all меняло поведение, поэтому я предполагаю, что тонкие различия - это юникод.Я хотел бы записать строки таким образом, чтобы различия были для меня визуальными.Какие у меня есть варианты для этого?

Ответы [ 4 ]

5 голосов
/ 16 марта 2012

Я рекомендую функцию Dump в модуле Devel::Peek в ядре Perl :

$ perl -MDevel::Peek -e 'Dump "abc"'
SV = PV(0x10441500) at 0x10491680
  REFCNT = 1
  FLAGS = (PADTMP,POK,READONLY,pPOK)
  PV = 0x10442224 "abc"\0
  CUR = 3
  LEN = 4

$ perl -MDevel::Peek -e 'Dump "\x{FEFF}abc"'
SV = PV(0x10441050) at 0x10443be0
  REFCNT = 1
  FLAGS = (PADTMP,POK,READONLY,pPOK,UTF8)
  PV = 0x10449bc0 "\357\273\277abc"\0 [UTF8 "\x{feff}abc"]
  CUR = 6
  LEN = 8

(Вы видите, как FLAGS содержит UTF8 во втором примере из-за широкого символа, но не в первом?)

4 голосов
/ 16 марта 2012

В большинстве случаев подойдет Data :: Dumper с Useqq.

use utf8;
use Data::Dumper;
local $Data::Dumper::Useqq = 1;
print(Dumper("foo–bar"));
print(Dumper("foo-bar"));

Выход:

$VAR1 = "foo\x{2013}bar";
$VAR1 = "foo-bar";

Если вам нужны внутренние детали (например, флаг UTF8), используйте Devel :: Peek .

use utf8;
use Devel::Peek;
Dump("foo–bar");
Dump("foo-bar");

Выход:

SV = PV(0x328ccc) at 0x1d6a0c4
  REFCNT = 1
  FLAGS = (PADTMP,POK,READONLY,pPOK,UTF8)
  PV = 0x1d6d52c "foo\342\200\223bar"\0 [UTF8 "foo\x{2013}bar"]
  CUR = 9
  LEN = 12
SV = PV(0x328dcc) at 0x32b594
  REFCNT = 1
  FLAGS = (PADTMP,POK,READONLY,pPOK)
  PV = 0x1d6d50c "foo-bar"\0
  CUR = 7
  LEN = 12
2 голосов
/ 16 марта 2012

Вы пробовали Test :: LongString ?Несмотря на то, что это действительно тестовый модуль, он удобен для того, чтобы показать вам, где происходят различия в строке.Он фокусируется на разных частях вместо того, чтобы показывать вам всю строку, и делает \x{} экранированием для спец.просто чтобы увидеть интересный крайний случай.

1 голос
/ 16 марта 2012

Все, что вам нужно для вывода любой строки:

printf "U+%v04X\n", $string;

Вы можете использовать это для форматирования строки:

($print_string = $string) =~ s/([^\x20-\x7E])/sprintf "\\x{%x}", $1/ge;

или даже

use charnames ();
($print_string = $string) =~ s/([^\x20-\x7E])/sprintf "\\N{%s}", charnames::viacode(ord $1)/ge;
* 1009Я понятия не имею, почему в wolrd вы бы использовали обманчиво названный utf8::all.Это не основной модуль, и вы, похоже, испытываете какие-то проблемы со знанием того, что он на самом деле делает.Если бы вы явно использовали отдельные основные части, которые входят в него, возможно, вы бы лучше все поняли.
...