正则表达式(Regex)教程以及相关工作中实践示例
正则表达式(Regex)教程
正则表达式(Regular Expression,简称 regex)是一个强大的文本处理工具,用于在字符串中进行模式匹配、查找和替换。正则表达式被广泛应用于编程、数据分析、日志处理、网络爬虫等领域。
目录
正则表达式基础语法
1. 字符匹配
.: 匹配任意单个字符(除了换行符)。\d: 匹配数字,等价于[0-9]。\D: 匹配非数字,等价于[^0-9]。\w: 匹配字母、数字和下划线,等价于[a-zA-Z0-9_]。\W: 匹配非字母、非数字、非下划线字符,等价于[^a-zA-Z0-9_]。\s: 匹配任意空白字符(包括空格、制表符、换行符等)。\S: 匹配非空白字符。
2. 字符集(Character Set)
[abc]: 匹配a、b或c中的任意一个字符。[^abc]: 匹配除了a、b、c外的任意字符。[a-z]: 匹配任意小写字母。[A-Z]: 匹配任意大写字母。[0-9]: 匹配任意数字。
3. 量词(Quantifiers)
*: 匹配前面的子表达式 0 次或多次。+: 匹配前面的子表达式 1 次或多次。?: 匹配前面的子表达式 0 次或 1 次。{n}: 匹配前面的子表达式恰好 n 次。{n,}: 匹配前面的子表达式至少 n 次。{n,m}: 匹配前面的子表达式至少 n 次,最多 m 次。
4. 边界匹配
^: 匹配输入字符串的开始。$: 匹配输入字符串的结束。\b: 匹配单词的边界(字母、数字和下划线的边界)。\B: 匹配非单词边界。
5. 分组和选择
(): 用于分组,把多个字符或表达式组合成一个单元。例如(abc)可以匹配字符串 “abc”。|: 或运算符,匹配|两边的任意一个表达式。例如abc|def可以匹配 “abc” 或 “def”。
6. 反向引用
\1,\2,\3, …: 引用前面括号内的分组。\1匹配第一个分组的内容,\2匹配第二个分组的内容,依此类推。
7. 预定义字符集
\b: 单词边界。\B: 非单词边界。\A: 匹配字符串的开始。\Z: 匹配字符串的结束。\z: 匹配字符串的结束(忽略换行符)。
c常用正则表达式示例
1. 邮箱地址匹配
正则表达式: ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
解释:
^[a-zA-Z0-9._%+-]+: 匹配邮箱的用户名部分(字母、数字和一些符号)。@: 匹配 “@” 符号。[a-zA-Z0-9.-]+: 匹配邮箱的域名部分(字母、数字、点、连字符)。\.[a-zA-Z]{2,}$: 匹配域名后缀(至少两个字母)。
2. 手机号匹配
正则表达式: ^1[3-9]\d{9}$
解释:
^1: 匹配以 1 开头。[3-9]: 第二位数字为 3 到 9 之间的任意一个。\d{9}$: 后面跟着 9 个数字。
3. 日期格式匹配(如 YYYY-MM-DD)
正则表达式: ^\d{4}-\d{2}-\d{2}$
解释:
c^\d{4}: 匹配 4 个数字(年份)。-\d{2}: 匹配一个 “-” 后面跟着 2 个数字(月份)。-\d{2}$: 匹配一个 “-” 后面跟着 2 个数字(日期)。
正则表达式的高级用法
1. 懒惰匹配(Lazy Matching)
默认情况下,量词(如 *、+)是贪婪的,即它们尽可能多地匹配字符。懒惰匹配会让它们尽可能少地匹配字符。
.*?: 匹配任意字符(最少匹配)。.+?: 匹配至少一个字符(最少匹配)。
2. 断言(Assertions)
断言用来匹配某个位置,而不消耗字符。
- 正向先行断言(Positive Lookahead):
(?=...)。表示当前位置后面必须满足某个条件。 - 负向先行断言(Negative Lookahead):
(?!...)。表示当前位置后面不能满足某个条件。
3. 替换与分割
- 替换: 使用
replace函数可以替换字符串中匹配的部分。例如,在 Python 中可以使用re.sub()来进行替换。 - 分割: 使用
split函数根据正则表达式分割字符串。例如,在 Python 中使用re.split()。
正则表达式的常见错误
1. 忘记转义特殊字符
在正则表达式中,某些字符(如 ., *, ?, +, (, ), [, ], \\ 等)有特殊含义。如果要匹配这些字符本身,必须使用反斜杠进行转义(例如:\.)。
2. 贪婪匹配导致问题
正则表达式的量词默认是贪婪的,会匹配尽可能多的字符,可能导致不想要的结果。可以使用懒惰匹配来限制匹配的字符数。
3. 不考虑行结束符(如换行符)
默认情况下,正则表达式的 . 不匹配换行符。如果想要匹配所有字符,包括换行符,可以使用 re.DOTALL 标志(在 Python 中)。
相关实践示例
1. 行匹配中忽略出现或者不出现的关键字
例如有些日志行 以
具体日志格式为
1 | <pattern>2025-02-10 xxxx |
真实的数据行结构分别为下面四种,
1 | <pattern>2025-02-10 xxxx |
1 | <pattern>2025-02-10 xxxx |
1 | <pattern>2025-02-10 xxxx |
1 | <pattern>2025-02-10 xxxx |
如果通过正则识别将下面的四种数据分开,
正常正则的正则识别规则
1 | ^(?:</pattern>)?<pattern> |
日志采集系统正则识别规则
1 | \n((?:</pattern>)?<pattern>) |