Bootstrap

正则表达式(Regular Expression, Regex)详解

正则表达式(Regular Expression, Regex)详解

正则表达式是一种用来匹配字符串的模式,它为文本处理提供了强大的功能,可以用于查找、替换、提取特定模式的文本。正则表达式广泛应用于文本搜索、数据验证、文本替换等场景。

一、正则表达式的基本语法

正则表达式由字符、元字符和量词组成。通过它们的组合,可以构建出非常复杂的匹配规则。

1. 元字符(Metacharacters)

元字符是正则表达式中的特殊字符,用于定义某种特定的匹配模式:

元字符含义
.匹配任意单个字符(除换行符)
^匹配字符串的开头
$匹配字符串的结尾
*匹配前面的字符零次或多次
+匹配前面的字符一次或多次
?匹配前面的字符零次或一次
[]匹配括号内的任意字符(字符集)
``
()分组,括号内的内容作为一个整体匹配
\转义符,表示将元字符转换为普通字符

2. 量词(Quantifiers)

量词用于控制匹配的次数,指定某个模式出现的次数范围:

量词含义
*匹配前面的模式零次或多次
+匹配前面的模式一次或多次
?匹配前面的模式零次或一次
{n}匹配前面的模式正好 n
{n,}匹配前面的模式至少 n
{n,m}匹配前面的模式至少 n 次,至多 m

3. 字符集(Character Classes)

字符集是用来定义要匹配的字符范围或类别:

字符集含义
[abc]匹配字符 abc
[^abc]匹配除 abc 之外的任意字符
[a-z]匹配所有小写字母
[A-Z]匹配所有大写字母
[0-9]匹配所有数字
\d匹配任意数字,等价于 [0-9]
\D匹配任意非数字字符,等价于 [^0-9]
\w匹配任意字母、数字或下划线,等价于 [A-Za-z0-9_]
\W匹配任意非字母、数字或下划线字符
\s匹配任意空白字符(空格、制表符、换行符等)
\S匹配任意非空白字符

二、常见正则表达式例子

1. 匹配电子邮件地址

要匹配一个电子邮件地址,可以使用以下正则表达式:

[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+

解释:

  • [a-zA-Z0-9_.+-]+:匹配邮箱名称部分,允许字母、数字、下划线、点号、加号、减号等字符,并且至少一个字符。
  • @:匹配固定的符号 @
  • [a-zA-Z0-9-]+:匹配域名部分,允许字母、数字和短横线。
  • \.:匹配点号。
  • [a-zA-Z0-9-.]+:匹配域名后缀部分,允许字母、数字、点号和短横线。

2. 匹配电话号码(中国手机号码)

匹配中国的11位手机号码(以1开头):

1[3-9]\d{9}

解释:

  • 1:匹配以 1 开头。
  • [3-9]:匹配第二位数字,范围为 39
  • \d{9}:匹配后面9位数字。

3. 匹配IP地址

IPv4 地址的匹配:

\b(?:\d{1,3}\.){3}\d{1,3}\b

解释:

  • \d{1,3}:匹配1到3位数字。
  • \.:匹配点号。
  • (?: ... ):非捕获组,匹配点号和数字部分三次。
  • \b:匹配边界,确保是独立的IP地址。

4. 匹配日期(格式:YYYY-MM-DD)

\d{4}-\d{2}-\d{2}

解释:

  • \d{4}:匹配4位数字(年份)。
  • -:匹配连字符。
  • \d{2}:匹配两位数字(月份和日期)。

5. 匹配URL地址

https?:\/\/(www\.)?[a-zA-Z0-9-]+\.[a-zA-Z]{2,}(/[a-zA-Z0-9#]+/?)* 

解释:

  • https?:匹配 httphttps
  • :\/\/:匹配 ://
  • (www\.)?:可选匹配 www.
  • [a-zA-Z0-9-]+:匹配域名部分。
  • \.[a-zA-Z]{2,}:匹配域名后缀,至少两位字母。
  • (/[a-zA-Z0-9#]+/?)*:匹配路径部分,可以出现零次或多次。

三、正则表达式在Python中的使用

在Python中,正则表达式由 re 模块提供支持。我们可以使用 re 模块来执行匹配、替换、查找等操作。

1. 导入 re 模块

import re

2. 常用方法

  • re.search():搜索字符串,返回第一个匹配的对象。
  • re.match():从字符串的开头开始匹配,如果开头不匹配则返回 None
  • re.findall():返回所有匹配的字符串列表。
  • re.sub():替换匹配的字符串。
  • re.split():根据正则表达式分割字符串。

3. 实例代码

1. 匹配电子邮件地址
import re

text = "请联系: [email protected][email protected]"
email_pattern = r'[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+'

emails = re.findall(email_pattern, text)
print(emails)  # 输出: ['[email protected]', '[email protected]']
2. 替换手机号码中的中间部分

将中国手机号的中间四位替换为****,如 13812345678 替换为 138****5678

phone = "13812345678"
masked_phone = re.sub(r'(\d{3})\d{4}(\d{4})', r'\1****\2', phone)
print(masked_phone)  # 输出: 138****5678
3. 分割字符串

使用正则表达式按空格或逗号分割字符串:

text = "apple, banana orange,grape"
split_text = re.split(r'[,\s]+', text)
print(split_text)  # 输出: ['apple', 'banana', 'orange', 'grape']
4. 验证日期格式

验证日期是否符合 YYYY-MM-DD 格式:

date_pattern = r'^\d{4}-\d{2}-\d{2}$'
date = "2024-10-22"

if re.match(date_pattern, date):
    print("日期格式正确")
else:
    print("日期格式错误")

四、贪婪与非贪婪匹配

  • 贪婪匹配:正则表达式默认是贪婪的,会尽可能多地匹配字符。
  • 非贪婪匹配:通过在量词后加 ?,让正则表达式匹配尽可能少的字符。

例子

text = "<html><head><title>Title</title></head><body>Content</body></html>"

# 贪婪匹配,会匹配到从第一个 < 到最后一个 >
print(re.findall(r'<.*>', text))  
# 输出: ['<html><head><title>Title</title></head><body>Content</body></html>']

# 非贪婪匹配,匹配最短的 < 和 > 之间的内容
print(re.findall(r'<.*?>', text)) 
# 输出: ['<html>', '<head>', '<title>', '</title>', '</head>', '<body>', '</body>', '</html>']

五、总结

正则表达式是一个非常强大的工具,适用于各种文本处理任务。从基础的匹配字符到复杂的模式提取,正则表达式提供了灵活的解决方案。尽管刚开始学习可能会显得复杂,但随着使用经验的积累,它将成为处理文本和数据不可或缺的工具。

下一步建议

  1. 通过更多实际案例练习正则表达式的应用,如日志分析、表单验证等。
  2. 学习如何在不同的编程语言中使用正则表达式,因为许多语言都支持正则表达式,如JavaScript、Java、Perl等。
;