【问题标题】:Using an external regex library from AWK使用来自 AWK 的外部正则表达式库
【发布时间】:2013-05-27 14:09:56
【问题描述】:

我的问题灵感来自一个有趣的question 有人在http://tex.stackexchange.com 提出的问题以及我提供 AWK 解决方案的尝试。注意这里的 AWK 表示 NAWK,因为我们知道 gawk != awk。我在这里复制了一些答案。

原问题:

我有一个包含大量数学符号的相当大的文档。我一直使用|foo| 来表示 foo 的绝对值。我想用\abs{foo} 替换|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)}'

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

【问题讨论】:

  • 简单直接的解决方案似乎是切换到 Perl。 Perl 发行版中有一个脚本a2p,它将 Awk 脚本转换为等效的 Perl 脚本,如果您更喜欢缓慢的学习曲线和近乎即时的结果而不是漂亮、可维护、惯用的 Perl 代码,这可能会有所帮助。

标签: regex awk regex-greedy


【解决方案1】:

以nawk为例,答案是:不修改源代码。

其中两个问题是:

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

gawk 解决此问题的一种方法是使用third argument 扩展match()。 (你注意到还有gensub(),但我尽量避免它。)

gawk 还支持loadable extensions,这将是一种与 PCRE 库接口以提供新的“内置”函数的方式(尽管不能替换 ~ 或任何内部函数)。此 API 是新的“4.1”扩展方式,以前的版本有一个大不相同的实现。

最后,实现所需替换的一种nawk 方法是:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-04
      • 2014-05-08
      • 1970-01-01
      相关资源
      最近更新 更多