正则表达式实例教程笔记

正则表达式(Regular Expression)是一种强大的文本处理工具,用于匹配、查找、替换和验证字符串。下面我将通过实例来讲解正则表达式的基本语法和常见用法。

1. 基本匹配

正则表达式由普通字符(例如字母、数字)和特殊字符(称为元字符)组成。最简单的正则表达式就是普通字符,例如:

  • 正则表达式 hello 会匹配字符串中出现的第一个”hello”。

2. 元字符

元字符是正则表达式中具有特殊意义的字符。常见的元字符包括:

  • . 匹配任意单个字符(除了换行符)

  • ^ 匹配字符串的开始

  • $ 匹配字符串的结束

  • * 匹配前面的子表达式零次或多次

  • + 匹配前面的子表达式一次或多次

  • ? 匹配前面的子表达式零次或一次

  • {n} 匹配前面的子表达式恰好n次

  • {n,} 匹配前面的子表达式至少n次

  • {n,m} 匹配前面的子表达式至少n次,至多m次

  • [] 字符集合,匹配所包含的任意一个字符

  • | 或,匹配两者之一

  • () 分组,将多个字符组合成一个单元,并可捕获匹配的文本

3. 转义

如果你想要匹配元字符本身,需要使用反斜杠\进行转义。例如,匹配点号.,需要使用\.

4. 字符类

用方括号[]表示,匹配括号内的任意一个字符。

  • [abc] 匹配a、b或c

  • [a-z] 匹配任意小写字母

  • [0-9] 匹配任意数字

  • [^abc] 匹配除了a、b、c之外的任意字符(在字符类中的^表示否定)

5. 预定义字符类

  • \d 匹配数字,等价于[0-9]

  • \D 匹配非数字,等价于[^0-9]

  • \w 匹配字母、数字、下划线,等价于[A-Za-z0-9_]

  • \W 匹配非字母、数字、下划线

  • \s 匹配空白字符(空格、制表符、换行符等)

  • \S 匹配非空白字符

6. 实例

实例1:匹配邮箱地址

假设我们要匹配一个简单的邮箱地址,格式为:用户名@域名.后缀

  • 用户名:可以包含字母、数字、点、下划线、减号,且不能以点开头或结尾,不能连续两个点。

  • 域名:可以包含字母、数字、减号,且不能以减号开头或结尾。

  • 后缀:一般为2-5个字母。

正则表达式:^[a-zA-Z0-9]+([._-]?[a-zA-Z0-9]+)*@[a-zA-Z0-9]+(-?[a-zA-Z0-9]+)*(\.[a-zA-Z]{2,5})+$

