在我正在编写的Bash脚本中,我需要捕获这一行中的navigationItem
和/path/to/my/file.c
:
93
在regex101.com的帮助下,我设法创建了此Perl正则表达式:
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).
但是我听说Bash不了解^(?:\S+\s){1,5}\((\S+):(\d+)\)
或\d
,所以我想到了:
?:
但是当我尝试时:
^([:alpha:]+[:space:]){1,5}\(([:alpha:]+):([0-9]+)\)
我没有任何比赛。我究竟做错了什么?如何编写与Bash兼容的正则表达式来做到这一点?
答案 0 :(得分:2)
在第一个模式中,您使用myDictionary.Where(d => d.Key >= from && d.Key <= to).Select(d => d.Value).ToArray();
匹配一个非空格字符。这是一个广泛匹配,并且还将匹配例如\S+
,这在第二种模式中没有考虑。
模式以/
开头,但第一个字符为0。您可以改用[:alpha:]
。由于重复也应匹配[: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
的版本短一点,值在组2和3中
\S
说明
^([[:alnum:]_]+[[:space:]]){1,5}\((\S+\.[[:alpha:]]):([[:digit:]]+)\)\.$
字符串的开头^
重复1-5次在第1组中捕获的内容([[:alnum:]_]+[[:space:]]){1,5}
匹配\(
(
捕获 group 2 匹配1个以上非空格字符,(\S+\.[[:alpha:]])
和一个字母字符.
匹配:
:
捕获第3组匹配1个以上的数字([[:digit:]]+)
匹配\)\.
).
字符串结尾关于bracket expressions的页面见此
答案 1 :(得分:2)
是的,Bash使用POSIX ERE,不支持\d
速记字符类,也不支持非捕获组。参见more regex features unsupported in POSIX ERE/BRE in this post。
使用
.*\((.+):([0-9]+)\)
或者甚至(如果您需要获取字符串中的第一个(...)
子字符串):
\(([^()]+):([0-9]+)\)
详细信息
.*
-尽可能多的0个字符(可以省略,只有在还有其他(...)
个子字符串并且您只需要获取 last 的情况下才需要一个)\(
-一个(
字符(.+)
-组1(${BASH_REMATCH[1]}
):尽可能多的1个字符以上:
-冒号([0-9]+)
-第2组(${BASH_REMATCH[2]}
):1位以上数字\)
-一个)
字符。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