Loading... <div class="tip inlineBlock warning simple"> 🤖 本博客内容使用 GPT-4 技术进行润色 </div> 在数据世界里,文本数据无所不在,处理它们是日常工作的一部分。数据清洗、日志分析或是文本挖掘,都需要一种既强大又灵活的工具。而正则表达式,一种用精巧的符号序列构建的技术,就像是程序员的瑞士军刀,简约而不简单,赋予文本处理以惊人的力量。本博客将带你深入正则表达式的世界,展示它如何简化复杂的文本任务。 正则表达式并不是 Python 独有的工具,它同样适用于其他编程语言。然而,Python 通过 `re` 库提供了对正则表达式的完整支持。利用这个强大的库,我们可以在 Python 环境中灵活地运用正则表达式。在 Python 中,几乎所有正则表达式的操作都依赖于 `re` 库。下面,我们将列出一些常用的匹配规则,并探讨 `re` 库中的一些常用方法。 ## 1、正则表达式模式 以下表格总结了一些基本的正则表达式模式及其描述: | 模式 | 描述 | | -------- | ------------------------------------------------------------------------------------ | | `\w` | 匹配字母、数字及下划线 | | `\W` | 匹配非字母、数字及下划线的字符 | | `\s` | 匹配任意空白字符,等价于`[\t\n\r\f]` | | `\S` | 匹配任意非空白字符 | | `\d` | 匹配任意数字,等价于`[0-9]` | | `\D` | 匹配非数字字符 | | `\A` | 匹配字符串开头 | | `\Z` | 匹配字符串结尾(不包括换行符) | | `\z` | 匹配字符串结尾(包括换行符) | | `\G` | 匹配最后一次匹配结束的位置 | | `\n` | 匹配换行符 | | `\t` | 匹配制表符 | | `^` | 匹配一行的开头 | | `$` | 匹配一行的结尾 | | `.` | 匹配任意字符(默认不包括换行符),使用`re.DOTALL` 标记后,可匹配包括换行符的任意字符 | | `[...]` | 匹配方括号内的任一字符,例如`[amk]` 匹配 `a`、`m` 或 `k` | | `[^...]` | 匹配不在方括号内的任一字符,例如`[^abc]` 匹配除 `a`、`b`、`c` 之外的任意字符 | | `*` | 匹配0次或多次前面的表达式 | | `+` | 匹配1次或多次前面的表达式 | | `?` | 匹配0次或1次前面的表达式,采用非贪婪方式 | | `{n}` | 精确匹配`n` 次前面的表达式 | | `{n, m}` | 匹配`n` 到 `m` 次前面的表达式,采用贪婪方式 | | `a|b` | 匹配`a` 或 `b` | | `()` | 将括号内的表达式作为一个分组 | ## 2、正则表达式修饰符(可选标志) 修饰符可以改变正则表达式的匹配行为。以下是一些常用的正则表达式修饰符及其作用: | 修饰符 | 描述 | | ------ | ------------------------------------------------------------------------------ | | `re.I` | 使匹配对大小写不敏感,即忽略大小写 | | `re.L` | 使`\w`、`\W`、`\b`、`\B`、`\s`、`\S` 这些特殊字符集依赖于当前环境 | | `re.M` | 多行匹配,影响`^` 和 `$` 的行为 | | `re.S` | 使`.` 匹配包括换行在内的所有字符 | | `re.U` | 使`\w`、`\W`、`\b`、`\B`、`\d`、`\D`、`\s`、`\S` 依赖于 Unicode 字符属性数据库 | | `re.X` | 提高可读性,允许在正则表达式中添加空格和注释(`#` 后面的内容) | ## 3、正则表达式实例 ### ① 字符匹配 这是最基础的匹配方式,直接通过字面值进行匹配。 | 实例 | 描述 | | ------ | ------------------- | | python | 匹配字符串 "python" | ### ② 字符类 字符类允许你匹配指定的字符集合。通过使用方括号,可以指定一个字符集,从而匹配多种可能的字符。 | 实例 | 描述 | | ------------- | ---------------------------------- | | `[Pp]ython` | 匹配 "Python" 或 "python" | | `pytho[ne]` | 匹配 "python" 或 "pythoe" | | `[aeiou]` | 匹配任一元音字母 | | `[0-9]` | 匹配任一数字,等同于`[0123456789]` | | `[a-z]` | 匹配任一小写字母 | | `[A-Z]` | 匹配任一大写字母 | | `[a-zA-Z0-9]` | 匹配任一字母或数字 | | `[^aeiou]` | 匹配除 "aeiou" 以外的任意字符 | | `[^0-9]` | 匹配任意非数字字符 | ### ③ 特殊字符类 特殊字符类用于匹配特定类型的字符,如数字、空白等,而无需显式地列出所有可能的字符。 | 实例 | 描述 | | ---- | ------------------------------------------------------------------------------------ | | `.` | 匹配除`\n` 之外的任何单个字符。要匹配包括 `\n` 在内的任何字符,请使用 `[.\n]` 模式。 | | `\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_]`。 | ## 4、正则表达式方法 ### `re.match()` 函数 `re.match()` 函数尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,`match()` 就返回 `None`。 ```python re.match(pattern, string, flags=0) ``` 参数说明: - `pattern`: 要匹配的正则表达式。 - `string`: 要匹配的字符串。 - `flags`: 标志位,用于控制正则表达式的匹配方式。 匹配成功,`re.match` 方法返回一个匹配的对象;否则返回 `None`,我们可以使用 `group(num)` 或 `groups()` 方法从匹配对象中获取信息。 ### `re.search()` 函数 `re.search()` 函数扫描整个字符串并返回第一个成功的匹配。 ```python re.search(pattern, string, flags=0) ``` 与 `re.match` 类似,`re.search` 在匹配成功时返回一个匹配对象,否则返回 `None`。 ### `re.match()` 与 `re.search()` 的区别 `re.match()` 只匹配字符串的开始部分,如果开头不符合正则表达式,则匹配失败,函数返回 `None`;而 `re.search()` 匹配整个字符串,直到找到一个匹配项。 ```python import re string = "This is Pluto's personal blog" match = re.match(r'blog', string, re.M|re.I) if match: print("match.group() : ", match.group()) else: print("No match!!") search = re.search(r'blog', string, re.M|re.I) if search: print("search.group() : ", search.group()) else: print("No search!!") ``` 输出结果将显示 "No match!!" 和 "search.group() : blog",因为 `match()` 没有在字符串开头找到 "blog",而 `search()` 在整个字符串中进行了搜索。 ### `re.sub()` 函数 `re.sub()` 函数用于替换字符串中的匹配项。 ```python re.sub(pattern, repl, string, count=0, flags=0) ``` 参数说明: - `pattern`: 匹配的正则表达式。 - `repl`: 替换的字符串或一个函数。 - `string`: 要匹配的字符串。 - `count`: 模式匹配后替换的最大次数,默认为 0,意味着替换所有的匹配。 ### `re.compile()` 函数 `re.compile()` 函数用于编译正则表达式,生成一个正则表达式对象(Pattern 对象),供 `match()` 和 `search()` 等函数使用。 ```python re.compile(pattern, flags=0) ``` 通过预编译可以提高正则表达式的重用性,并提升匹配效率。 ### `findall()` 和 `finditer()` 函数 `findall()` 在字符串中找到正则表达式所匹配的所有子串,并返回一个列表;`finditer()` 返回一个迭代器,其中每个元素都是 `MatchObject` 实例。 ### `re.split()` 函数 `re.split()` 函数按照正则表达式匹配的子串将字符串分割后返回列表。 ## 5、正则表达式对象 在 Python 的 `re` 模块中,正则表达式的编译和匹配操作都与特定的对象相关联。这些对象增强了正则表达式的功能,使得文本处理更加高效和灵活。下面是两个最核心的对象: ### `re.RegexObject` 对象 `re.RegexObject` 是由 `re.compile()` 方法返回的对象,它代表了一个编译后的正则表达式。这个对象预先编译了正则表达式的模式,并可被多次用于匹配操作。使用 `re.RegexObject` 的好处是,当你需要多次使用同一个正则表达式时,你不必在每次匹配时重新编译它,这样可以大大提高效率。 例如,如果你正在构建一个文本编辑器,需要高亮显示所有的 Python 变量名,你可以编译一个匹配 Python 变量命名规则的正则表达式,并在每次文本更新时使用它。 ```python import re # 编译一个匹配 Python 变量名的正则表达式 variable_regex = re.compile(r'\b[a-zA-Z_][a-zA-Z_0-9]*\b') # 在文本中多次使用 text = "Here are some variables: var1, var2, function_name, _private_var" matches = variable_regex.findall(text) for match in matches: print("Found Python variable:", match) ``` ### `re.MatchObject` 对象 `re.MatchObject` 是由 `match()`、`search()` 等匹配函数返回的对象,它包含了匹配的详细信息。这个对象提供了多种方法来获取关于匹配部分的信息,例如匹配的文本、匹配的位置等。 `re.MatchObject` 的常用方法包括: - `group()`: 返回匹配的字符串。 - `start()`: 返回匹配开始的索引。 - `end()`: 返回匹配结束的索引。 - `span()`: 返回一个包含匹配 (开始, 结束) 索引的元组。 下面是一个 `re.MatchObject` 的使用示例: ```python import re # 匹配一个简单的日期格式:YYYY-MM-DD date_pattern = re.compile(r'(\d{4})-(\d{2})-(\d{2})') text = "The event will take place on 2024-02-29." match = date_pattern.search(text) if match: print("Matched date:", match.group()) # 获取整个匹配的部分 year, month, day = match.groups() # 获取各个组的匹配部分 print("Year:", year, "Month:", month, "Day:", day) print("Match starts at index:", match.start()) print("Match ends at index:", match.end()) print("Match span:", match.span()) ``` 通过使用这些对象和它们的方法,你可以更加精确地控制文本匹配和处理的过程,从而实现复杂的文本分析和数据提取任务。 ## 6、常用表达式集锦 <div class="tip inlineBlock info simple"> 注意,正则表达式用于校验的场景非常多,而且有些表达式可能因为业务需求的不同而有所变化。上述表达式是基于常用的模式简化和优化后的结果,但在实际使用中可能需要根据具体情况进行调整。 </div> ### 校验数字的表达式 - 数字:`^\d+$` - n位的数字:`^\d{n}$` - 至少n位的数字:`^\d{n,}$` - m-n位的数字:`^\d{m,n}$` - 非零开头的数字:`^[1-9]\d*$` - 正整数:`^[1-9]\d*$` - 负整数:`^-[1-9]\d*$` - 非负整数(正整数 + 0):`^\d+$` - 非正整数(负整数 + 0):`^-\d+$` - 正浮点数:`^[1-9]\d*\.\d+|0\.\d*[1-9]\d*$` - 负浮点数:`^-([1-9]\d*\.\d+|0\.\d*[1-9]\d*)$` - 浮点数:`^-?([1-9]\d*\.\d+|0\.\d*[1-9]\d*|0?\.0+|0)$` ### 校验字符的表达式 - 汉字:`^[\u4e00-\u9fa5]+$` - 英文和数字:`^[A-Za-z0-9]+$` - 长度为n的所有字符:`^.{n}$` - 由26个英文字母组成的字符串:`^[A-Za-z]+$` - 由26个大写英文字母组成的字符串:`^[A-Z]+$` - 由26个小写英文字母组成的字符串:`^[a-z]+$` - 由数字和26个英文字母组成的字符串:`^[A-Za-z0-9]+$` - 由数字、26个英文字母或者下划线组成的字符串:`^\w+$` ### 特殊需求表达式 - Email地址:`^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$` - 域名:`^(?i:[a-z0-9]-?[a-z0-9]*\.)+[a-z]{2,}$` - Internet URL:`^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$` - 手机号码(简化匹配):`^\+?\d{10,13}$` - 身份证号(简化匹配):`^\d{15}(\d{2}[0-9xX])?$` - 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):`^[a-zA-Z][a-zA-Z0-9_]{4,15}$` - 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):`^[a-zA-Z]\w{5,17}$` - 强密码(包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):`^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$` - 日期格式(YYYY-MM-DD):`^\d{4}-\d{1,2}-\d{1,2}$` - 中国邮政编码:`^[1-9]\d{5}$` - IP地址:`^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$` Last modification:March 1, 2024 © Allow specification reprint Support Appreciate the author AliPayWeChat Like 如果觉得我的文章对你有用,请随意赞赏