我正在尝试使用变量替换一行中的一些数字,我遇到了无法解决的问题。以下输入:
111111 133433.000 222222 5225.9860 360 01333.4400 90 10.37 137.71 190410
111111 133434.000 222222 5225.9837 360 01333.4432 90 1.11 138.34 190410
脚本应使用第一行中的1.11
替换第二行中的值10.37
。要处理的文件中有几千行,因此将对行进行评估,并将数字1.11
和10.37
存储在变量中。在这种特殊情况下:
$speed = 1.11
$speed_p = 10.37
$tmpline - current processed line (part of an array)
我用这个替换:
$tmpline =~ s/$speed/$speed_p/eeg;
不幸的是,这个命令忽略了$speed
中的“点”,我得到了第二行的以下结果:
10.3711 133434.000 222222 5225.9837 360 01333.4432 90 10.37 138.34 190410
所以命令用新值替换111
和1.11
,有没有办法改进这个并逃避变量中的“点”?
提前致谢!
亚历
答案 0 :(得分:2)
句点.
是一个正则表达式元字符,它是一个通配符,它匹配除换行符\n
之外的任何内容。您需要做的是禁用句点的元状态,这通常使用反斜杠。但是,在您的情况下,您可以使用\Q ... \E
转义序列:
$tmpline =~ s/\Q$speed\E/$speed_p/g;
另请注意,我删除了双重评估/ee
修饰符。它们不是必需的,使用起来很危险。
但它并不止于此,因为您仍然可以部分匹配1.11
(例如它可以匹配21.1123
)。因此,您需要确保匹配整个数字:
$tmpline =~ s/(?<!\S)\Q$speed\E(?!\S)/$speed_p/g;
我在这里使用双重否定,带有lookbehind和lookahead断言,以确保数字两边的字符不是非空格。双重否定意味着处理边缘情况,因为它认为字符串的开头或结尾是可接受的。如果您确定数字周围始终有空格,则只需使用(?<=\s)
和(?=\s)
即可。