【问题标题】:\x not working inside the substitution\x 在替换中不起作用
【发布时间】:2017-02-20 21:16:38
【问题描述】:

我正在尝试解码 unicode 字符。所以我只是在正则表达式替换e中尝试了十六进制转义序列\x{}

use LWP::Simple;
my $k = get("url");

my ($kv) =map{/js_call\(\\"(.+?)\\"\)/} $k;

#now $kv data is https://someurl/call.pl?id=15967737\u0026locale=en-GB\u0026mkhun=ccce

$kv=~s/\\u(.{4})/"\x{$1}"/eg;

我正在尝试替换所有 unicode 字符。

我的预期输出是:

https://someurl/call.pl?id=15967737&locale=en-GB&mkhun=ccce

下面提到的print 语句给出了预期的输出。但是,正则表达式似乎无法正常工作。

print "\x{0026}";

【问题讨论】:

    标签: regex perl unicode


    【解决方案1】:

    如果您启用use warnings,您将看到$1 在反向引用被插值之前被逐字评估。

    $kv =~ s/\\u(.{4})/ sprintf("\"\\x{%s}\"", $1) /eeg;
    

    有点作品,但它非常丑陋。我一直在尝试简化它,但我尝试过的各种想法总是让我回到“非法十六进制数字'$'被忽略”警告。

    【讨论】:

      【解决方案2】:

      这个也可以试试:

      $kv=~s/\\u([[:xdigit:]]{1,5})/chr(eval("0x$1"))/egis;

      谢谢。

      【讨论】:

        【解决方案3】:

        s/\\u(.{4})/"\x{$1}"/e 的问题是反斜杠转义 \x{$1} 在编译时被评估,它给出一个 NULL 字节:

        $ perl -E 'printf "%vX\n", "\x{$1}"'
        0
        

        如果我们转义 x ( s/\\u(.{4})/"\\x{$1}"/ge ) 前面的反斜杠,我们会得到一个带有文字转义序列的字符串,但仍然不是所需的 unicode 字符:

        use feature qw(say);
        $kv = '\u0026';
        $kv =~ s/\\u(.{4})/"\\x{$1}"/ge;
        say $kv; 
        

        现在的输出是:

        \x{0026}
        

        只需稍加修改,您就可以生成"\x{0026}",这是您可以编译和执行以生成所需值的 Perl 代码。为此,您需要参与eval(EXPR)

        $kv =~ s/\\u(.{4})/ my $s = eval(qq{"\\x{$1}"}); die $@ if $@; $s /ge;
        

        这可以缩短为

        $kv =~ s/\\u(.{4})/ qq{"\\x{$1}"} /gee;
        

        但是,更好的解决方案是使用以下方法:

        $kv =~ s/\\u(.{4})/chr hex $1/ge;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-05-02
          • 2018-04-27
          • 2018-03-15
          • 2015-02-21
          • 2013-03-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多