【问题标题】:Determine if perl scalar originally had one backslash or two确定 perl 标量最初是否有一个或两个反斜杠
【发布时间】:2018-03-21 02:21:15
【问题描述】:

我有从网络服务获得的数据。数据中包含 \\ 是有效的。数据中包含单个 \ 也是有效的。考虑以下对我的 perl 程序的有效数据输入。我不确定如何确定哪些数据最初具有单个 \ 与双 \\。

$ cat data.pl
my $data ='=01=00=00=00=DF=FC=D3Y\=03';
my $data2='=01=00=00=00=DF=FC=D3Y\\=03';
print $data;

请注意,上面代码中 $data 和 $data2 的唯一区别是 $data2 有一个额外的反斜杠。我也不想逃避反斜杠。反斜杠只是此数据流中的有效数据。两者都正常,并且发生在我的数据中。

调试会话:

$ perl -d data.pl

Loading DB routines from perl5db.pl version 1.37
Editor support available.

Enter h or 'h h' for help, or 'man perldebug' for more help.

main::(data.pl:1):      my $data='=01=00=00=00=DF=FC=D3Y\=03';
  DB<1> n
main::(data.pl:2):      my $data2='=01=00=00=00=DF=FC=D3Y\\=03';
  DB<1> x $data
0  '=01=00=00=00=DF=FC=D3Y\\=03'
  DB<2> p $data
=01=00=00=00=DF=FC=D3Y\=03
  DB<3> l
2==>    my $data2='=01=00=00=00=DF=FC=D3Y\\=03';
3:      print $data;
  DB<3> n
main::(data.pl:3):      print $data;
  DB<3> x $data2
0  '=01=00=00=00=DF=FC=D3Y\\=03'
  DB<4> p $data2
=01=00=00=00=DF=FC=D3Y\=03

因此,即使我的输入不同,perl 仍将它们视为相同的数据,因为 \\ 是标量中的单个反斜杠,\ 也是如此。在赋值语句之后,对我来说似乎结束了。无论数据是否有 \\ 或 \,我都丢失了。

似乎 perlio 层在某种程度上通过在反斜杠变为标量之前转义来处理这个问题?对于进入我的程序的数据,我不确定在哪里正确转义 \。

数据从 HTTP 服务通过 LWP::UserAgent 流向一些 perl 类,最终出现在我的程序中。有没有办法在我的数据中处理这个 \\ vs \ 在它达到标量后?

编辑

经过 ikegami 的进一步研究和输入,我意识到这个问题现在很愚蠢,我对在 perl 中如何发生反斜杠转义感到困惑。任何接受输入的东西都会转义反斜杠,以便可以在 perl 中正确表示。在我的情况下,我在数据路径上丢失了一些对我来说并不明显的反斜杠。

$ perl -d data.pl

Loading DB routines from perl5db.pl version 1.37
Editor support available.

Enter h or 'h h' for help, or 'man perldebug' for more help.

main::(data.pl:5):      my $data='{ "data": "=01=00=00=00=DF=FC=D3Y\\\\=03" }';
  DB<1> n
main::(data.pl:6):      my $decoded = decode_json($data);
  DB<2> x $decoded
0  HASH(0x175fcf8)
   'data' => '=01=00=00=00=DF=FC=D3Y\\=03'

就我而言,我必须通过 json_decode 重新转义反斜杠。

鉴于最初的问题很愚蠢,而且我们现在处于非常具体的领域,我想结束这个问题。

谢谢。

【问题讨论】:

标签: perl perl-io


【解决方案1】:

您似乎认为my $data1 = '=01=00=00=00=DF=FC=D3Y\\=03';'=01=00=00=00=DF=FC=D3Y\\=03' 放在标量中,但这是完全错误的。

字符串文字(即一段代码)'=01=00=00=00=DF=FC=D3Y\\=03' 计算为字符串 =01=00=00=00=DF=FC=D3Y\=03。赋值将该字符串放在标量中。

同样,字符串文字 '=01=00=00=00=DF=FC=D3Y\=03' 的计算结果为字符串 =01=00=00=00=DF=FC=D3Y\=03。赋值将该字符串放在标量中。

同样,&lt;$fh&gt; 的计算结果为字符串 =01=00=00=00=DF=FC=D3Y\=03(当从包含 =01=00=00=00=DF=FC=D3Y\=03 的文件中读取时)。赋值将该字符串放在标量中。

无法判断这些代码中的哪一段产生了字符串。


因此,即使我的输入不同,perl 仍将它们视为相同的数据,因为 \\ 是标量中的单个反斜杠,\ 也是如此。

这没有任何意义。您的示例中没有输入,Perl 没有做任何“考虑”。你只需要两段等价的代码。


数据从 HTTP 服务通过 LWP::UserAgent 流向一些 perl 类,最终出现在我的程序中。有没有办法在我的数据中处理这个 \\ vs \ 在它达到标量后?

LWP::UserAgent 将提供服务器返回的内容。它不会执行您所描述的那种转换。

控制台 1:

$ nc -l 8888 <<'.'
HTTP/1.1 200 OK
Content-Type: text/plain

=01=00=00=00=DF=FC=D3Y\=03
=01=00=00=00=DF=FC=D3Y\\=03
.

控制台 2:

$ perl -MLWP::UserAgent -e'print LWP::UserAgent->new->get("http://localhost:8888")->content'
=01=00=00=00=DF=FC=D3Y\=03
=01=00=00=00=DF=FC=D3Y\\=03

【讨论】:

  • 感谢 ikegami,我在输入问题时才意识到这一点。鉴于我通过 LWP::UserAgent simple_request 获取数据,有没有办法保存数据,比如从标准输入读取数据?如果您将 $data2 的内容保存到文件中,将其转换为 perl 并从标准输入中读取,那么一切都很好。双反斜杠将被转义为四个反斜杠...
  • LWP::UserAgent 不执行任何此类翻译。
  • @callyalater,多么讽刺。谢谢。
  • 谢谢,看看 HTTP::Message::content,它确实有四个反斜杠来表示内容中的两个反斜杠。否则,当您打印它时,它只会打印一个反斜杠。我编辑了原始问题以包括我的愚蠢 - 谢谢
猜你喜欢
  • 2013-05-09
  • 1970-01-01
  • 1970-01-01
  • 2013-11-10
  • 1970-01-01
  • 1970-01-01
  • 2012-04-25
  • 1970-01-01
相关资源
最近更新 更多