我的问题的灵感来自一个有趣的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代码(指向文档的指针就可以了)。
答案 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}$