好的,我已经检查了以前类似的问题,我一直在玩弄不同的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
由于$
字符。
答案 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
替换的右侧;只有左边。