正则表达式

发布于:2025-07-12 ⋅ 阅读:(19) ⋅ 点赞:(0)

1. 正则表达式的基本概念

正则表达式(Regex)是一种用于描述字符串模式的工具,通过特定语法匹配、查找、替换或验证文本。它由普通字符(如字母、数字)和特殊字符(元字符)组成,广泛应用于编程语言、文本处理工具(如 grep、sed)和框架(如 Spring Cloud Gateway)中。

核心用途
  • 查找:在文本中匹配符合特定规则的字符串(如邮箱、手机号)。
  • 替换:将匹配的文本替换为其他内容。
  • 验证:检查输入是否符合预期格式(如表单验证)。
  • 提取:从复杂文本中提取关键信息(如日志分析)。

2. 正则表达式的基本语法

(1) 元字符
元字符 说明 示例
. 匹配任意单个字符(除换行符外) a.c 匹配 abca1c
\d 匹配数字字符(等价于 [0-9] \d{3} 匹配 123
\D 匹配非数字字符 \D+ 匹配 abc
\w 匹配字母、数字或下划线(等价于 [a-zA-Z0-9_] \w+ 匹配 hello_123
\W 匹配非字母、数字或下划线 \W+ 匹配 !@#
\s 匹配空白字符(空格、制表符等) \s+ 匹配多个空格
\S 匹配非空白字符 \S+ 匹配连续的非空字符
(2) 量词
量词 说明 示例
* 匹配前一个字符 0 次或多次 a* 匹配 ""aaa
+ 匹配前一个字符 1 次或多次 a+ 匹配 aaa,但不匹配 ""
? 匹配前一个字符 0 次或 1 次 a? 匹配 ""a
{n} 匹配前一个字符 恰好 n 次 a{3} 匹配 aaa
{n,} 匹配前一个字符 至少 n 次 a{2,} 匹配 aaaaa
{n,m} 匹配前一个字符 至少 n 次,最多 m 次 a{2,4} 匹配 aaaaaaaaa
(3) 边界符号
符号 说明 示例
^ 匹配字符串的开头 ^abc 匹配以 abc 开头的字符串
$ 匹配字符串的结尾 xyz$ 匹配以 xyz 结尾的字符串
\b 匹配单词边界 \bcat\b 匹配 cat,但不匹配 category
\B 匹配非单词边界 \Bcat\B 匹配 category 中的 cat
(4) 字符类
  • [abc]:匹配 abc 中的任意一个字符。
  • [^abc]:匹配 非 a、b、c 的字符。
  • [a-z]:匹配任意小写字母。
  • [A-Z0-9]:匹配任意大写字母或数字。
(5) 分组与捕获
  • 捕获组:用 () 包裹的子表达式,可提取匹配内容。
    (\w+)-management(?<segment>/?.*)
    
    • (\w+):捕获模块名称(如 storage)。
    • (?<segment>/?.*):捕获路径后缀(如 /api/v1/data)。
  • 反向引用:通过 \1\2 等引用捕获组内容。
    (\w+)\s\1  # 匹配重复的单词(如 "hello hello")
    

3. 正则表达式在 Spring Cloud Gateway 中的应用

(1) 路径匹配与重写

在 Spring Cloud Gateway 的路由配置中,正则表达式常用于:

  • 路径匹配:通过 Path 断言匹配请求路径。
  • 路径重写:通过 RewritePath 过滤器修改请求路径。
(2) 示例:合并模块路径重写

需求:将 /xxx-management/** 请求统一转发到 mes-runtime 服务,并移除模块前缀(如 /storage-management/api/api)。

优化前(冗余配置)

filters:
  - RewritePath=/storage-management(?<segment>/?.*), $\{segment}
  - RewritePath=/carrier-management(?<segment>/?.*), $\{segment}
  ...

优化后(通用正则表达式)

filters:
  - RewritePath=/(?<module>[a-zA-Z]+)-management(?<segment>/?.*), $\{segment}
  • 解释
    • (?<module>[a-zA-Z]+):捕获模块名称(如 storagecarrier)。
    • (?<segment>/?.*):捕获路径后缀(如 /api/v1/data)。
    • $\{segment}:替换为后缀部分,去除模块前缀。
(3) 注意事项
  • 转义字符:在 YAML 中,反斜杠 \ 需要转义为 \\
  • 测试工具:使用 regex101.com 验证正则表达式逻辑。
  • 性能影响:复杂正则表达式可能增加匹配开销,需权衡简洁性与性能。

4. 高级用法:环视断言与非捕获组

(1) 环视断言(Lookaround)
  • 正向前瞻(?=...),匹配某个位置 之后必须满足的条件
    \d{3}(?=-)  # 匹配后跟 `-` 的三位数字(如 `123-456` 中的 `123`)
    
  • 正向后顾(?<=...),匹配某个位置 之前必须满足的条件
    (?<=\d{3})-\d{3}  # 匹配 `123-456` 中的 `-456`
    
  • 负向前瞻/后顾(?!=...)(?<!...),匹配不满足条件的位置。
(2) 非捕获组
  • 使用 (?:...) 定义分组,但不捕获内容。
    (?:storage|carrier)-management  # 匹配 `storage-management` 或 `carrier-management`
    

5. 常见应用场景

(1) 表单验证
  • 邮箱^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
  • 手机号(中国大陆)^1[3-9]\d{9}$
  • 日期(YYYY-MM-DD)^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$
(2) 日志分析
  • 提取日志中的 IP 地址:
    \b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b
    
(3) 文本替换
  • 将重复的单词替换为单次出现:
    \b(\w+)\s+\1\b  # 匹配 "hello hello"
    替换为:$\1
    

6. 工具推荐

  1. 在线测试工具
    • regex101.com:实时验证正则表达式逻辑。
    • RegExr:交互式学习与调试。
  2. 编程语言支持
    • Javajava.util.regex.Pattern
    • Pythonre 模块。
    • JavaScript:正则表达式字面量 /pattern/

7. 常见误区与避坑

  1. 贪婪匹配
    • 默认量词(如 *+)是贪婪的,可能匹配过多内容。
    • 使用 ? 修饰为非贪婪模式:.*?
  2. 转义字符
    • 特殊字符(如 .*)需用 \ 转义。
    • 在字符串中需双重转义(如 \\d)。
  3. 边界条件
    • 使用 \b 匹配单词边界,避免部分匹配(如 cat vs category)。

8. 总结

正则表达式是处理文本的强大工具,尤其在路径匹配、数据验证和文本提取场景中不可或缺。通过合理使用元字符、分组和断言,可以显著提升配置的简洁性与可维护性(如 Spring Cloud Gateway 的路由优化)。掌握其语法和高级用法,能有效解决复杂文本处理问题。


网站公告

今日签到

点亮在社区的每一天
去签到