繁体   English   中英

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

[英]Using an external regex library from AWK

我的问题的灵感来自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代码进行接口(指向文档的指针就可以了)。

对于nawk ,答案是:并非不修改源代码。

两个问题是:

  • 正则表达式是语言( ~// )以及定义的语言函数( match()等)的一部分。
  • nawk使用自己的正则表达式代码(在文件bc ),因此与使用一个正则表达式库的程序不同,将另一个库与regcomp() regexec()替代实现一起使用将无济于事。

gawk解决这个问题的一种方法是使用第三个参数扩展match() (您也注意到了gensub() ,但我尝试尽可能避免它。)

gawk还支持可加载扩展 ,这是与PCRE库连接以提供新的“内置”功能(尽管不能替换~或任何内部功能)的一种方式。 该API是新的“ 4.1”扩展方式,以前的版本实现方式大不相同。

最后,一个nawk的方式来实现所需要的替换是:

match($0,/\|[^|]*\|/) {
    do {
        sub(/\|[^|]*\|/,"\\abs{" substr($0,RSTART+1,RLENGTH-2) "}",$0)
    } while (match($0,/\|[^|]*\|/))
}
{ print }

这是我使用拆分功能的基于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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM