自学内容网 自学内容网

正则表达式从入门到精通

正则表达式从入门到精通教程

这个教程会通过三个阶段(入门、进阶、精通)带你逐步学习正则表达式,附带实战练习和如何逐步编写符合需求的正则表达式。


阶段 1:入门

1. 什么是正则表达式?

正则表达式(Regular Expression, regex)是一种用于字符串匹配和处理的模式描述语言,可以用来搜索、替换和验证字符串。


2. 必备基础概念

特殊符号
  • .: 匹配任意单个字符(除换行符)。
    • 示例:a.c 匹配 abc, a1c 等。
  • []: 匹配字符集中的任意一个字符。
    • 示例:[abc] 匹配 a, b, c
  • -: 表示字符范围。
    • 示例:[a-z] 匹配所有小写字母。
  • \: 转义符,用于匹配特殊字符本身。
    • 示例:\. 匹配点号 .
量词
  • *: 匹配前面的内容 0 次或多次。
    • 示例:a* 匹配 "", a, aaa
  • +: 匹配前面的内容 1 次或多次。
    • 示例:a+ 匹配 a, aa
  • ?: 匹配前面的内容 0 次或 1 次。
    • 示例:a? 匹配 "", a
  • {n}: 匹配前面的内容正好 n 次。
    • 示例:a{3} 匹配 aaa

3. 入门实战:用正则匹配简单的格式

任务:匹配一个简单的电话号码格式
  • 示例号码:123-456-7890
  • 步骤:
    1. 分析结构:由数字、短横线组成,格式是 三位数字-三位数字-四位数字
    2. 转换为正则:\d{3}-\d{3}-\d{4}
import re

pattern = r"\d{3}-\d{3}-\d{4}"
text = "我的电话是 123-456-7890,请联系我。"
match = re.search(pattern, text)
if match:
    print("找到电话号码:", match.group())

阶段 2:进阶

1. 边界匹配

  • ^: 匹配字符串的开头。
    • 示例:^hello 匹配以 hello 开头的字符串。
  • $: 匹配字符串的结尾。
    • 示例:world$ 匹配以 world 结尾的字符串。
任务:验证字符串是否是邮箱格式
  • 示例邮箱:example@mail.com
  • 分析结构:
    • 开头是字母或数字,可能包含下划线、点号。
    • 接着是 @,后面是域名。
    • 域名部分由字母数字组成,最后是点加后缀。
  • 转换为正则:^\w+@\w+\.\w+$
pattern = r"^\w+@\w+\.\w+$"
email = "example@mail.com"
if re.match(pattern, email):
    print("合法邮箱")
else:
    print("非法邮箱")

2. 分组与引用

分组用 () 表示,引用用 \数字 指代之前的分组。

任务:匹配重复的单词
  • 示例文本:hello hello world
  • 分析需求:
    • 匹配相邻两个完全相同的单词。
    • 转换为正则:\b(\w+)\s+\1\b
pattern = r"\b(\w+)\s+\1\b"
text = "hello hello world"
match = re.search(pattern, text)
if match:
    print("找到重复单词:", match.group())

3. 实战练习:提取日期

  • 示例日期:2024-11-17
  • 分析需求:
    • 格式是 年-月-日
    • 年是四位数字,月和日是两位数字。
    • 转换为正则:(\d{4})-(\d{2})-(\d{2})
pattern = r"(\d{4})-(\d{2})-(\d{2})"
date = "今天是 2024-11-17。"
match = re.search(pattern, date)
if match:
    year, month, day = match.groups()
    print(f"提取日期: 年={year}, 月={month}, 日={day}")

阶段 3:精通

1. 贪婪与懒惰模式

  • 默认是贪婪模式:尽可能多地匹配。
  • ? 转为懒惰模式:尽可能少地匹配。
任务:匹配 HTML 标签内容
  • 示例文本:<div>Hello</div><div>World</div>
  • 贪婪模式:<.*> 会匹配整个 <div>Hello</div><div>World</div>
  • 懒惰模式:<.*?> 会分别匹配 <div></div>
pattern = r"<.*?>"
text = "<div>Hello</div><div>World</div>"
matches = re.findall(pattern, text)
print("匹配结果:", matches)

2. 高级应用:嵌套匹配

任务:匹配嵌套结构(如数学表达式)

