所以我已经做了一些关于这个问题的研究,但是我没有find完美的解决scheme。 例如,我有一个variables内的string。
var="a1b1c2"
现在我想要做的只是匹配任何数字后跟一个“a”,但我只希望它返回“a”之后的数字为了匹配它的规则,如
'a\d'
因为我只需要这个数字,所以我尝试了
'a(\d)'
也许它确实捕捉到了某处,但是我不知道在哪里,这里的输出仍然是“a1”
我也尝试了一个非捕获组来忽略输出中的“a”,但在perl regex中没有效果:
'(?:a)\d'
作为参考,这是我的terminal中的完整命令:
[root@host ~]# var="a1b1c2" [root@host ~]# echo $var |grep -oP "a(\d)" a1 <--output
也许这也可能没有-P(一些非Perl的正则expression式格式),我感谢每一个答案:)
编辑:使用
\K
并不是真正的解决scheme,因为我不一定需要比赛的最后一部分。
编辑2:我需要能够得到比赛的任何部分,例如:
[root@host ~]# var="a1b1c2" [root@host ~]# echo $var |grep -oP "(a)\d" a1 <--output but the wanted output in this case would be "a"
编辑3:问题几乎解决使用“后视断言”,如:
(?<=a)\d
将不会返回字母“a”,只有后面的数字,但它需要一个固定的长度,例如它不能被用作:
(?<=\w+)\d
编辑4:到目前为止最好的方法是使用Perl或结合后置断言和\ K的组合,但它似乎仍然有一些限制。 例如:
1234_foo_1234_bar 1234567_foo_123456789_bar 1_foo_12345_bar if "foo" and "bar" are place-holders for words that don't always have the same length, there is no way to match all above examples while output "foobar", since the number between them doesn't have a fixed length, while it can't be done with \K since we need "foo"
任何进一步的build议仍然赞赏:)
经过一些测试后,我发现,在后视断言内部的模式需要固定的长度(类似
(?<=\w+)something
不会工作,有什么建议吗?
正如我以前发布和删除我的答案,因为你说它不符合你的需要:
大多数情况下,通过使用\K
可以避免可变长度的向后看 。 这将重置报告匹配的起始点,并且不再包含任何以前消耗的字符。 ( 抛弃与之相配的所有东西 )
使用\K
和一个倒序之间的关键区别是,倒序不允许使用量词:你正在寻找的长度必须是固定的 。 但是\K
可以放在任何模式的任何地方,所以你可以使用任何量词。
正如你在下面的例子中看到的,在lookbheind中使用量词是行不通的。
echo 'foosomething' | grep -Po '(?<=\w+)something' #=> grep: lookbehind assertion is not fixed length
所以你可以这样做:
echo 'foosomething' | grep -Po '\w+\Ksomething' #=> something
为了只在两种模式之间获得一个子字符串,你可以添加积极的Lookahead到混合中。
echo 'foosomethingbar' | grep -Po 'foo\K.*?(?=bar)' #=> something
或者使用了固定的Lookbehind和Lookahead。
echo 'foosomethingbar' | grep -Po '(?<=foo).*?(?=bar)' #=> something
模式(?<=a)\d
使用后退断言来仅打印字母“a”后面的数字。 这适用于GNU grep -Po
, ack -o
和pcregrep -o
。 断言是零宽度,所以它不包括在比赛中。
您可以直接使用Perl,通过%ENV
散列来访问环境变量:
perl -lwe 'print $ENV{var} =~ /a(\d+)/;'
它只会在括号内打印捕获。