通过 grep 正则表达式断言提取字符串

通过 grep 正则表达式断言提取字符串

假设一个文本字符串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=,替换###

相关内容