perl正则表达式替换/替换使用带有特殊字符的变量

时间:2012-04-06 13:32:33

标签: regex perl special-characters

好的,我已经检查了以前类似的问题,我一直在玩弄不同的quotemeta变种,但有些东西仍然不对。

我有一行带有单词ID和两个单词 - 第一个是错误的单词,第二个是正确的。 我正在使用正则表达式用正确的单词替换错误的单词。

$line = "ANN20021015_0104_XML_16_21 A$xAS   A$xASA";
@splits = split("\t",$line);
$wrong_word = quotemeta $splits[1];
$right_word = quotemeta $splits[2];
print $right_word."\n";
print $wrong_word."\n";

$line =~ s/$wrong_word\t/$right_word\t/g;

print $line;

我在做什么有什么问题?

修改

问题在于我无法保留完整的单词 - 它们会被特殊字符切断。这段代码非常适用于没有特殊字符的单词。

上面示例我需要的输出是:

ANN20021015_0104_XML_16_21      A$xASA   A$xASA

但我得到的是

ANN20021015_0104_XML_16_21      A   A

由于$字符。

3 个答案:

答案 0 :(得分:3)

ETA:

你得到:

ANN20021015_0104_XML_16_21      A   A

何时需要:

ANN20021015_0104_XML_16_21      A$xASA   A$xASA

我的怀疑如下:

  • 您并不是故意插入变量$xAS$xASA,因为它们未定义,只需将空字符串添加到$line,这在输出中可见。例如。 "A$xAS"已扩展为"A" . undef
  • 您没有使用use warnings,因此您无法获得有关此错误的信息。

<强>解决方案:

使用use strict; use warnings;。总是。他们为你节省了很多时间。

分配时,请使用单引号来避免变量插值:

$line = 'ANN20021015_0104_XML_16_21 A$xAS   A$xASA';

旧答案:

既然你没有说出了什么问题,那就是我最终的猜测。

我可以看到变量$xAS$xASA的可能意外插值,您可以通过转义美元符号或使用$line分配上的单引号来解决这些问题。

您还可以使用join而不是正则表达式构建新字符串,例如:

$line = join "\t", @splits[0,2,2];

答案 1 :(得分:3)

  • 如果您使用过strict,则会告诉您必须声明变量$xAS$xASA
  • 如果您使用过warnings,它会告诉您,您正在连接一个未初始化的变量。

因此常见的警告:“使用严格,使用警告”。

您只需要将字符串放在non-interpolated quotes''q{})或转义 sigil ({ {1}})这样它就不会尝试interpolate它认为是变量的东西。

  • $是引用会破坏你的字符串的引用
  • ""是不会
  • 的引用

课程:使用单引号,除非您想要插值。

答案 2 :(得分:1)

问题不在于你的替代;问题出在您的代码示例的第一行。

$line = "ANN20021015_0104_XML_16_21 A$xAS   A$xASA";

尝试将变量$xAS$xASA插入$line,并且不插入任何内容,因为这些变量为空。使用单引号而不是双引号,以便字符串不进行插值。

如果你打开warnings它会警告你,你正在插入一个未初始化的变量,并且你打开了strict 'vars'它就不会让你使用未声明的{ {1}}和$xAS

最后,您不必$xASA替换的右侧;只有左边。