Regex 为什么grep比它应该匹配的更多,例如^[\s]*在“中设置断点。*”;“火柴”;在main.c:5“处设置断点1;? patterns.txt script.txt 示例和意外结果
当我运行Regex 为什么grep比它应该匹配的更多,例如^[\s]*在“中设置断点。*”;“火柴”;在main.c:5“处设置断点1;? patterns.txt script.txt 示例和意外结果,regex,bash,grep,Regex,Bash,Grep,当我运行cat“${script.txt}”| grep-f patterns.txt时,结果是: set breakpoint 1 at main.c:5 // WHY DOES THIS MATCH??? set breakpoint 2 at main.c:6 // WHY DOES THIS MATCH??? set breakpoint 3 at main.c:7 // WHY DOES THIS MATCH??? set breakpoint 4 if 这同样适用于: cat "$
cat“${script.txt}”| grep-f patterns.txt
时,结果是:
set breakpoint 1 at main.c:5 // WHY DOES THIS MATCH???
set breakpoint 2 at main.c:6 // WHY DOES THIS MATCH???
set breakpoint 3 at main.c:7 // WHY DOES THIS MATCH???
set breakpoint 4 if
这同样适用于:
cat "${script.txt}" | grep -E '^[\s]*set breakpoint.*if|^[\s]*set breakpoint.*in|^[\s]*set breakpoint.*skip'
这是因为
breakpoint.*in
与前3行中的main
断点相匹配(main
以in
结尾)
您应该在模式中使用端点锚定,如下所示:
cat patterns.txt
^\s*set breakpoint.*if$
^s\s*et breakpoint.*in$
^s\s*et breakpoint.*skip$
否则:
^\s*set breakpoint.*i[fn]$
^s\s*et breakpoint.*skip$
贪婪的表情
^[\s]*在中设置断点。*
你的正则表达式太贪婪了<代码>*通常是个问题,因为它会消耗尽可能多的资源,包括“main”中的“in”。您需要一个不那么贪婪的表达式,以及一个更精确的模式
使用单词边界
使表达式不那么贪婪的一种方法是让模式与\b
原子匹配单词边界。例如,在patterns.txt中的关键字前添加单词边界,如下所示:
^[\s]*set breakpoint.*\bif
^[\s]*set breakpoint.*\bin
^[\s]*set breakpoint.*\bskip
然后,当您运行extended grep时,您将只获得您可能期望的输出:
$ egrep -f pattern.txt script.txt
set breakpoint 4 if
因为此匹配:
^[\s]*在
中设置断点。*因为“main”中的“in”。非常有用的单词边界提示。非常感谢。
^[\s]*set breakpoint.*\bif
^[\s]*set breakpoint.*\bin
^[\s]*set breakpoint.*\bskip
$ egrep -f pattern.txt script.txt
set breakpoint 4 if