Pau*_*ce. 29
Parentheses can be used for grouping alternatives. For example:
sed 's/a\(bc\|de\)f/X/'
Run Code Online (Sandbox Code Playgroud)
says to replace "abcf" or "adef" with "X", but the parentheses also capture. There is not a facility in sed
to do such grouping without also capturing. If you have a complex regex that does both alternative grouping and capturing, you will simply have to be careful in selecting the correct capture group in your replacement.
Perhaps you could say more about what it is you're trying to accomplish (what your need for non-capturing groups is) and why you want to avoid capture groups.
Edit:
There is a type of non-capturing brackets ((?:pattern)
) that are part of Perl-Compatible Regular Expressions (PCRE). They are not supported in sed
(but are when using grep -P
).
bar*_*lop 11
答案是,在写作时,你不能 - 不支持它.Sed支持BRE和ERE,但不支持PCRE.
(注意 - 一个答案指出BRE也称为POSIX sed,ERE是通过sed -r的GNU扩展.点仍然是sed不支持PCRE.)
对于Windows或Linux,Perl可以工作
这里的例子
https://superuser.com/questions/416419/perl-for-matching-with-regular-expressions-in-terminal
例如来自windows中的cygwin
$ echo -e 'abcd' | perl -0777 -pe 's/(a)(?:b)(c)(d)/\1/s'
a
$ echo -e 'abcd' | perl -0777 -pe 's/(a)(?:b)(c)(d)/\2/s'
c
Run Code Online (Sandbox Code Playgroud)
虽然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>
Run Code Online (Sandbox Code Playgroud)
作者(不是我)在这里的答案中提到了他的程序https://superuser.com/questions/339118/regex-replace-from-command-line
它有一个非常好的语法.
要使用的标准内容是perl,或者几乎任何其他人们使用的编程语言.
我假设你说的是反向引用语法,它是括号( )
而不是方括号[ ]
默认情况下,sed
将按( )
字面意思进行解释,而不尝试对其进行反向引用。您需要对它们进行转义以使它们变得特殊,就像\( \)
只有当您使用 GNUsed -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/'
(###)
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
来自评论:
不存在仅组、非捕获括号( )
,因此您可以使用间隔之类的东西{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
Run Code Online (Sandbox Code Playgroud)