1 第4.2节:正则表达式语法详解-转义字符与POSIX
1.1 背景
要学习正则表达式语法,就要了解业界的正则表达式引擎,目前各大正则表达式引擎在一定程度上都会向PCRE
标准靠拢,同时又有自己的特色,因此,在不同的工具或编程语言环境下,正则表达式的描述都会可能存在一定的差异,读者一定要阅读具体工具的正则表达式语法。
以下是几个常见的正则表达式引擎及特点:
引擎名称 | 核心特点 | 优势场景 | 典型应用领域 |
---|---|---|---|
PCRE / PCRE2 | 兼容Perl语法,支持几乎所有现代正则特性(非贪婪匹配、断言、递归等);PCRE2优化了Unicode和性能 | 通用场景,需要复杂模式匹配 | PHP、Nginx、Apache、C/C++项目 |
Boost.Regex | 多标准兼容(PCRE、POSIX、Unicode),C++风格接口,与C++标准库无缝集成 | C++开发,需跨标准适配的文本处理 | C++应用程序、跨平台项目 |
Onigmo | 卓越的Unicode支持,兼容Perl/Ruby语法,支持多字节字符集和Unicode属性类 | 多语言文本处理(如中日韩文字) | Ruby语言、Sublime Text编辑器 |
RE2 | 线性时间复杂度,避免回溯陷阱,安全性高,适合不可信输入 | 处理用户提交的正则模式,防ReDoS攻击 | Go语言标准库、V8引擎、Redis |
Hyperscan | 基于DFA和SIMD优化,支持数千模式同时匹配,速度极快 | 网络安全(入侵检测)、日志实时分析 | 防火墙、病毒扫描工具 |
TRE | 支持近似匹配(模糊匹配),可配置错误容忍度,兼容POSIX标准 | 拼写纠错、相似文本搜索、模糊匹配需求 | 文本处理工具、自然语言处理库 |
1.2 转义字符
部分特殊字符或保留字符不能直接写在字符串中,比如:引号、斜线等本身在正则表达式中有特殊意义的字符,需要用转义字符来表示它们,转义字符是由反斜杠(‘\’)开头的字符序列。转义字符的一个最常用的用处是在字符串常量中包含双引号。由于普通的双引号会终止字符串,所以必须用 ‘"’ 来表示字符串里实际的双引号字符。例如:
$ awk 'BEGIN { print "He said \"hi!\" to her." }'
执行结果:
He said "hi!" to her.
反斜杠字符本身也是一个不能直接包含的字符,必须写成 ‘\’ 才能在字符串或正则表达式中放入一个反斜杠。因此,由 ‘"’ 和 ‘\’ 这两个字符组成的字符串必须写成 "\"\\"
。
1.2.1 标准转义字符
转义字符还可以用于表示不可打印的字符,如制表符(TAB)或换行符。以下是AWK中一些常见的转义字符及其含义:
转义字符 | 说明 |
---|---|
\a | 响铃(警报)字符,通常会让终端发出哔声。 |
\b | 退格符。 |
\f | 换页符。 |
\n | 换行符。 |
\r | 回车符。 |
\t | 制表符。 |
\v | 垂直制表符。 |
\ddd | 八进制数 ddd 所表示的字符。例如,\040 是空格,\11 是制表符。 |
\xhh | 十六进制数 hh 所表示的字符。(GNU awk 特有) |
\uhh | Unicode字符编码,十六进制数 hh 所表示的字符。(GNU awk 特有) |
/ | 转义/字符 |
\ | 转义\字符 |
" | 转义"字符 |
例如,下面的代码会打印一个包含制表符的字符串:
$ awk 'BEGIN { print "Column1\tColumn2" }'
执行结果:
Column1 Column2
在正则表达式中,反斜杠也有特殊的含义。它用于对正则表达式中的特殊字符进行转义,使其作为普通字符来处理。例如,如果你想匹配一个点号(‘.’),由于点号在正则表达式中有特殊含义(匹配任意单个字符),你需要写成 ‘.‘。下面的例子会匹配包含实际点号的记录:
$ awk '/\./ { print $0 }' data.txt
这里,/\./
这个正则表达式会匹配任何包含点号的记录,并打印出整条记录。
在字符串常量和正则表达式常量中使用转义字符时,要确保正确理解其含义,避免因误用而导致意外的结果。
1.2.2 gawk扩展转义字符
转义字符 | 说明 |
---|---|
\s | 匹配当前区域设置定义的任何空白字符,可视为 [[:space:]] 的简写 |
\S | 匹配当前区域设置定义的任何非空白字符,可视为 [1] 的简写 |
\w | 匹配任何单词构成字符,即匹配字母、数字或下划线,可视为 [[:alnum:]_] 的简写 |
\W | 匹配任何非单词构成字符,可视为 [^[:alnum:]_] 的简写 |
\< | 匹配单词开头的空字符串,例如 /\<away/ 匹配 away 但不匹配 stowaway |
\> | 匹配单词结尾的空字符串,例如 /stow\>/ 匹配 stow 但不匹配 stowaway |
\y | 匹配单词开头或结尾的空字符串(即单词边界 ),例如 \yballs?\y 可匹配 ball 或 balls 作为独立单词 |
\B | 匹配两个单词构成字符之间的空字符串,例如 /\Brat\B/ 匹配 crate 但不匹配 dirty rat ,本质与 \y 相反,匹配不在单词边缘的空字符串 |
::: alert-danger
awk的正则表达式并没有完整兼容PCRE
,比如:没有\d
(数字)这个转义字符。因此,匹配数字时,使用替换方案[0-9]
来代表数字,或使用POSIX的[:digit:]
字符类。
:::
1.3 POSIX字符类
正因为正则表达式的强大作用,在业界形成统一的规范前,已经有很多的工具软件实现了自己的正则表达式语法,且各个软件的正则表达式语法各不相同,增加了使用者的学习成本,因此,POSIX对正则表达式进行了一定的规范化,目前主流的正则表达式引擎对POSIX都做了兼容。
POSIX字符类 | 说明 |
---|---|
[:alnum:] | 字母数字字符(字母和数字) |
[:alpha:] | 字母字符(A - Z、a - z 等) |
[:blank:] | 空格和制表符(TAB)字符 |
[:cntrl:] | 控制字符(如 ASCII 里的控制码,像换行、回车等非打印控制功能的字符 ) |
[:digit:] | 数字字符(0 - 9 ) |
[:graph:] | 可打印且可见的字符(空格可打印但不可见,“a”这类字符既满足可打印又满足可见 ) |
[:lower:] | 小写字母字符(a - z ) |
[:print:] | 可打印字符(非控制字符,除了控制码外,像字母、数字、标点、空格等能输出显示的字符 ) |
[:punct:] | 标点字符(非字母、数字、控制字符、空格的字符,像!、,、. 等 ) |
[:space:] | 空白字符(含空格、制表符、换行符、回车符、换页符、垂直制表符 ) |
[:upper:] | 大写字母字符(A - Z ) |
[:xdigit:] | 十六进制数字字符(0 - 9、a - f、A - F ,用于表示十六进制数 ) |
1.3.1 例1:awk语法查找电话号码
文本num.txt
内容如下
13112345678
13212345678
13312345678
13412345678
13512345678
- awk语法查找电话号码
awk '/\y13[0-9]{9}\y/' num.txt
- POSIX语法查找电话号码
awk '/\y13[[:digit:]]{9}\y/' num.txt
🕮说明:在使用POSIX字符类时,需要在字符类的外层再加一对[]!
::: alert-danger
awk的正则表达式语法,部分描述和PCRE
存在差异,读者在使用时要注意区分!
:::
作者声明:本文用于记录和分享作者的学习心得,可能有部分文字或示例来自AI平台,如:豆包、DeepSeek(硅基流动)(注册链接)等,由于本人水平有限,难免存在表达错误,欢迎留言交流和指教!
Copyright © 2022~2025 All rights reserved.
:space: ↩︎