sed正则替换命令匹配逻辑、子表达式差异及前置空格作用咨询
sed正则匹配逻辑说明
测试基础信息
待处理原始文本:
1a fost odata 2un balaur care fura mere de aur
执行的sed命令:
sed 's/\([a-z]*\)\(.*\)\( [a-z]*\)/\1 ... \2/' filename
执行输出:
... 1a fost ... 2un balaur care ... mere ... de
先讲两个核心基础规则,搞懂了就不会看不懂匹配结果:
- 这条sed用的是POSIX基础正则,匹配从左到右扫描,
*代表匹配前面的规则零次或多次,默认是贪婪模式,会尽可能匹配最长的符合要求的内容 s/匹配规则/替换内容/只会替换每行里第一个被规则命中的子串,没被命中的部分原样保留;替换串里的\1/\2/\3对应三个括号分组捕获的内容,没写在替换串里的分组内容会直接丢掉
整条匹配规则拆成三个连续的捕获组,结构是(组1)(组2)(组3):
- 组1:
[a-z]*,匹配零个或多个连续小写字母 - 组2:
.*,匹配零个或多个任意字符 - 组3:
[a-z]*,匹配一个空格,加后面零个或多个连续小写字母
疑问解答
1. 第一个[a-z]*子表达式和最后一个[a-z]*子表达式有什么区别?
两者核心差异是匹配位置和上下文约束完全不同:
- 组1的
[a-z]*在正则最左端,没有任何前置约束,从扫描起点(默认是行首)开始匹配连续小写字母。如果起点位置的字符不是小写字母(比如测试文本前两行开头是数字1、2),它就匹配空内容(毕竟*允许零次匹配);如果行首是连续小写字母,就把这串连续字母全部捕获。 - 组3的
[a-z]*在正则最右端,有强制前置约束:必须紧跟在一个空格后面,捕获的是空格后跟着的连续小写字母。再加上组2的.*是贪婪匹配,组3一定会拿到当前匹配范围内最靠右的、符合「空格+连续小写字母」规则的内容。 - 额外说明:你写的替换串里没有引用
\3,所以组3捕获的所有内容都会在替换时被直接丢弃。
2. 最后一个子表达式的[a-z]前为什么要设置空格?
这个空格是用来给组3划定匹配边界的:强制要求组3捕获的必须是前面带空格的小写字母串。你的测试文本是用空格分隔的单词,加这个空格就是为了让组3能定位到单词的起始位置(单词前必然是空格),配合组2的贪婪匹配,就能把匹配范围内最后一个空格分隔的单词整段切下来丢掉。
内容的提问来源于stack exchange,提问作者HyperOni
相关产品推荐
相关产品推荐

