Bash 正则表达式匹配"0xffffffc0006e0584 is in some_function (/path/to/my/file.c:93)."



在我正在编写的 Bash 脚本中,我需要捕获这一行中的/path/to/my/file.c93

0xffffffc0006e0584 is in some_function (/path/to/my/file.c:93).
0xffffffc0006e0584 is in another_function(char *arg1, int arg2)  (/path/to/my/other_file.c:94).

在 regex101.com 的帮助下,我设法创建了这个Perl正则表达式:

^(?:S+s){1,5}((S+):(d+))

但我听说 Bash 不懂d?:,所以我想出了这个:

^([:alpha:]+[:space:]){1,5}(([:alpha:]+):([0-9]+))

但是当我尝试一下时:

line1="0xffffffc0006e0584 is in some_function (/path/to/my/file.c:93)."
regex="^([:alpha:]+[:space:]){1,5}(([:alpha:]+):([0-9]+))"
[[ $line1 =~ $regex ]]
echo ${BASH_REMATCH[0]}

我没有得到任何匹配。我做错了什么?如何编写与 Bash 兼容的正则表达式来执行此操作?

你是对的,Bash 使用 POSIX ERE 并且不支持速记字符类d也不支持非捕获组。在这篇文章中查看更多 POSIX ERE/BRE 中不支持的正则表达式功能。

.*((.+):([0-9]+))

甚至(如果您需要获取字符串中的第一个(...)子字符串(:

(([^()]+):([0-9]+))

  • .*- 任何 0+ 个字符,尽可能多的(可以省略,只有在有其他(...)子字符串时才需要,你只需要抓取最后一个(
  • (-(
  • (.+)- 第 1 组 (${BASH_REMATCH[1]}(: 任意 1+ 字符 尽可能多
  • :- 冒号
  • ([0-9]+)- 第 2 组 (${BASH_REMATCH[2]}(: 1+ 位数字
  • )- 一个)字符。

请参阅Bash演示(或此演示(:

test='0xffffffc0006e0584 is in some_function (/path/to/my/file.c:93).'
reg='.*((.+):([0-9]+))'
# reg='(([^()]+):([0-9]+))' # This also works for the current scenario
if [[ $test =~ $reg ]]; then
echo ${BASH_REMATCH[1]};
echo ${BASH_REMATCH[2]};
fi

输出:

/path/to/my/file.c
93

在第一种模式中,您使用与非空格字符匹配的S+。这是一个广泛的匹配,并且也将匹配例如/在第二种模式中未考虑。

模式以[:alpha:]开头,但第一个字符是 0。您可以改用[:alnum:]。由于重复也应该与可以添加_相匹配。

请注意,对捕获组使用量词时,该组将捕获迭代的最后一个值。因此,当使用{1,5}时,您仅将该量词用于重复。它的价值将是some_function

您可以使用:

^([[:alnum:]_]+[[:space:]]){1,5}(((/[[:alpha:]]+)+.[[:alpha:]]):([[:digit:]]+)).$

正则表达式演示 |砰演示

您的代码可能如下所示

line1="0xffffffc0006e0584 is in some_function (/path/to/my/file.c:93)."
regex="^([[:alnum:]_]+[[:space:]]){1,5}(((/[[:alpha:]]+)+.[[:alpha:]]):([[:digit:]]+)).$"
[[ $line1 =~ $regex ]]
echo ${BASH_REMATCH[2]}
echo ${BASH_REMATCH[4]}

结果

/path/to/my/file.c
93

或者使用S的更短的版本,值在第 2 组和第 3 组中

^([[:alnum:]_]+[[:space:]]){1,5}((S+.[[:alpha:]]):([[:digit:]]+)).$

解释

  • ^字符串开头
  • ([[:alnum:]_]+[[:space:]]){1,5}重复第 1 组中捕获的内容 1-5 次
  • (匹配(
  • (S+.[[:alpha:]])捕获组 2匹配 1+ 非空格字符、.和字母字符
  • :比赛:
  • ([[:digit:]]+)捕获组 3匹配 1+ 数字
  • ).比赛).
  • $字符串结尾

有关括号表达式,请参阅此页面

正则表达式演示

相关内容

最新更新