有没有可能在sed中指定非捕获组?
如果是的话,怎么样?
圆括号可以用于分组替代。 例如:
sed 's/a\(bc\|de\)f/X/'
用“X”代替“abcf” 或 “adef”,但是括号也被捕获。 没有一个设施在sed
做这样的分组没有也夺取。 如果你有一个复杂的正则表达式,可以做替代分组和捕获,你只需要小心地选择正确的捕获组。
也许你可以多说一些你正在努力完成的事情(你对非捕获组的需求是什么)以及为什么你想避免捕获组。
编辑:
有一种类型的非捕获括号( (?:pattern)
)是Perl兼容正则表达式 (PCRE)的一部分。 它们在sed
不受支持(但在使用grep -P
)。
我假设你说的backrefence语法是括号( )
而不是括号[ ]
默认情况下, sed
将逐字解释( )
而不是试图从它们中引出后退。 你需要把它们转义出来,使它们像\( \)
一样特殊。只有当你使用GNU sed -r
选项时,才会转义转义。 用sed -r
,非转义( )
会产生反向引用,转义\( \)
将被视为文字。 示例如下:
sed
$ echo "foo(###)bar" | sed 's/foo(.*)bar/@@@@/' @@@@ $ echo "foo(###)bar" | sed 's/foo(.*)bar/\1/' sed: -e expression #1, char 16: invalid reference \1 on `s' command's RHS -bash: echo: write error: Broken pipe $ echo "foo(###)bar" | sed 's/foo\(.*\)bar/\1/' (###)
sed -r
$ echo "foo(###)bar" | sed -r 's/foo(.*)bar/@@@@/' @@@@ $ echo "foo(###)bar" | sed -r 's/foo(.*)bar/\1/' (###) $ echo "foo(###)bar" | sed -r 's/foo\(.*\)bar/\1/' sed: -e expression #1, char 18: invalid reference \1 on `s' command's RHS -bash: echo: write error: Broken pipe
来自评论:
只有组的非捕获括号( )
所以你可以使用像间隔{n,m}
东西{n,m}
而不创建反向引用\1
不存在。 首先,间隔不是POSIX sed的区别,你必须使用GNU -r
扩展来启用它们。 只要启用-r
任何分组括号也将被捕获以供反向引用使用。 例子:
$ echo "123.456.789" | sed -r 's/([0-9]{3}\.){2}/###/' ###789 $ echo "123.456.789" | sed -r 's/([0-9]{3}\.){2}/###\1/' ###456.789
答案是,在写作时,你不能 – sed不支持它。 Sed支持BRE和ERE,但不支持PCRE。
(注 – 一个答案指出,BRE也被称为POSIX sed,而ERE是通过sed -r的GNU扩展,剩下的是PCRE不被sed支持)。
Perl将工作,为Windows或Linux
这里的例子
https://superuser.com/questions/416419/perl-for-matching-with-regular-expressions-in-terminal
虽然Windows有一个程序,可以在命令行上进行搜索和替换,并支持PCRE。 这就是所谓的rxrepl。 这当然不是sed,但它会搜索并替换PCRE支持。
C:\blah\rxrepl>echo abc | rxrepl -s "(a)(b)(c)" -r "\1" a C:\blah\rxrepl>echo abc | rxrepl -s "(a)(b)(c)" -r "\3" c C:\blah\rxrepl>echo abc | rxrepl -s "(a)(b)(?:c)" -r "\3" Invalid match group requested. C:\blah\rxrepl>echo abc | rxrepl -s "(a)(?:b)(c)" -r "\2" c C:\blah\rxrepl>
作者(不是我),在这里提到他的程序在一个答案https://superuser.com/questions/339118/regex-replace-from-command-line
它有一个非常好的语法。
标准的东西是perl,或者几乎任何人们使用的其他编程语言。