正则表达式常用语法与实例详解
正则表达式(Regular Expression)是一种用于匹配字符串模式的工具,广泛应用于文本检索、验证、替换等场景。本文基于常用正则语法,结合实例解析其核心规则,帮助快速掌握正则表达式的使用。
基础匹配符号
1. 普通字符与转义符(\)
普通字符:直接匹配自身(如
a匹配 “a”,123匹配 “123”)。转义符
\:将特殊字符转为普通字符,或表示特殊含义:- 匹配特殊字符(如
\.匹配 “.”,\*匹配 “*”)。 - 表示不可见字符(如
\n匹配换行,\t匹配制表符)。
示例:
- 正则
a\.b匹配 “a.b”(而非 “acb” 等)。 - 正则
\t匹配字符串中的制表符。
- 匹配特殊字符(如
2. 锚点:定位匹配位置
^:匹配字符串的开始位置(如^abc匹配以 “abc” 开头的字符串,如 “abc123”)。$$`:匹配字符串的结束位置(如 `xyz$$ 匹配以 “xyz” 结尾的字符串,如 “123xyz”)。
\b:匹配单词边界(单词与非单词字符的分界,如er\b匹配 “never” 中的 “er”,但不匹配 “verb” 中的 “er”)。\B:匹配非单词边界(如er\B匹配 “verb” 中的 “er”,但不匹配 “never” 中的 “er”)。示例:
- 正则
^hello$仅匹配字符串 “hello”(精确匹配)。 - 正则
\bcat\b匹配 “cat” 或 “a cat”,但不匹配 “category”(”cat” 不是独立单词)。
- 正则
量词:控制匹配次数
量词用于指定前面的子表达式匹配的次数,默认是贪婪模式(尽可能多匹配),加 ? 可变为非贪婪模式(尽可能少匹配)。
| 量词 | 含义 | 示例 |
|---|---|---|
* |
匹配 0 次或多次(等价于 {0,}) |
zo* 匹配 “z”、”zo”、”zoo” |
+ |
匹配 1 次或多次(等价于 {1,}) |
zo+ 匹配 “zo”、”zoo”,不匹配 “z” |
? |
匹配 0 次或 1 次(等价于 {0,1}) |
do(es)? 匹配 “do” 或 “does” |
{n} |
精确匹配 n 次 | o{2} 匹配 “food” 中的两个 “o” |
{n,} |
至少匹配 n 次 | o{2,} 匹配 “foooood” 中的所有 “o” |
{n,m} |
匹配 n 到 m 次(n ≤ m) | o{1,3} 匹配 “foooo” 中的前 3 个 “o” |
*?/+? |
非贪婪模式(尽可能少匹配) | a.*?b 匹配 “aabcb” 中的 “aab” |
示例:
- 贪婪模式:
a.*b匹配 “aabcb” 中的 “aabcb”(从第一个 “a” 到最后一个 “b”)。 - 非贪婪模式:
a.*?b匹配 “aabcb” 中的 “aab”(从第一个 “a” 到最近的 “b”)。
字符集与范围
1. 字符集 []
- 匹配括号内的任意一个字符(如
[abc]匹配 “a”、”b” 或 “c”)。 - 特殊字符在
[]中无需转义(如[.*+]匹配 “.”、”*” 或 “+”)。
示例:
- 正则
[0-9a-zA-Z_]匹配数字、字母或下划线(等价于\w)。
2. 否定字符集 [^]
- 匹配不在括号内的任意字符(如
[^abc]匹配除 “a”、”b”、”c” 外的任何字符)。
示例:
- 正则
[^0-9]匹配非数字字符(等价于\D)。
3. 字符范围 -
- 表示连续字符范围(如
[a-z]匹配小写字母,[0-9]匹配数字)。
示例:
- 正则
[A-Za-z]匹配所有大小写字母。 - 正则
[1-5a-c]匹配 “1”-“5” 或 “a”-“c”。
预定义字符类
正则提供了简化常用字符集的预定义类:
| 预定义类 | 含义 | 等价字符集 |
|---|---|---|
. |
匹配除换行符(\n)外的任意字符 |
无(需匹配换行可使用 [\s\S]) |
\d |
匹配数字字符 | [0-9] |
\D |
匹配非数字字符 | [^0-9] |
\s |
匹配空白字符(空格、制表符、换行等) | [ \f\n\r\t\v] |
\S |
匹配非空白字符 | [^ \f\n\r\t\v] |
\w |
匹配字母、数字、下划线 | [A-Za-z0-9_] |
\W |
匹配非字母、数字、下划线 | [^A-Za-z0-9_] |
示例:
- 正则
\d{3}-\d{4}匹配形如 “123-4567” 的字符串。 - 正则
\w+@\w+\.\w+匹配简单邮箱(如 “user@example.com”)。
分组与引用
1. 分组 (pattern)
- 将
pattern视为一个整体(子表达式),可配合量词使用。 - 捕获分组:匹配的内容会被保存,可通过
\n(反向引用)或编程语言的 API 获取(如 Java 的group(n))。
示例:
- 正则
(ab)+匹配 “ababab”(”ab” 重复 3 次)。 - 正则
(\d{3})-(\d{4})匹配 “123-4567”,分组 1 为 “123”,分组 2 为 “4567”。
2. 非捕获分组 (?:pattern)
- 仅分组,不保存匹配结果(提升性能,无需引用时使用)。
示例:
- 正则
(?:ab)+匹配 “abab”,但不保存分组内容。
3. 反向引用 \n
- 引用第 n 个捕获分组的内容(n 为正整数)。
示例:
- 正则
(\w+) \1匹配重复的单词(如 “hello hello”,\1引用第一个分组 “hello”)。 - 正则
<(\w+)>.*</\1>匹配成对标签(如<div>content</div>,\1引用 “div”)。
断言(零宽匹配)
断言用于判断某个位置前后是否符合特定条件,不消耗字符(仅匹配位置)。
1. 正向先行断言 (?=pattern)
- 匹配后面符合
pattern的位置。
示例:
- 正则
Windows(?=95|98|NT)匹配 “Windows95” 中的 “Windows”,但不匹配 “WindowsXP”。
2. 正向负向断言 (?!pattern)
- 匹配后面不符合
pattern的位置。
示例:
- 正则
Windows(?!95|98|NT)匹配 “WindowsXP” 中的 “Windows”,但不匹配 “Windows98”。
3. 反向先行断言 (?<=pattern)
- 匹配前面符合
pattern的位置。
示例:
- 正则
(?<=http:|https:)//匹配 “http://“ 或 “https://“ 中的 “//“(前面必须是 “http:” 或 “https:”)。
4. 反向负向断言 (?<!pattern)
- 匹配前面不符合
pattern的位置。
示例:
- 正则
(?<!abc)123匹配 “x123” 中的 “123”,但不匹配 “abc123” 中的 “123”。
常用正则实例
1. 验证场景
- 手机号:
^1[3-9]\d{9}$(以 1 开头,第二位 3-9,共 11 位)。 - 邮箱:
^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$(支持字母、数字、下划线及多级域名)。 - URL:
^https?://[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+(:\d+)?(/.*)?$(匹配 http/https 开头的网址)。 - 身份证号:
^\d{17}[\dXx]$(18 位,最后一位可为数字或 X/x)。
2. 提取与替换
- 提取 HTML 标签内容:
<title>(.*?)</title>(非贪婪匹配提取标题内容)。 - 替换空格:正则
\s+匹配连续空格,替换为单个空格。 - 隐藏手机号中间 4 位:正则
(\d{3})\d{4}(\d{4}),替换为$1****$2(如 “13800138000” → “138**8000”)。
注意事项
1.贪婪 vs 非贪婪 :量词后加 ? 切换为非贪婪模式(如 .\*? 而非 .\*)。
2.转义字符 :在编程语言中使用时,需注意双重转义(如 Java 中 \\d 表示 \d)。
3.性能优化 :避免过度复杂的正则(如嵌套量词 (a\*)\*),可能导致匹配效率低下。
4.测试工具 :使用在线工具(如 Regex101)验证正则表达式,快速调试