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

问题描述

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

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 值将始终跟在 { 之后,没有任何空格。我可以使用这个 while 循环在一行中获取每个 X 值:

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

但是如何为找到字符串的每个 X 值添加一个值(如 6.3)? 我希望新字符串看起来就像原来的一样,只是每个 X 值都应该增加 6.3。

感谢您对此的任何指导。

解决方法

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

\K 保留花括号。 /es/// 标志对替换的替换部分中的表达式求值。并且 g 标志替换匹配的每个匹配项。

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

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

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

,

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

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

模式匹配:

  • \{ 匹配 {
  • \K 暂时忘记匹配的内容
  • \d+ 匹配 1 个以上的数字
  • (?:\.\d+)? (可选)匹配一个点和 1 个以上的数字

查看 Regex demoPerl 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