Regex Bash正则表达式匹配“0xFFFFC0006E0584在某个函数中(/path/to/my/file.c:93)。”

Regex Bash正则表达式匹配“0xFFFFC0006E0584在某个函数中(/path/to/my/file.c:93)。”,regex,bash,Regex,Bash,在我正在编写的Bash脚本中,我需要捕获此行中的/path/to/my/file.c和93: 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正则表达式: ^(?:

在我正在编写的Bash脚本中,我需要捕获此行中的/path/to/my/file.c和93:

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兼容的正则表达式来实现这一点?

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

模式以[:alpha:]开头,但第一个字符是0。您可以改为使用[:alnum:]。因为重复也应该匹配,所以也可以添加

请注意,当为捕获组使用量词时,该组捕获迭代的最后一个值。所以当使用{1,5}时,你只在重复时使用这个量词。它的值将是某种函数

您可以使用:

^([[: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:][u]+[:space:][{1,5}重复第1组中捕获的内容1-5次 \匹配 \S+\.[:alpha:]捕获组2匹配1+非空白字符。还有一个字母 :匹配: [[:数字:]+捕获组3匹配1+数字 \\. 火柴 $字符串结尾 参见本页关于


没错,Bash使用POSIX ERE,不支持\d速记字符类,也不支持非捕获组。看

使用

或者即使你需要抓住第一个。。。字符串中的子字符串:

\(([^()]+):([0-9]+)\)
细节

.*-任何0+个字符(尽可能多)都可以省略,只有在有其他字符时才需要。。。子字符串,您只需要获取最后一个 \-一个字符 .+-Group 1${BASH_REMATCH[1]}:尽可能多的任意1+字符 :-冒号 [0-9]+-2组${BASH_重新匹配[2]}:1+位数 \-一个字符。 见或:

输出:

/path/to/my/file.c
93

像这样试试吧^[:alnum:][unum:][+[:space:][1,5}\/[:alpha:][+\[:alpha:][:digit:][]+\.$值在第2组和第4组echo${BASH_REMATCH[2]}和echo${BASH_REMATCH[4]}谢谢@Thefourthbird,为什么必须对文件名和扩展名进行分区?这是因为在一个组中重复/和1+alpha字符以匹配类似路径的结构。组的最后一次重复将保持匹配,在本例中为/file
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