正则表达式

本文最后更新于 2026年1月3日 下午

在很多题目中都用到过正则表达式,但是每次都借助ai,没有好好学习过,故写篇文章系统学习一下

正则表达式是一种用于匹配和操作文本的强大工具,它是由一系列字符和特殊字符组成的模式,用于描述要匹配的文本模式。

注:python部分根据《python编程快速上手——让繁琐工作自动化》总结,php部分由豆包ai生成

python

一个例子

1
2
3
4
5
>>>import re
>>>tel=re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')
>>>mo=tel.search('my phone number is 415-555-4242')
>>>mo.group()
415-555-4242

其中r’’用于传入原始字符串,tel是一个regex对象,mo是一个match对象

利用括号分组

1
2
3
4
5
6
7
8
9
10
11
>>>tel=re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)')
>>>mo=tel.search('my phone number is 415-555-4242')
>>>mo.group(1)
415
>>>mo.group(0)
415-555-4242
>>>mo.groups()
('415','555-4242')
>>>a,b=mo.groups()
>>>a
>>>415

管道符匹配多个分组

1
2
>>>tel=re.compile(r'Batman|Tina')
>>>tel=re.compile(r'Bat(man|mobile)')

可选匹配

符号 次数
零次或一次
* 任意次数(包括零次)
+ 一次或多次
{} 特定次数
?* 0 次或多次(非贪婪模式:尽可能少匹配)

特殊字符类元字符

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

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

  • \w 匹配任意单词字符(字母、数字、下划线),等价于 [a-zA-Z0-9_]

  • \W 匹配任意非单词字符,等价于 [^a-zA-Z0-9_]

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

  • \S 匹配任意非空白字符

字符类元字符

[] (方括号)

  • 定义字符集合,匹配其中任意一个字符
  • 示例:[aeiou] 匹配任意一个元音字母

[^] (否定字符类)

  • 匹配不在方括号中的任意字符
  • 示例:[^0-9] 匹配任意非数字字符

- (连字符)

  • 在字符类中表示范围
  • 示例:[a-z] 匹配任意小写字母

基本元字符

. (点号)

  • 匹配除换行符(\n)外的任意单个字符

    示例:a.b 匹配 “aab”, “a1b”, “a b” 等

^ (脱字符)

  • 匹配字符串的开始位置
  • 示例:^abc 匹配以 “abc” 开头的字符串

$ (美元符)

  • 匹配字符串的结束位置
  • 示例:xyz$ 匹配以 “xyz” 结尾的字符串

\ (反斜杠)

  • 转义字符,使后面的字符失去特殊含义
  • 示例:\. 匹配实际的点号而不是任意字符

PHP

一个例子

1
preg_match('/sys.*nb/is',$xdmtql)

在正则表达式/sys.*nb/is中,//是定界符,,其中 i 表示忽略大小写,s 表示单行模式(使 . 匹配包括换行符在内的所有字符),那么它就匹配sys开头nb结尾中间有任意字符的字符串

定界符

PHP 中正则表达式必须用定界符包裹,常用定界符为 /,也可使用 #~ 等(当表达式中包含 / 时,用其他定界符可避免转义,更简洁)。

示例:/abc/#a/b/c#~hello~

最小匹配单位

  • 普通字符:a-z、A-Z、0-9 等,匹配自身。示例:/test/ 匹配字符串中的 “test”。
  • 特殊字符:需转义(加 \),如 .*+?^$()[]{} 等。示例:/a\.b/ 匹配 “a.b”,而非 “aab”、”acb” 等。
  • 元字符(预定义原子):
    • \d:匹配数字,等价于 [0-9]
    • \D:匹配非数字,等价于 [^0-9]
    • \w:匹配字母、数字、下划线,等价于 [a-zA-Z0-9_]
    • \W:匹配非字母、数字、下划线,等价于 [^a-zA-Z0-9_]
    • \s:匹配空白字符(空格、制表符 \t、换行符 \n 等)
    • \S:匹配非空白字符
    • \b:单词边界(匹配单词开头或结尾,如 \btest\b 匹配 “test” 单词,不匹配 “test123” 或 “123test”)
    • \B:非单词边界

量词(匹配次数)

  • *:匹配前面的原子 0 次或多次(贪婪匹配)。示例:/ab*c/ 可匹配 “ac”、”abc”、”abbc” 等。
  • +:匹配前面的原子 1 次或多次(贪婪匹配)。示例:/ab+c/ 可匹配 “abc”、”abbc”,不匹配 “ac”。
  • ?:匹配前面的原子 0 次或 1 次(贪婪匹配)。示例:/ab?c/ 可匹配 “ac”、”abc”。
  • {n}:匹配前面的原子恰好 n 次。示例:/ab{3}c/ 匹配 “abbbc”。
  • {n,}:匹配前面的原子至少 n 次。示例:/ab{2,}c/ 可匹配 “abbc”、”abbbc” 等。
  • {n,m}:匹配前面的原子 n 到 m 次(n ≤ 次数 ≤ m)。示例:/ab{1,3}c/ 可匹配 “abc”、”abbc”、”abbbc”。
  • 非贪婪匹配:在量词后加 ?,即 *?+???{n,m}?,匹配尽可能少的次数。示例:/a.*?b/ 匹配 “aab” 中的 “aab”(贪婪匹配 a.*b 会匹配整个字符串,若字符串为 “aabab”)。

