awk:用于从字符串中转义正则表达式运算符的函数

6

需要在 awk 脚本中编写一个函数来转义包含正则表达式运算符的字符串。

我找到了这个“丑陋”的解决方案:

function escape_string( str )
{
    gsub( /\\/, "\\\\",  str );
    gsub( /\./, "\\.", str );
    gsub( /\^/, "\\^", str );
    gsub( /\$/, "\\$", str );
    gsub( /\*/, "\\*", str );
    gsub( /\+/, "\\+", str );
    gsub( /\?/, "\\?", str );
    gsub( /\(/, "\\(", str );
    gsub( /\)/, "\\)", str );
    gsub( /\[/, "\\[", str );
    gsub( /\]/, "\\]", str );
    gsub( /\{/, "\\{", str );
    gsub( /\}/, "\\}", str );
    gsub( /\|/, "\\|", str );

    return str;
}

有更好的想法吗?

1
是的,但为什么呢?当人们试图转义正则表达式元字符时,几乎总是因为他们真的想对字符串进行操作而不知道如何进行字符串操作,所以误导地尝试转义所有RE元字符,以便在正则表达式操作中将它们用作字符串(例如match($0,regexp)),而不是在字符串操作中按原样使用它们(例如index($0,string))。 - Ed Morton
@EdMorton 是的,几乎总是,但并非总是。这里的目的是处理包含两列的文本文件,如此一个:http://pastebin.com/U9Sjq53W - 因此,我编写了以下 awk 脚本:http://pastebin.com/AwHmHS74 来处理这类文件。我正在搜索字符串 recording made when T.M.A-1 greeted - http://pastebin.com/sMDQxfcE - 在这种情况下,普通的字符串操作无法解决问题。 - Lacobus
1个回答

7
您可以只使用单个gsub,使用字符类来实现替换,如下所示:

`gsub(/[^\w\s]/, '')`


function escape_string( str ) {
   gsub(/[\\.^$(){}\[\]|*+?]/, "\\\\&", str)
   return str
}

&是对匹配字符串的反向引用,\\\\则用于转义匹配。


4
我认为你可以避免在字符类内使用转义符[, 而如果你将]列在首位,它也不需要转义:gsub(/[][\\.^$(){}|*+?]/, …。但这是否更加清晰是另一个讨论话题。 - Jonathan Leffler
是的,我知道将它们放在第一和第二位置可以避免转义。我只是避免这样做,因为对于一些人来说会感到困惑,因为看起来使用了两个不同的字符类 :) - anubhava

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接