在 中,和函数awk
的第一个参数、函数的第二个参数以及 , 的可选第三个参数是扩展正则表达式。sub()
gsub()
match()
split()
这样的参数可以是任意表达式,其计算结果为被解释为正则表达式的字符串,也可以是正则表达式常量。
在 中,为某些正则表达式(语法中的“标记” )awk
编写了正则表达式常量。/RE/
RE
ERE
awk
问题:假设RE
保持不变(一些非变量正则表达式),在调用中使用/RE/
和使用"RE"
(语法STRING
中的“标记” )之间是否存在任何实际差异,例如?或者:是否有任何已知的实现可以在调用上述函数时区分这两种表示正则表达式的方式?awk
sub()
awk
询问的原因是我记得必须修改一些尝试在调用or中awk
用作正则表达式的代码,因为无论出于何种原因,除非我使用 调用该函数,否则手头的实现会做错事情。"RE"
sub()
gsub()
awk
/RE/
不幸的是,这已经是很久以前的事了(2 年多了),所以我不记得细节了,甚至不确定当时我使用的是什么 Unix(可能是 OpenBSD),但从那时起我就一直想问这个问题。
答案1
是的,它们在所有 awk 实现中的不同之处在于使用反斜杠作为转义符。看https://www.gnu.org/software/gawk/manual/gawk.html#Compulated-Regexps对于这个和更多细节:
...请注意,用斜杠括起来的正则表达式常量和用双引号括起来的字符串常量之间存在差异。如果您要使用字符串常量,则必须了解该字符串本质上会被扫描两次:第一次是 awk 读取您的程序,第二次是它匹配 awk 左侧的字符串。具有右侧模式的运算符。对于任何字符串值表达式(例如前面示例中所示的digits_regexp)都是如此,而不仅仅是字符串常量。
如果字符串被扫描两次会有什么区别?答案与转义序列有关,尤其是反斜杠。要将反斜杠添加到字符串内的正则表达式中,您必须键入两个反斜杠。
例如,
/\*/
是文字 的正则表达式常量*
。只需要一个反斜杠。要对字符串执行相同的操作,您必须键入"\\*"
。第一个反斜杠对第二个反斜杠进行转义,以便字符串实际上包含两个字符\
和*
。
因此,在编写正则表达式时,唯一考虑使用"RE"
而不是/RE/
当:
- RE 包含
/
s 并且没有转义符,因此您可以编写,例如,sub("/foo/bar","")
而不只是sub(/\/foo\/bar/,"")
为了简洁,或者 - 您需要字符串分隔符来连接,例如
var=17; sub("stuff" var,"")
否则,请始终在正则表达式周围使用正则表达式分隔符 ( /
),而不是字符串分隔符 ( "
)。