【问题标题】:How to match $123$, $$, $, but not $123 with regex?如何用正则表达式匹配 $123$、$$、$,但不是 $123?
【发布时间】:2016-05-20 23:37:18
【问题描述】:

我有一个相当简单的 awk 脚本,它需要查看一个字符串并替换任何双美元符号 ($$)、双美元符号与中间数字 ($123$) 和单美元符号 ($)和_。我用 gsub 在两个正则表达式中很容易地完成了它,但我觉得我应该能够用一个正则表达式来完成它,它让我发疯,我无法锁定它。可能对时间或速度无关紧要,但在这一点上,我只需要知道我是否正确关于有更浓缩的方式还是我疯了。

这是我目前拥有的:

gsub (/\$[0-9]*\$/, "_", $1);
gsub (/\$/, "_", $1);

我认为使用

将其设置在一行中没有问题
gsub (/\$[0-9]*\$*/, "_", $1);

但我没有意识到在单个美元符号后跟数字 ($123) 的情况下,我只想替换美元符号而不是数字。所以我需要匹配 1 个美元符号,然后是 0 个或更多数字,如果数字匹配,则需要 1 个美元符号,如果没有数字,则需要 0 到 1 个(或更多,无关紧要)美元符号。

编辑:抱歉,我没有给出更好的输入和期望输出示例。

输入:

foo$bar$$foofoo$353$foobar$123
abc$123$xyz$$123abc$def$$hij$456$klm

输出:

foo_bar_foofoo_foobar_123
abc_xyz_123abc_def_hij_klm

希望我想要什么更清楚。

【问题讨论】:

  • \$([0-9]+\$|\$?)
  • edit 您的问题包括简洁、可测试的样本输入和预期输出。尤其重要的是要包含脚本可能难以正确处理的情况,并在输入和输出中包含要匹配的字符串周围的上下文(如果您不删除它)。
  • 您要这样做吗? 1. 在由一个或多个美元符号组成的分隔符上拆分字符串。 2. 从拆分列表中删除由数字组成的元素。 3. 使用下划线作为分隔符连接其余部分。

标签: regex awk


【解决方案1】:

您的要求不是很明确,但这是您想要的吗?

$ awk '{sub(/\$([0-9]*\$)*/,"_")}1' file
_ - match
_ - match
_ - match
_123 - don't match

IDK 如果以上是预期的输出,或者没有给出我假设是您发布的示例输入:

$ cat file
$ - match
$$ - match
$124$ - match
$123 - don't match

【讨论】:

    【解决方案2】:

    我不认为awk 在它的正则表达式中支持负前瞻,所以你需要使用程序逻辑。

    gsub(/\$[0-9]*\$/, "_", $1);
    if ($1 ~ /\$/ && $1 !~ /\$[0-9]/) gsub(/\$/, "_", $1);
    

    但是,这不适用于$foo $123 之类的字符串,因为$123 会阻止进行任何替换。

    如果您使用的是 GNU Awk,则可以使用其 gensub 函数在替换中使用捕获组。然后您可以匹配$ 后跟不是数字的内容,并将非数字复制到替换中。

    gensub(/\$([^0-9]|$)/, "_\\1", "g", $1);
    

    【讨论】:

      猜你喜欢
      • 2018-05-18
      • 1970-01-01
      • 2018-10-31
      • 2018-09-26
      • 2013-07-16
      • 2011-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多