如何匹配$ 123 $,$$,$,而不是123美元与正则表达式?

时间:2016-05-20 23:37:18

标签: regex awk

我有一个非常简单的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

希望我想要的更清楚。

2 个答案:

答案 0 :(得分:2)

您的要求不是很清楚,但这是您想要的吗?

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

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

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

答案 1 :(得分:1)

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

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

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

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

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