run*_*rin 3 sed shell-script regular-expression
echo '123980925sriten34=ienat' | sed -e 's/^.*\?\([1-9][0-9]\{0,2\}\+\)\([%=+-]\).*/ \1 \2 /'
Run Code Online (Sandbox Code Playgroud)
正在给出结果:
4 =
Run Code Online (Sandbox Code Playgroud)
我期待:
34 =
Run Code Online (Sandbox Code Playgroud)
我不明白什么?
(哦,我什至添加了+
和?
以加倍确定,但是{0,2}
没有它们afaik应该是贪婪的。)
G-M*_*ca' 11
正如steeldriver 所说,问题不在于[0-9]{0,2}
它是非贪婪的;问题是它.*?
之前是贪婪的。
sed
支持 BRE 和 ERE,两者都不支持非贪婪匹配。这是 PCRE 的一个特性。例如,以下命令:
$ echo 'aQbQc' | sed 's/.*\?Q/X/'
$ echo 'aQbQc' | sed 's/.*Q/X/'
$ echo 'aQbQc' | sed -r 's/.*?Q/X/'
$ echo 'aQbQc' | sed -r 's/.*Q/X/'
Run Code Online (Sandbox Code Playgroud)
所有输出
$ echo 'aQbQc' | sed 's/.*\?Q/X/'
$ echo 'aQbQc' | sed 's/.*Q/X/'
$ echo 'aQbQc' | sed -r 's/.*?Q/X/'
$ echo 'aQbQc' | sed -r 's/.*Q/X/'
Run Code Online (Sandbox Code Playgroud)
(我不确定为什么它只是忽略了?
.)
请参阅与 SED regex (emulate perl's .*?
) 的非贪婪匹配。
您对要执行的功能的描述很肤浅,但我相信我已经对其进行了逆向工程。您可以通过在找到数字之前不匹配要匹配的数字之前的字符来获得所需的效果 :
$ echo '123980925sriten34=ienat' | sed -e 's/\([1-9][0-9]\{0,2\}\+\)\([%=+-]\).*/! \1 \2 /' -e 's/.*!//'
34 =
Run Code Online (Sandbox Code Playgroud)
用!
任何已知不会出现在输入数据中的字符串替换。如果您没有这样的字符串,但您使用的是 GNU sed,则可以使用换行符:
$ echo '123980925sriten34=ienat' | sed -e 's/\([1-9][0-9]\{0,2\}\+\)\([%=+-]\).*/\n \1 \2 /' -e 's/.*\n//'
34 =
Run Code Online (Sandbox Code Playgroud)
当然,它不能出现在任何一行中。