如何在awk regex中引用一个regex组?

Jus*_*ner 11 awk regular-expression

如何在 awk regex 中引用正则表达式组?例如,如果我有一个正则表达式组(\w),我以后如何在同一个正则表达式中引用它(\w)\1?awk 支持这个功能吗?下面的例子不起作用。

# In this example, I want to change aa to aaa and cc to ccc.
echo ab aa cc de mn | gawk '{print gensub(/(\w)\1/, "\\1\\1\\1", "g")}'
# The result is: ab aa cc de mn
# The expected result is: ab aaa ccc de mn
Run Code Online (Sandbox Code Playgroud)

Sté*_*las 14

的 busybox 实现awk是我所知道的唯一一个支持反向引用的实现。它碰巧也支持gawk'sgensub()\w扩展:

sub()gsub(),你必须使用"..."的,而不是/.../和使用\\1的,而不是\1(在标准awk"\1"是值1(性格^A),并/\1/要求该字符,同时匹配的"\\1"是(也就是)联合国(DER)的POSIX规定;还要注意POSIX ERE 没有反向引用,这是 BRE 具有但不是 ERE 的一项功能)。

$ echo ab aa cc de mn | busybox awk '{print gensub("(\\w)\\1", "\\1\\1\\1", "g")}'
ab aaa ccc de mn
Run Code Online (Sandbox Code Playgroud)

请注意,尽管 busyboxawk不是国际化的,但它的\w唯一匹配a-zA-Z0-9_项与语言环境无关(与 相同[[:alnum:]])并且不支持多字节字符:

$ echo ee éé | busybox awk '{print gensub("(\\w)\\1", "\\1\\1\\1", "g")}'
eee éé
Run Code Online (Sandbox Code Playgroud)

使用标准实用程序,您通常会sed用于该工作:

sed 's/\([[:alnum:]_]\)\1/&\1/g'
Run Code Online (Sandbox Code Playgroud)

sed正则表达式是支持反向引用的基本正则表达式。一些sed实现支持使用or扩展正则表达式,并且 POSIX 将在标准的下一个主要版本中指定,但仍然没有反向引用(尽管捕获组 for的替换会)。GNU 和busybox确实支持反向引用,但FreeBSD不支持。-r-E-Essed-Esed

  • @cas,仅适用于 UTF-8 语言环境。你应该使用:`perl -Mopen=locale -pe 's/(\w)\1/$1$1$1/g'` (2认同)

cas*_*cas 13

$ echo ab aa cc de mn | perl -pe 's/(\w)\1/\1\1\1/g'
ab aaa ccc de mn
Run Code Online (Sandbox Code Playgroud)

有时你不得不承认有些事情 awk 不能做,但 perl 可以。

从好的方面来说,如果您足够熟练awk地使用gensub并想要进行反向引用,那么您应该会发现perl自己是一个轻而易举的人。也就是说,如果你会写 awk,你就可以写 perl。

  • 也许我应该看看 perl。感谢您的回答和建议! (3认同)
  • 我强烈建议您这样做,特别是如果您发现自己在想“我希望 awk 可以做这个 sed 事情”,反之亦然。perl 的功能远不止这些,但是非常简单的管道过滤器样式用法就像 sed、awk、cut、grep、tr、sh 等的组合。在类固醇。 (3认同)

mos*_*svy 7

这可能超出了问题的范围,但awk不支持反向引用的原因是因为awk一直使用真正的正则表达式,即可以通过有限状态机无需递归实现的表达式。这样的实现不能支持任何形式的反向引用(它可以支持捕获组,尽管实现不是直接的)。

awk我所看到的想法是,您应该将正则表达式用于直接的时间和内存有界匹配,而它的类似 C 的图灵完备语言则用于处理比这更复杂的任何事情。

相反,来自 perl / pcre / etc 的“regexp”已经发展成为一种紧凑的语法来描述只能由图灵机实现的递归匹配过程。这具有安全隐患:不受信任的用户可以输入此类正则表达式的任何搜索框等都是拒绝服务攻击的邀请;没有人知道这样一场比赛需要多少时间或记忆,只有粗略的措施,比如对其进行严格的任意限制和禁止顽固的猪。

这是Russ Cox 的一篇旧文章,其中更深入地描述了所有这些。