什么是正则表达式?正则表达式从入门到精通:一文掌握文本匹配的核心技巧

什么是正则表达式?正则表达式从入门到精通:一文掌握文本匹配的核心技巧

一、什么是正则表达式

正则表达式是一种用于描述、匹配和处理文本模式的工具,广泛应用于编程语言(如 PythonJavaScriptJava 等)、文本编辑器(如 VS Code、Sublime)、命令行工具(如 grep、sed)中。
核心功能
  • 验证文本格式(如邮箱、手机号、URL)
  • 搜索和提取文本中的特定模式
  • 替换文本中的内容
  • 分割字符串

二、基础元字符(Metacharacters)

元字符是正则表达式中具有特殊含义的字符,用于定义模式的规则。

 

元字符 含义 示例
. 匹配任意单个字符(除了换行符n,某些引擎支持匹配换行符) a.c 匹配 abca0ca#c 等
^ 匹配字符串的开头 ^hello 匹配以 hello 开头的字符串
$ 匹配字符串的结尾 world$ 匹配以 world 结尾的字符串
* 匹配前一个字符0 次或多次(贪婪匹配) a* 匹配空字符串、aaaaaa 等
+ 匹配前一个字符1 次或多次(贪婪匹配) a+ 匹配 aaaaaa 等,不匹配空字符串
? 匹配前一个字符0 次或 1 次(可选) colou?r 匹配 color 或 colour
[] 匹配括号内的任意一个字符 [abc] 匹配 abc 中的任意一个
[^] 匹配不在括号内的任意一个字符(取反) [^abc] 匹配除 abc 外的任意字符
{n} 匹配前一个字符恰好 n 次 a{2} 匹配 aa
{n,} 匹配前一个字符至少 n 次 a{2,} 匹配 aaaaa 等
{n,m} 匹配前一个字符至少 n 次,最多 m 次 a{2,5} 匹配 aaaaaaaaaaaaaa
| 匹配左右任意一个表达式(逻辑或) a|b 匹配 a 或 b
转义字符,用于取消元字符的特殊含义(如匹配 $[ 等) $ 匹配字符 $[ 匹配字符 [

三、预定义字符类(Predefined Character Classes)

为常见字符集合提供简写形式。
字符类 含义 等价写法
d 匹配任意一个数字(0-9) [0-9]
D 匹配任意一个非数字字符 [^0-9]
w 匹配任意一个单词字符(字母、数字、下划线) [A-Za-z0-9_]
W 匹配任意一个非单词字符 [^A-Za-z0-9_]
s 匹配任意一个空白字符(空格、制表符、换行符等) [tnrfv]
S 匹配任意一个非空白字符 [^tnrfv]

四、分组与反向引用(Groups and Backreferences)

  1. 分组(()
    用于将多个字符组合成一个整体,方便后续操作(如量词、反向引用)。
    示例
    • (ab)+ 匹配 abababababab 等(将 ab 作为一个整体重复)。
    • (d{3})-(d{4}) 匹配 123-4567 这样的格式,分组可用于提取部分匹配结果。
  2. 反向引用(n
    引用之前分组匹配到的内容,1 表示引用第一个分组,2 表示第二个分组,以此类推。
    示例
    • (w+)s1 匹配重复的单词,如 hello hello(第一个分组 (w+) 匹配 hello1 引用该内容)。
    • (<tag>).+?</1> 匹配 HTML 标签,如 <div>content</div>1 引用 <div>)。

五、零宽断言(Zero-Width Assertions)

用于匹配某个位置的前后条件,不消耗字符(零宽度)。

 

断言类型 含义 示例
正向前瞻 (?=) 匹配当前位置后面满足条件的内容 abc(?=def) 匹配 abc 后面紧跟 def 的位置(如 abcdef 中的 abc
负向前瞻 (?!) 匹配当前位置后面不满足条件的内容 abc(?!def) 匹配 abc 后面不跟 def 的位置(如 abcxyz 中的 abc
正向后瞻 (?<=) 匹配当前位置前面满足条件的内容 (?<=abc)def 匹配 def 前面是 abc 的位置(如 abcdef 中的 def
负向后瞻 (?<!) 匹配当前位置前面不满足条件的内容 (?<!abc)def 匹配 def 前面不是 abc 的位置(如 xdef 中的 def

六、贪婪与非贪婪匹配

  • 贪婪匹配:默认行为,尽可能多地匹配字符(使用 *+?{n,m} 时)。
    示例a.*b 匹配 aXbYb 时,会匹配整个 aXbYb(贪婪地匹配到最后一个 b)。
  • 非贪婪匹配:在量词后加 ?,尽可能少地匹配字符。
    示例a.*?b 匹配 aXbYb 时,会匹配 aXb(遇到第一个 b 就停止)。

七、常用场景示例

  1. 证邮箱格式
    ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$
    


    • ^[a-zA-Z0-9._%+-]+:用户名(字母、数字、特殊符号)。
    • @[a-zA-Z0-9.-]+:域名主体(如 example)。
    • .[a-zA-Z]{2,}$:域名后缀(如 .com.cn)。
  2. 提取电话号码(中国大陆手机号)
    ^1[3-9]d{9}$
    

    1:开头为 1。

    • [3-9]:第二位为 3-9 之间的数字。
    • d{9}:后面 9 位数字。
  3. 匹配 HTML 标签
    <(w+)>.*?</1>
    

    分组 (w+) 匹配标签名(如 divp),反向引用 1 匹配闭合标签。

八、注意事项

  1. 不同引擎的差异:正则表达式语法在不同语言 / 工具中可能略有不同(如换行符处理、断言支持等)。
  2. 性能优化:避免过度使用贪婪匹配和复杂分组,可能导致匹配效率低下。
  3. 调试优先:复杂模式建议先用在线工具测试,再集成到代码中。
阅读剩余