regex - bash 中 grep 对前面有几个相同字符的行的意外行为
问题描述
我正在玩overthewire.org的强盗;达到 10 级需要我在文本文件中查找前面有几个“=”字符(等号)(我将“几个”解释为“两个或更多”)的字符串。
目标行如下所示:
========== passwordhere123
即十个等号、一个空格和一串字母和数字,然后是换行符(不确定是哪种确切类型)。
应排除这些行:
c========== EqualSignDidNotStartLine
= only-one-equal-sign
equalsign=somewhereElse
No equal signs at all
原始数据不包含任何前面有少于十但多于一个 = 的行;文本中有一些 +(加号),但 + 和 = 永远不会在同一行。
强盗服务器运行某种 linux @ 4.18.12 (uname -r)、GNU bash 4.4(来自手册页)和 GNU grep 2.27(来自手册页)。
原始数据包含不可读的部分,因此它首先被输入strings
,只留下人类可读的字符串来处理 grep。
据我所知,grep 的默认正则表达式引擎(BRE,感谢Casimir)与 PCRE 的区别不大。*
仍然是一个量词(匹配前面的模式零次或多次),而不是作为一个独立的模式,意思是“任何东西,零次或多次”。这让我对下面 grep 的行为感到困惑。
编辑:根据此图表,“+”需要\+
在 BRE 中转义(即)。但它无济于事。我将制作更多的测试字符串来尝试破译发生了什么。
这是我尝试过的命令:
strings data.txt | grep -P -e ^==+.*
strings data.txt | grep -P -e ^==+.*$ #both PCRE expressions worked correctly
#start BRE
strings data.txt | grep -e ^==.* #includes every line preceded by at least two =; works
strings data.txt | grep -e ^==.*$ #includes every line preceded by at least two =; works
strings data.txt | grep -e ^==+.* #no output; why?
strings data.txt | grep -e ^==+.*$ #no output
strings data.txt | grep -e ^==+* #includes every target line, so works; WHY IS THIS A LEGAL REGEX?
strings data.txt | grep -e ^==+*$ #no output
strings data.txt | grep -e ^==\+.* #no output
strings data.txt | grep -e ^==\+.*$ #no output
strings data.txt | grep -e ^==\+* #includes every target line, so works
strings data.txt | grep -e ^==\+*$ #no output
解决方案
首先,我会担心外壳扩展。根据长期经验,我将正则表达式放在命令行中的“单引号”中,以避免元字符的疯狂。
其次,这个(在BRE下):
^==+*
是完全有效的。它的意思是:
^ anchored at the start of the input
== followed by 2 '=' charaters
+* followed by 0 or more '+' characters
您说“根据我所学到的,grep 的默认正则表达式引擎(BRE,感谢 Casimir)与 PCRE 应该没有太大不同”,我认为这是您的问题。特别是,+
是PRCE 中的元字符,而不是BRE 中的元字符。观察:
echo '==+++++' | grep ^==+*
==+++++
echo '==+++++' | grep -E ^==+*
grep: repetition-operator operand invalid
-E
ongrep
启用扩展的正则表达式。
那么,既然您知道这+
只是+
BRE 下的文字,您能明白为什么所有模式的行为方式都如此吗?
推荐阅读
- ios - 代码未进入数据任务的完成处理程序
- jquery - Opera mobile 中的音频问题
- linux - 使用 dd 创建磁盘映像时“设备上没有剩余空间”
- r - 如何获得 R 中单尾自举 Pearson 相关的置信区间?
- direct3d9 - 如何获取windows HDR切换状态使用码?
- amazon-kinesis - 如何访问 Kinesis 流中的特定记录?
- mysql - 表加密每表文件表空间未加密
- c# - 从给定的 JSON 文件中检索特定属性
- android - Flutter 应用程序崩溃使用 i18n Jetbrains 插件的样板构建具有多语言的 AppBar
- java - ListIterator 或 Iterator 不会在 List 的末尾停止