假设一个文本字符串my_string
$ my_string="foo bar=1ab baz=222;"
我想提取关键字baz
和分号之间的字母数字字符串。
如何使用正则表达式断言修改以下 grep 代码以排除尾随分号?
$ echo $my_string | grep -oP '(?<='baz=').*'
222;
答案1
除非您要提取的字符串本身可能包含,否则最简单的事情可能是将(匹配任何单个字符);
替换为(匹配除 之外的任何字符).
[^;]
;
$ printf '%s\n' "$my_string" | grep -oP '(?<='baz=')[^;]*'
222
通过grep
链接到 libpcre 7.2 或更高版本,您还可以使用以下形式简化lookbehind \K
:
$ printf '%s\n' "$my_string" | grep -oP 'baz=\K[^;]*'
222
这些将打印字符串中的所有匹配项,并假设匹配文本不包含换行符(因为grep
单独处理每一行输入)。
答案2
也可以轻松搭配sed:
sed -n 's/.*baz=\([^;]*\).*/\1/p' <<< $my_string
222
答案3
Steeldriver 的答案是准确的,但我在前瞻/后瞻方面遇到了困难,为了可读性,我会这样做(使用bash
):
my_string="foo bar=1ab baz=222;"
regex='baz=([0-9]+);'
[[ $my_string =~ $regex ]] &&
echo "${BASH_REMATCH[1]}"
答案4
对于任何 POSIX shell:
baz=
对于第一次出现和最后一次出现之间的文本;
:my_string="foo bar=1ab baz=222;" case $my_string in (*baz=*\;*) result=${my_string#*baz=} result=${result%;*};; (*) result= esac
对于第一次出现 和之后
baz=
的下一次出现之间的文本,替换为上面;
%
%%
为了最后的出现
baz=
,替换#
为##
。