替换模式中的十六进制变量

时间:2011-02-25 15:01:53

标签: regex perl

我收到的文件已经完整,格式错误的UTF-8代码,如<0308>等。我可以识别它们,但我想用实际的utf-8字母替换它们,最好是用正则表达式。我已经尝试了几十个像这样的正则表达式:

s/<[0-9a-fA-F]{2,4}/\x{$1}/g
s/<[0-9a-fA-F]{2,4}/\N{U+$1}/g

依此类推,但每次它都告诉我$不是有效的十六进制字符(我完全赞同)。它不应该只取我$1中的数字并把它放在那里吗?或者Perl真的希望我只使用固定值\x{..}\N{U+..}吗?如果是这样,我必须手工编写每个可能的十六进制值的转换 - 不是很有用。

3 个答案:

答案 0 :(得分:3)

首先,您需要使用括号来捕获正则表达式中的内容;否则$1将无法设置为任何内容。

带有eval的

chr + hex可以解决这个问题:

s/ <
   ([0-9a-fA-F]{2,4})     # parentheses to set $1
   > 
 / 
   chr(hex($1)) 
 /gex;        

答案 1 :(得分:1)

您可能需要使用eval开关。试试/\x{$1}/eg/"\x{$1}"/eg

答案 2 :(得分:1)

您使用的是什么版本的perl?这似乎对我来说在5.10.1上很好:

$ perl -E '$foo = "<0308>"; $foo =~ s/<[0-9a-fA-F]{2,4}/\N{U+$1}/g; say $foo'
Wide character in print at -e line 1.
�>

(使用\x{$1}时,似乎没有任何内容替换数字,但我仍然没有收到错误消息。)