Perl,如何在单个字符串中查找和修改多个表达式

Perl, How to find and modify multiple expressions in a single string

我有一个包含许多行的文件,如下所示:

some text { {{7.718 1072.463} {7.718 1230.985} {15.724 1230.985} {15.724 1198.742} {15.759 1198.742} } {{7.702 1072.489} {7.702 889.858} {13.418 889.858} {13.418 887.367} {13.435 887.367} {13.435 887.376} {7.144 887.376} } } some more text

每一对值都是X和Y坐标。对于文件中的每一行,我想找到每个 X 值并添加一个特定值(比如 6.3)并打印该新行。 X 值将始终跟随 { 而没有任何 space。我可以使用此 while 循环在一行中获取每个 X 值:

 while ($line=~/\{\d+(?:\.\d+)?/g) {
     $oldX=~s/\{//;
 }

但是我如何才能在找到字符串的每 X 次出现的 X 值中添加一个值(如 6.3)? 我希望新字符串看起来像原始字符串,只是每个 X 值都应增加 6.3。

感谢您对此的任何指导。

$line =~ s/\{\K(\d+(?:\.\d+)?)/ + 6.3/ge 将紧跟大括号 ({) 的每个数字替换为增加 6.3 的相同数字。

\K保留大括号。 s////e 标志计算替换的替换部分中的表达式。并且 g 标志替换匹配项的每个匹配项。

如果您需要匹配以点开头的数字(例如 .25),请尝试:

$line =~ s/\{\K(\d+(?:\.\d+)?|\.\d+)/ + 6.3/ge

您可以将正则表达式中的 6.3 替换为包含要添加的数量的变量。

您也可以只使用 \K 并在替换中使用 $& 的完整匹配。

使用\K将重置报告匹配的起点(忘记到目前为止匹配的是什么)

模式匹配:

  • \{ 匹配 {
  • \K 忘记到目前为止匹配的内容
  • \d+ 匹配 1+ 个数字
  • (?:\.\d+)? 可选择匹配一个点和 1+ 个数字

看到一个Regex demo or a Perl demo

例如

$line =~ s/\{\K\d+(?:\.\d+)?/$& + 6.3/ge;
print($line);

输出

{ {{14.018 1072.463} {14.018 1230.985} {22.024 1230.985} {22.024 1198.742} {22.059 1198.742} } {{14.002 1072.489} {14.002 889.858} {19.718 889.858} {19.718 887.367} {19.735 887.367} {19.735 887.376} {13.444 887.376} } }

如果你想在右边断言结束},你可以使用积极的前瞻。

\{\K\d+(?:\.\d+)?(?=[^{}]*})

Regex demo