【问题标题】:Perl, How to find and modify multiple expressions in a single stringPerl,如何在单个字符串中查找和修改多个表达式
【发布时间】:2021-06-04 15:56:25
【问题描述】:

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

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 出现的 X 值中添加一个值(如 6.3)? 我希望新字符串看起来和原来的一样,除了每个 X 值应该增加 6.3。

感谢您对此提供任何指导。

【问题讨论】:

    标签: regex string perl string-substitution


    【解决方案1】:

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

    \K 保留花括号。 /e 标志到s/// 评估替换的替换部分中的表达式。并且g 标志会替换每一次匹配。

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

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

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

    【讨论】:

    • 在没有充分理由的情况下将分隔符 / 替换为 ! 可能是个坏主意,只能起到混淆作用。
    【解决方案2】:

    您也可以只使用\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

    【讨论】:

    • 在没有充分理由的情况下将分隔符 / 替换为 ~ 可能是个坏主意,并且只能起到混淆的作用。
    • 在最近的 perls 中,您需要转义文字左大括号 effectiveperlprogramming.com/2017/04/…
    • 这只是原因之一,包括奇怪的分隔符和没有解释 \K 的作用。但是,无法编译的代码通常是一个充分的理由。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-23
    • 1970-01-01
    • 2014-06-26
    • 1970-01-01
    • 2017-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多