正则表达式不能直接处理嵌套结构,但可以通过多步操作实现。

  • 示例文本:(a + (b - c))
  • 分析需求:
    • 提取匹配外层和内层括号。
  • 转换为正则:\([^()]*\)
pattern = r"\([^()]*\)"
text = "(a + (b - c)) + (d / e)"
matches = re.findall(pattern, text)
print("匹配括号内容:", matches)

3. 动态构造正则表达式

使用 re.compile 动态创建正则表达式,支持多种标志。

import re

flags = re.IGNORECASE | re.MULTILINE
pattern = re.compile(r"hello", flags)
text = "Hello world\nhello again"
matches = pattern.findall(text)
print("匹配结果:", matches)

总结:如何编写正则表达式?

  1. 分析目标结构:
  • 定位模式中的固定部分和可变部分。
  • 确定字符类型(数字、字母、特殊字符)。
  1. 逐步分解编写:
  • 从简单匹配入手,逐步增加复杂逻辑。
  1. 测试表达式:
  1. 优化与调试:
  • 使用非贪婪模式或分组引用优化结果。

附:正则表达式一览表

1. 元字符(Metacharacters)

元字符是正则表达式的核心,用于匹配特定类型的字符或定义模式。

基本元字符:

元字符作用示例匹配结果
.匹配任意单个字符(除了换行符)a.c匹配 abc, a1c
\转义符,用于匹配特殊字符本身a\.c匹配 a.c
^匹配字符串的开头^abc匹配以 abc 开头的字符串
$匹配字符串的结尾xyz$匹配以 xyz 结尾的字符串
*匹配前一个字符 0 次或多次a*匹配 "", a, aaa
+匹配前一个字符 1 次或多次a+匹配 a, aa 等,但不匹配 ""
?匹配前一个字符 0 次或 1 次a?匹配 "", a
{n}匹配前一个字符正好 n 次a{3}匹配 aaa
{n,}匹配前一个字符至少 n 次a{2,}匹配 aa, aaa
{n,m}匹配前一个字符至少 n 次,至多 m 次a{2,4}匹配 aa, aaa, aaaa

字符集和范围:

元字符作用示例匹配结果
[]匹配括号内任意字符[abc]匹配 a, b, c
[^]匹配不在括号内的字符[^abc]匹配除 a, b, c 以外的字符
-指定字符范围[a-z]匹配 az 的任意小写字母

预定义字符集:

表达式作用示例匹配结果
\d匹配任意数字(0-9)\d+匹配 123, 4
\D匹配任意非数字\D+匹配 abc, !@#
\w匹配任意单词字符(字母、数字或下划线)\w+匹配 abc, a1_
\W匹配任意非单词字符\W+匹配 @#$
\s匹配任意空白字符(空格、制表符等)\s+匹配空格、换行符等
\S匹配任意非空白字符\S+匹配 abc, 123

2. 匹配模式(Greedy vs Lazy)

正则表达式默认是贪婪模式(尽可能多地匹配),但可以通过 ? 使其变为非贪婪模式(尽可能少地匹配)。

表达式作用示例匹配结果
.*贪婪:匹配尽可能多的字符<.*>匹配整个 <html><body>
.*?非贪婪:匹配尽可能少的字符<.*?>分别匹配 <html><body>

3. 分组与引用

表达式作用示例匹配结果
()定义一个组(abc)+匹配 abc, abcabc
(?:...)非捕获组,不保存匹配结果(?:abc)+匹配但不保存组
\n引用第 n 个捕获组(a)(b)\1\2匹配 abab

4. 边界匹配

表达式作用示例匹配结果
\b匹配单词边界\bword\b匹配 word ,但不匹配 sword
\B匹配非单词边界\Bword\B匹配 sworded 中的 word

5. 标志(Flags)

标志修改正则表达式的行为:

标志作用示例
re.IGNORECASE / re.I忽略大小写re.match("abc", "ABC", re.I)
re.DOTALL / re.S. 匹配换行符re.match("a.b", "a\nb", re.S)
re.MULTILINE / re.M多行模式,^$ 匹配每一行re.match("^abc$", "abc\ndef", re.M)

6. 常见正则表达式例子

表达式匹配内容
^\d{4}-\d{2}-\d{2}$日期格式:YYYY-MM-DD
\w+@\w+\.\w+电子邮件地址
https?://\S+匹配 URL
\d{3}-\d{3}-\d{4}电话号码:123-456-7890

原文地址:https://blog.csdn.net/cgy091107/article/details/143836996

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!