在grep中指定正则表达式匹配重复组为0次或4次(非1-3次)
简洁实现grep匹配重复组0次或4次的正则方案
兄弟,我懂你想要简洁正则的心情!刚好之前也碰过类似需求,给你分两种常见场景给出优雅的实现:
场景1:整个字符串由目标组重复0次或4次组成(纯重复场景)
如果你的需求是整个行仅由目标组重复0次(空行)或4次构成,比如要匹配空行或者abababab(ab重复4次),完全不允许其他字符,那么正则可以写成:
grep -E '^(?:YOUR_GROUP){4}?$' input.txt
解释:
^和$锚定整个行,避免部分匹配(比如不会把ababababc误判为匹配)(?:YOUR_GROUP)用非捕获组包裹你要重复的单元,避免生成额外的捕获分组,提升效率{4}精确匹配该组4次?让前面的4次重复组可选(即要么出现4次,要么完全不出现,对应0次的情况)
举个实际例子,假设目标组是[0-9](单个数字),执行命令:
grep -E '^(?:[0-9]){4}?$' numbers.txt
会匹配空行、1234,但不匹配1、12、123、12345。
场景2:目标组在任意位置,总出现次数为0或4次(允许其他字符)
如果允许行中存在其他字符,但要求目标组总共出现0次或恰好4次,比如匹配abc test def test ghi test jkl test(test出现4次)或者hello world(test出现0次),那么可以用合并逻辑的正则:
grep -E '^(?:(.*YOUR_GROUP){4})|^((?!YOUR_GROUP).)*$' input.txt
解释:
^((?!YOUR_GROUP).)*$:匹配完全不包含目标组的行(0次的情况),通过正向否定预查确保行中没有目标组的任何出现^(?:(.*YOUR_GROUP){4}):匹配包含恰好4次目标组的行,.*允许目标组之间存在任意字符|把两种合法情况合并,只要满足其中一种就会匹配
同样拿test作为目标组举例,执行命令后:
- 匹配:空行、
test test test test、foo test bar test baz test qux test - 不匹配:
test、test test、test test test、test test test test test
这种写法比嵌套多层排除逻辑的正则简洁很多,可读性也更强~
内容的提问来源于stack exchange,提问作者q0987
相关产品推荐
相关产品推荐

