正则表达式语法与实战速查
常用写法
grep -E '^error' app.log
grep -E 'error|warn' app.log
grep -E '^[0-9]{4}-[0-9]{2}-[0-9]{2}' app.log
grep -E 'user_[a-z0-9]+' app.log
grep -E 'colou?r' app.log
grep -E '^[^#]' config.conf
grep -P '\b\d{1,3}(\.\d{1,3}){3}\b' app.log
grep -P '(?<=user=)[^&]+' access.log
grep -P '^(?!.*healthz).*$' access.log
grep -oE '[0-9]+ms' app.log | sort -n
sed -E 's/[[:space:]]+/ /g' file
sed -E 's/^([^:]+):.*/\1/' file
awk '/^ERROR/ {print $0}' app.log
场景速查
| 目的 |
写法/命令 |
注意 |
| 行首/行尾 |
^ / $ |
多行文本需显式启用多行模式 |
| 任意字符 |
. |
默认不匹配换行 |
| 字符类 |
[a-z0-9_] |
- 放首尾才是字面量 |
| 排除字符 |
[^abc] |
方括号内取反 |
| 量词 |
* + ? {m,n} |
默认贪婪匹配 |
| 非贪婪 |
*? +? |
主要见于 PCRE |
| 分组捕获 |
(...) / \1 |
sed -E 用 \1 引用 |
| 非捕获分组 |
(?:...) |
只分组不捕获 |
| 或 |
a|b |
用括号限定作用范围 |
| 单词边界 |
\b |
GNU 工具支持,POSIX 未定义 |
| 前瞻 |
(?=...) / (?!...) |
需要 PCRE(grep -P) |
| 后顾 |
(?<=...) / (?<!...) |
后顾长度通常要求固定 |
| 忽略大小写 |
grep -i / (?i) |
不要硬编码两种大小写 |
易错点
- 错误:在默认 BRE 里写
grep '\d+';正确:用 grep -E '[0-9]+' 或 grep -P '\d+'。
- 错误:
sed 's/\d+/N/g';正确:sed -E 's/[0-9]+/N/g',或改用 perl -pe。
- 错误:认为
.* 能跨行匹配;正确:默认 . 不匹配换行,需要 (?s) 或 grep -Pzo。
- 错误:贪婪量词吃掉过多内容;正确:用
*?/+?,或把 . 换成更窄的字符类。
- 错误:把
. 当字面点号;正确:转义为 \. 或放进字符类 [.]。
- 错误:在双引号里写含
$ 的正则;正确:用单引号避免 shell 展开变量和反引号。
- 错误:假设
[a-z] 只匹配 ASCII;正确:受 locale 影响,可设 LC_ALL=C 或改用 [[:lower:]]。
- 错误:写
(a+)+ 这类嵌套量词;正确:收窄字符类并限制长度,避免灾难性回溯。
- 错误:写成
a|b 却在长表达式中优先级错乱;正确:用 (?:a|b) 明确作用范围。
相关命令
读完自测
* 与 + 的区别是什么?
- 贪婪与非贪婪如何选择?
grep -E 与 grep -P 有什么区别?
答案
* 匹配 0 次或多次,+ 匹配 1 次或多次。
- 默认贪婪;在量词后加
? 改为非贪婪,PCRE 支持。
-E 使用 POSIX ERE,-P 使用 PCRE,支持 \d、前瞻和后顾等。