解释:

  • ^ 表示字符串开始

  • [a-zA-Z0-9]+ 至少一个字母或数字开头

  • ([._-]?[a-zA-Z0-9]+)* 接下来可以是零个或多个以下结构:一个可选的点、下划线或减号,然后至少一个字母或数字。注意这里我们使用了?表示前面的字符可选,这样允许中间有点、下划线或减号,但不会连续两个点。

  • @ 匹配字面量@

  • [a-zA-Z0-9]+ 域名部分以至少一个字母或数字开头

  • (-?[a-zA-Z0-9]+)* 之后可以跟零个或多个:一个可选的减号然后至少一个字母或数字,这样确保域名中可以有减号但不能连续减号或开头结尾有减号。

  • (\.[a-zA-Z]{2,5})+ 匹配一个点后跟2到5个字母,这个整体可以出现一次或多次(例如:.com、.co.uk

  • $ 字符串结束

注意:这只是一个简单的示例,实际邮箱地址更复杂,此表达式可能不覆盖所有情况。

实例2:匹配URL

假设我们要匹配HTTP/HTTPS的URL。

正则表达式:^https?://[^\s/$.?#].[^\s]*$

解释:

  • ^https? 匹配http或https,s可选

  • :// 匹配字面量

  • [^\s/$.?#] 匹配一个不是空白字符、不是/、$、.、?、#的字符,确保域名部分不以这些字符开头

  • [^\s]* 匹配任意非空白字符,直到字符串结束

实例3:匹配日期(YYYY-MM-DD)

正则表达式:^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$

解释:

  • ^\d{4} 匹配4位数字的年份

  • - 匹配字面量减号

  • (0[1-9]|1[0-2]) 匹配月份,01-09或10-12

  • - 匹配字面量减号

  • (0[1-9]|[12][0-9]|3[01]) 匹配日期,01-09、10-29、30-31

实例4:匹配手机号码(以中国手机为例)

中国手机号码:1开头,第二位是3-9,后面9位数字。

正则表达式:^1[3-9]\d{9}$

实例5:替换HTML标签

如果我们想移除字符串中所有的HTML标签,可以使用替换功能,将匹配到的标签替换为空字符串。

正则表达式:<[^>]+>

解释:匹配以<开头,后面跟着一个或多个不是>的字符,然后以>结尾。

基本语法

1. 字面量匹配

hello        # 匹配 "hello"
test123      # 匹配 "test123"

2. 特殊字符转义

\.           # 匹配点号字符
\\           # 匹配反斜杠
\$           # 匹配美元符号

常用元字符

元字符 说明 示例
. 匹配任意单个字符 a.c 匹配 “abc”, “a c”, “a-c”
^ 匹配字符串开始 ^Hello 匹配以 “Hello” 开头的字符串
$ 匹配字符串结束 end$ 匹配以 “end” 结尾的字符串
\d 匹配数字 \d\d 匹配 “12”, “45” 等
\w 匹配字母、数字、下划线 \w+ 匹配单词
\s 匹配空白字符 \s+ 匹配空格、制表符等

量词

量词 说明 示例
* 0次或多次 ab*c 匹配 “ac”, “abc”, “abbc”
+ 1次或多次 ab+c 匹配 “abc”, “abbc”
? 0次或1次 colou?r 匹配 “color” 或 “colour”
{n} 恰好n次 a{3} 匹配 “aaa”
{n,} 至少n次 a{2,} 匹配 “aa”, “aaa” 等
{n,m} n到m次 a{2,4} 匹配 “aa”, “aaa”, “aaaa”

字符类

1. 自定义字符类

[aeiou]      # 匹配任意元音字母
[0-9]        # 匹配任意数字
[a-zA-Z]     # 匹配任意字母

2. 排除字符类

[^aeiou]     # 匹配非元音字母
[^0-9]       # 匹配非数字字符

分组和捕获

1. 基本分组

(abc)+       # 匹配 "abc", "abcabc" 等

2. 非捕获分组

(?:abc)+     # 匹配但不捕获分组

3. 命名捕获组

(?<year>\d{4})-(?<month>\d{2})  # 命名捕获年月

实际应用示例

1. 邮箱验证

^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

示例匹配:

2. 手机号码验证

^1[3-9]\d{9}$

示例匹配:

  • 13812345678

  • 15987654321

3. URL 提取

https?://[^\s/$.?#].[^\s]*

示例匹配:

4. 日期匹配

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

示例匹配:

  • 2023-12-25

  • 1990-01-01

5. HTML 标签提取

<([a-z][a-z0-9]*)[^>]*>(.*?)</\1>

示例匹配:

  • <div>内容</div>

  • <p class="text">段落</p>

6. 密码强度验证

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$

要求:

  • 至少8个字符

  • 包含大小写字母

  • 包含数字

  • 包含特殊字符

不同语言中的使用

Python 示例

# 匹配邮箱
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
email = "user@example.com"

if re.match(pattern, email):
    print("邮箱格式正确")

# 提取所有数字
text = "价格是123元,重量是45公斤"
numbers = re.findall(r'\d+', text)
print(numbers)  # ['123', '45']

JavaScript 示例

// 验证手机号码
const phonePattern = /^1[3-9]\d{9}$/;
const phone = "13812345678";

if (phonePattern.test(phone)) {
    console.log("手机号码格式正确");
}

// 替换文本
const text = "今天是2023-12-25";
const newText = text.replace(/(\d{4})-(\d{2})-(\d{2})/, "$1年$2月$3日");
console.log(newText);  // "今天是2023年12月25日"

Java 示例

import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        // 验证邮箱
        String emailPattern = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
        String email = "user@example.com";
        
        if (email.matches(emailPattern)) {
            System.out.println("邮箱格式正确");
        }
        
        // 提取URL
        String text = "访问 https://example.com 获取更多信息";
        Pattern urlPattern = Pattern.compile("https?://[^\\s/$.?#].[^\\s]*");
        Matcher matcher = urlPattern.matcher(text);
        
        while (matcher.find()) {
            System.out.println("找到URL: " + matcher.group());
        }
    }
}

实用技巧

  1. 使用在线测试工具:如 regex101.com 测试和调试正则表达式

  2. 注释复杂表达式:使用 (?#注释) 或 x 模式添加注释

  3. 性能优化:避免过度使用回溯,尽量使用具体字符类

  4. 测试边界情况:确保正则表达式处理各种边界情况

这个教程涵盖了正则表达式的基础知识和常见应用场景。建议在实际使用中多加练习,逐步掌握这个强大的文本处理工具!

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部
×
问题求助