1_1、 正则表达式 - 指南

1. 简介

正则表达式(Regular Expression,简称RegexRegExp一种用于描述、匹配和处理文本模式的就是)特殊字符串规则。它通过预定义的符号和语法,飞快从复杂文本中筛选、验证、提取或替换符合特定格式的内容,是编程、文本处理、数据清洗等场景的核心工具。

方便来说,正则表达式的核心价值是用一套简洁的规则,替代繁琐的字符串判断逻辑。比如:

  • 验证“手机号是否为11位数字”
  • 从文本中提取所有“邮箱地址”
  • 将所有“日期格式(2024-05-20)”替换为“2024年05月20日”
  • 过滤文本中的所有“HTML标签”

没有正则表达式时,需要写大量代码判断字符类型、长度、位置;有了正则,一行规则即可完成。

2. 基本语法:符号即规则

正则表达式的语法由“普通字符”和“元字符”组成,元字符是实现“模式匹配”的核心,常用元字符可分为以下几类:

2.1 匹配“单个字符”的元字符

元字符含义示例
.匹配任意单个字符(除换行符 \na.b 可匹配 aabacba1b(中间是任意字符)
[ ]匹配“括号内任意一个字符”[0-9] 匹配单个数字;[a-zA-Z] 匹配单个字母
[^ ]匹配“非括号内的任意字符”[^0-9] 匹配非数字(如字母、符号)
\d等价于 [0-9],匹配单个数字\d{3} 匹配 3 个连续数字(如 123
\D等价于 [^0-9],匹配非数字\D 可匹配 a!(空格)
\w匹配“字母、数字、下划线”(等价于 [a-zA-Z0-9_]\w 可匹配 A5_
\W匹配“非字母、非数字、非下划线”\W 可匹配 @#(空格)
\s匹配“空白字符”(空格、制表符 \t、换行符 \n 等)a\sb 可匹配 a b(中间是空格)、a\tb(中间是制表符)

2.2 控制“匹配次数”的元字符

用于指定某个字符/子模式的重复次数,处理“多字符匹配”问题:

元字符含义示例
*匹配前一个元素“0次或多次”(贪婪:尽可能多匹配)a* 可匹配 ""(空)、aaaaaa
+匹配前一个元素“1次或多次”(贪婪)a+ 可匹配 aaa,但不匹配空
?匹配前一个元素“0次或1次”(可选)ab? 可匹配 a(b出现0次)、ab(b出现1次)
{n}匹配前一个元素“恰好n次”\d{4} 匹配 4 个数字(如 2024,用于匹配年份)
{n,}匹配前一个元素“至少n次”\d{2,} 可匹配 121231234
{n,m}匹配前一个元素“n到m次”\d{3,4} 可匹配 123(3次)、1234(4次)
*?/+?非贪婪模式(尽可能少匹配)aabbaaa.*?a,会匹配 aabba(而非全串)

2.3 控制“位置”的元字符

用于锁定匹配内容在文本中的位置(开头、结尾、单词边界等):

元字符含义示例
^匹配“字符串开头”(多行模式下匹配“每行开头”)^Hello 可匹配 Hello World(开头是Hello),不匹配 Hi Hello
$匹配“字符串结尾”(多行模式下匹配“每行结尾”)World$ 可匹配 Hello World(结尾是World),不匹配 World Hi
\b匹配“单词边界”(字母/数字与非字母/数字的分隔处)\bcat\b 可匹配 cat(单独单词),不匹配 category(cat是前缀)
\B匹配“非单词边界”\Bcat\B 可匹配 category(cat在单词中间),不匹配单独的 cat

2.4 分组与逻辑:处理复杂模式

当需要匹配“多个子模式的组合”时,用分组和逻辑符号:

元字符含义示例
( )分组:将多个字符视为一个整体,且可“捕获”匹配结果(ab)+ 可匹配 ababab(ab重复1次或多次);(\d{4})-(\d{2}) 可捕获“年”和“月”
1(竖线)逻辑“或”:匹配多个模式中的一个cat1dog 可匹配 catdog
\n引用第n个分组的匹配结果(反向引用)(\w+)\s+\1 可匹配重复单词(如 hello hello\1 引用第一个分组的 hello

3. 典型应用场景(附示例)

正则表达式的用法本质是“用规则匹配文本”,以下是最常见的场景:

3.1 文本验证(格式合法性判断)

否符合特定格式(如手机号、邮箱、身份证):就是验证输入

  • 验证中国大陆手机号“1开头,第二位3-9,后面9位数字”就是:规则
    正则:^1[3-9]\d{9}$
    匹配:13812345678(有效);不匹配:12345678901(第二位是2,无效)

  • 验证邮箱:规则是“用户名@域名.后缀”(简化版)
    正则:^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$
    匹配:test@example.com(有效);不匹配:test@.com(域名无效)

3.2 内容提取(从文本中抓指定信息)

从杂乱文本中提取符合规则的内容(如日期、URL):

  • 提取所有日期(格式:2024-05-20)
    正则:\d{4}-\d{2}-\d{2}
    文本:今天是2024-05-20,昨天是2024-05-19
    提取结果:2024-05-202024-05-19

  • 提取URL中的域名
    正则:https?://(www\.)?([^/]+)https? 匹配http或https;([^/]+) 捕获域名)
    文本:访问 https://www.qt.io/doc/ 查看文档
    提取结果:qt.io(第二个分组的内容)

3.3 文本替换(批量修改内容)

按规则替换文本中的特定部分(如敏感词过滤、格式转换):

  • 过滤敏感词“bad”
    正则:bad(可加 i 选项不区分大小写,如 bad/i
    文本:This is a bad word, BAD!
    替换为 *** 后:This is a *** word, ***!

  • 将日期“2024-05-20”改为“2024年05月20日”
    正则:(\d{4})-(\d{2})-(\d{2})(分组捕获年、月、日)
    替换规则:$1年$2月$3日$1 引用第一个分组的“年”,以此类推)
    替换后:2024年05月20日

3.4 文本分割(按复杂规则拆分)

按“非固定分隔符”拆分文本(如同时按逗号、分号、空格拆分):

  • 正则:[,;\\s]+[,;] 匹配逗号或分号;\s 匹配空格;+ 表示“一个或多个”)
    文本:apple, banana; orange grape
    分割结果:["apple", "banana", "orange", "grape"]

4. 总结

4.1 注意事项

  1. 转义字符挑战:在编程语言(如C++、Java)中,\ 是转义符,因此正则中的 \d 需写成 \\d(双重转义)。例如在C++中,匹配数字的正则要写为 "\\d",而非 "\d"

  2. 贪婪与非贪婪*+ 默认是“贪婪模式”(尽可能多匹配),如需“非贪婪”(尽可能少匹配),需在后面加 ?。例如:

    • 文本:aabbaa
    • 贪婪匹配 a.*a:会匹配整个字符串 aabbaa(从第一个a到最后一个a)
    • 非贪婪匹配 a.*?a:会匹配 aabba(从第一个a到最近的a)
  3. 性能考量:复杂正则(如多层嵌套、大量通配符)在处理超长文本时可能效率较低,建议:

    • 尽量用具体规则替代模糊规则(如用 [0-9] 而非 . 匹配数字)
    • 避免不必要的分组和回溯(如用 {3} 替代 ???
  4. 工具辅助:正则语法较抽象,推荐用在线工具调试(如Regex101Regexr),输入规则和测试文本即可实时查看匹配结果。

4.2 跨语言通用性

正则表达式的核心语法是通用的(如元字符 .*\d 等),但不同编程语言(C++、Python、Java、JavaScript)的“语法细节”和“支持的高级特性”略有差异:

  • C++:通过 QRegExp(Qt)或 std::regex(C++11+)实现
  • Python:通过内置 re 模块实现
  • JavaScript:通过 RegExp 对象或字面量(如 /\d+/)实现

但只要掌握核心语法,切换语言时只需调整“语法细节”(如转义方式、函数调用)即可。

“文本处理的瑞士军刀”——学会它,能极大提升文本处理的效率和灵活性。就是总之,正则表达式

posted on 2025-10-03 12:13  ljbguanli  阅读(15)  评论(0)    收藏  举报