使用AWK的外部正则表达式库

时间:2013-05-27 14:09:56

标签: regex awk regex-greedy

我的问题的灵感来自一个有趣的question有人问http://tex.stackexchange.com我试图提供AWK解决方案。注意这里的AWK意味着NAWK,因为我们知道gawk != awk。我在这里再现一点答案。

原始问题:

我有一个包含大量数学符号的相当大的文档。我一直使用|foo|表示foo的绝对值。我想用|foo|替换\abs{foo}的每个实例,以便我可以通过我定义的abs宏来控制符号。

我的回答:

这篇文章的灵感来自 cmhughes 提出的解决方案。他的帖子是我读过的最有趣的TeX编辑帖子之一。我花了2个小时试图制作nawk解决方案。在那个过程中,我了解到AWK不仅不支持非贪婪的正则表达式,因为它是sed的堂兄,但更糟糕的是AWK正则表达式不能捕获它的组。 一个简单的AWK脚本

#!/usr/bin/awk -f

NR>0{
gsub(/\|([^|]*)\|/,"\\abs{\1}")
print
}

应用于文件

$|abs|$ so on and so fourth
$$|a|+|b|\geq|a+b|$$
who is affraid of wolf $|abs|$
不幸的是,

会产生

$\abs{}$ so on and so fourth
$$\abs{}+\abs{}\geq\abs{}$$
who is affraid of wolf $\abs{}$

上述解决方案的一个明显解决方法是使用 gawk ,而不是

awk '{print gensub(/\|([^|]*)\|/, "\\abs{\\1}", "g", $0)}'

但我想知道是否有办法使用外部的正则表达式库 AWK例如tre。更一般地说,如何与AWK接口 C代码(指向文档的指针就可以了)。

2 个答案:

答案 0 :(得分:1)

nawk的情况下,答案是:不是没有修改源。

其中两个问题是:

  • 正则表达式是语言(~//)的一部分,以及定义的语言函数(match()等。)
  • nawk使用自己的正则表达式代码(在文件b.c中),因此与使用一个正则表达式库的程序不同,使用具有regcomp() {{1}的替代实现的不同库无济于事。

regexec()接近此方法的一种方法是使用third argument扩展gawk。 (你还注意到match(),但我尽可能避免使用它。)

gensub()还支持loadable extensions,这是一种与PCRE库接口以提供新内置"的方法。函数(虽然不能替换gawk或任何内部函数)。这个API是新的" 4.1"做扩展的方式,以前的版本实现了截然不同的。

最后,实现所需替换的一种~方式是:

nawk

答案 1 :(得分:1)

这是我使用分割功能的基于nawk的解决方案:

awk '{
   split($0, arr, "|");
   for (i=1; i<=length(arr); i++) {
      if (i%2)
         printf("%s", arr[i]);
      else
         printf("\\abs{%s}", arr[i]);
   }
   printf("%s", ORS)
}' file

<强>输出:

$\abs{abs}$ so on and so fourth
$$\abs{a}+\abs{b}\geq\abs{a+b}$$
who is affraid of wolf $\abs{abs}$

现场演示:http://ideone.com/lMf2hL