边界符

  • ^:匹配字符串开头(多行模式下匹配每行开头)。示例:/^test/ 匹配 “testabc”,不匹配 “abctest”。
  • $:匹配字符串结尾(多行模式下匹配每行结尾)。示例:/test$/ 匹配 “abctest”,不匹配 “testabc”。
  • ^$:匹配空字符串(或仅含空白字符的字符串,需结合 \s*,即 /^\s*$/)。

选择符与分组

  • 选择符 |:匹配多个表达式中的一个。示例:/test|demo/ 匹配 “test” 或 “demo”。
  • 分组 ()
    • 将多个原子视为一个整体。示例:/(ab)+/ 匹配 “ab”、”abab” 等。
    • 捕获分组:默认捕获分组内容,可通过反向引用(\1\2…)使用。示例:/(\w+)\s+\1/ 匹配重复的单词,如 “test test”(\1 引用第一个分组匹配的内容)。
    • 非捕获分组:(?:表达式),仅分组不捕获,无法反向引用。示例:/(?:ab)+/ 匹配 “abab”,但不能用 \1 引用 “ab”。

字符类

[] 定义,匹配其中任意一个原子,可简化原子写法。

  • 普通字符类:[abc] 匹配 “a”、”b” 或 “c”;[a-z] 匹配任意小写字母;[A-Z0-9] 匹配任意大写字母或数字。
  • 否定字符类:[^abc] 匹配除 “a”、”b”、”c” 外的任意字符。
  • 特殊说明:[] 内部部分特殊字符无需转义,如 <code id=”118.”、)、”-“(中间)需转义或特殊处理。示例:[a\.b] 匹配 “a”、”.” 或 “b”;[a-b-c] 匹配 “a”、”b”、”c” 或 “-“。

常用函数

preg_match()

功能:执行一次正则匹配,返回匹配次数(0 次或 1 次,因为只匹配一次),不匹配返回 0,错误返回 FALSE。

语法:int preg_match(string $pattern, string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]])

  • $pattern:正则表达式(带定界符)。
  • $subject:待匹配的字符串。
  • $matches:可选参数,存储匹配结果。$matches[0] 是完整匹配结果,$matches[1]$matches[2]… 是捕获分组的结果。
  • $flags:可选参数,常用 PREG_OFFSET_CAPTURE,表示同时返回匹配结果的起始位置。
  • $offset:可选参数,指定从 $subject 的哪个位置开始匹配。

示例:

1
2
3
4
5
6
7
8
9
<?php
$str = "Hello, PHP regex!";
$pattern = "/PHP/";
if (preg_match($pattern, $str, $matches)) {
echo "匹配成功:" . $matches[0]; // 输出:匹配成功:PHP
} else {
echo "匹配失败";
}
?>

preg_replace()

功能:执行正则表达式的搜索和替换,返回替换后的字符串,若没有匹配项则返回原字符串。

语法:mixed preg_replace(mixed $pattern, mixed $replacement, mixed $subject [, int $limit = -1 [, int &$count ]])

  • $pattern:正则表达式(可传入数组,多个正则)。
  • $replacement:替换后的内容(可传入数组,与 $pattern 对应;可使用 \1\2… 引用捕获分组,或 $1$2…)。
  • $subject:待替换的字符串(可传入数组,多个字符串)。
  • $limit:可选参数,指定最大替换次数,默认 -1(无限制)。
  • $count:可选参数,存储实际替换的次数。

示例 1:基础替换

1
2
3
4
5
6
7
<?php
$str = "Hello, 2024! Hello, PHP!";
$pattern = "/Hello/";
$replacement = "Hi";
$result = preg_replace($pattern, $replacement, $str);
echo $result; // 输出:Hi, 2024! Hi, PHP!
?>

示例 2:引用分组替换(格式化日期)

1
2
3
4
5
6
7
<?php
$str = "2024-05-20";
$pattern = "/(\d{4})-(\d{2})-(\d{2})/";
$replacement = "\2/\3/\1"; // 或 "$2/$3/$1"
$result = preg_replace($pattern, $replacement, $str);
echo $result; // 输出:05/20/2024
?>

正则表达式
https://www.sunynov.top/2025/12/18/正则表达式/
作者
suny
发布于
2025年12月18日
许可协议