如何使用 awk 的 gensub 或替代方案来替换重叠匹配

Foo*_*Foo 3 bash awk

我在用:

$ echo ".a.b.c." | awk '
{
  t=gensub(/.([a-z])./,"[\\1]","g",$1); print t
}'
[a]b[c]
Run Code Online (Sandbox Code Playgroud)

我想结束[a][b][c]。我怎样才能开始gensub处理重叠的比赛?

如果这是不可能的,我怎样才能实现这一目标?

Sté*_*las 6

你可以这样做:

perl -pe 's{\.([a-z](?:\.[a-z])*)\.}{"[$1]" =~ s/\./][/gr}ge'
Run Code Online (Sandbox Code Playgroud)

即把所有的 替换为.x.y.z.[x.y.z]其中.s 替换为][

同样的awk,避免使用gensub()gawk 特有的并且使用起来很麻烦,因为它不会让你知道它何时成功:

awk '
  {
    while(match($0, /(\.[abcdefghijklmnopqrstuvwxyz])+\./)) {
      s = substr($0, RSTART + 1, RLENGTH - 2)
      gsub(/\./, "][", s)
      $0 = substr($0, 1, RSTART - 1) "["s"]" substr($0, RSTART+RLENGTH)
    }
    print
  }'
Run Code Online (Sandbox Code Playgroud)

如果使用当前版本mawk(尚未本地化)或最新版本,gawk或者如果在 C 语言环境中,则可以替换abcdefghijklmnopqrstuvwxyza-z. 除了这些条件之外,不能保证它们是等效的。特别是,在某些语言环境中,[a-z]每个 POSIX 旨在匹配一系列整理元素,而不是字符甚至可以匹配多个字符,例如ddzs在匈牙利语言环境中。

无论如何,请注意,要匹配正则表达式中的文字点,您需要\.[.].否则,它本身就是一个匹配任何单个字符的正则表达式运算符。