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