PHP中使用正则表达式主要依赖PCRE库和preg_系列函数,通过定界符、修饰符和元字符实现字符串的匹配、查找、替换与分割,结合捕获组、非捕获组及反向引用可高效提取和处理数据,处理多字节字符时需添加u修饰符以支持UTF-8编码。

PHP中使用正则表达式,主要是通过内置的
preg_
在PHP中,处理正则表达式主要依赖于PCRE(Perl Compatible Regular Expressions)库,并通过一系列以
preg_
preg_match
preg_replace
str_replace
substr
首先,你需要定义一个正则表达式模式。这个模式通常由定界符包围,例如
/pattern/
1. 匹配与查找:preg_match()
preg_match_all()
立即学习“PHP免费学习笔记(深入)”;
preg_match(string $pattern, string $subject, array &$matches = null, int $flags = 0, int $offset = 0)
1
0
false
$matches
$text = "我的电话是 138-1234-5678,她的电话是 139-8765-4321。";
$pattern = '/(\d{3}-\d{4}-\d{4})/'; // 匹配电话号码
if (preg_match($pattern, $text, $matches)) {
    echo "找到第一个电话号码: " . $matches[1] . "\n";
    // $matches[0] 包含完整匹配的字符串
    // $matches[1] 包含第一个捕获组的内容
}preg_match_all(string $pattern, string $subject, array &$matches, int $flags = PREG_PATTERN_ORDER, int $offset = 0)
$text = "我的电话是 138-1234-5678,她的电话是 139-8765-4321。";
$pattern = '/(\d{3}-\d{4}-\d{4})/';
preg_match_all($pattern, $text, $allMatches);
echo "所有电话号码:\n";
foreach ($allMatches[1] as $phone) {
    echo $phone . "\n";
}
// $allMatches[0] 是所有完整匹配的数组
// $allMatches[1] 是所有第一个捕获组的数组2. 替换:preg_replace()
preg_replace(string|array $pattern, string|array $replacement, string|array $subject, int $limit = -1, int &$count = null)
$text = "Hello, World! This is a test string."; $pattern = '/(World|test)/'; $replacement = 'PHP'; $newText = preg_replace($pattern, $replacement, $text); echo "替换后的文本: " . $newText . "\n"; // 输出: Hello, PHP! This is a PHP string. // 结合反向引用 $name = "Doe, John"; $pattern = '/(\w+), (\w+)/'; // 匹配 "姓, 名" $replacement = '$2 $1'; // 替换成 "名 姓" $formattedName = preg_replace($pattern, $replacement, $name); echo "格式化后的名字: " . $formattedName . "\n"; // 输出: John Doe
3. 分割:preg_split()
preg_split(string $pattern, string $subject, int $limit = -1, int $flags = 0)
$csvLine = "apple,banana , orange;grape";
$pattern = '/[,;]\s*/'; // 匹配逗号或分号,后面跟着零个或多个空格
$fruits = preg_split($pattern, $csvLine);
print_r($fruits);
/*
Array
(
    [0] => apple
    [1] => banana
    [2] => orange
    [3] => grape
)
*/这些函数构成了PHP正则表达式使用的核心,理解它们如何与正则表达式语法结合,是高效处理字符串的关键。
在使用PHP正则表达式时,理解定界符、修饰符(也叫模式修正符)和各种元字符是基础,也是我个人在初期学习时常犯错的地方。
定界符 (Delimiters) 正则表达式模式必须被定界符包围。最常见的是斜杠
/
#
~
!
为什么需要定界符? 它告诉PHP哪里是模式的开始,哪里是模式的结束,以及模式后面可能跟的修饰符。
避坑点: 如果你的模式本身包含定界符,比如你要匹配URL路径中的斜杠
/
#
\/
// 匹配 /path/to/resource // 错误示范(需要转义,但容易混淆): // $pattern = '/\/path\/to\/resource/'; // 推荐做法(更换定界符): $pattern = '#/path/to/resource#'; // 或者 $pattern = '~^/user/(\d+)/profile$~'; // 匹配 /user/123/profile
修饰符 (Modifiers/Flags) 这些是紧跟在模式定界符后面的单个字母,用于改变匹配行为。
i
preg_match('/php/i', 'PHP is great', $matches); // 匹配成功s
.
.
$text = "Line 1\nLine 2";
preg_match('/Line.Line/s', $text, $matches); // 匹配成功m
^
$
$text = "Line 1\nLine 2";
preg_match_all('/^Line/m', $text, $matches); // 匹配两行U
$html = "<div><span>Text</span><span>More Text</span></div>";
// 贪婪模式 (默认): 匹配整个 <div>...</div>
preg_match('/<div>.*<\/div>/', $html, $matches);
echo $matches[0] . "\n"; // 输出: <div><span>Text</span><span>More Text</span></div>
// 非贪婪模式: 只匹配第一个 <div>...</div>
preg_match('/<div>.*?<\/div>/U', $html, $matches); // 或者直接用 `.*?`
echo $matches[0] . "\n"; // 输出: <div><span>Text</span><span>More Text</span></div>U
常用元字符 (Metacharacters) 这些特殊字符赋予正则表达式强大的匹配能力。
.
s
+
?
{n}n
{n,}n
{n,m}n
m
[]
[abc]
[0-9]
[a-zA-Z]
[^]
[^0-9]
()
|
|
cat|dog
^
m
$
m
\
\.
\d
[0-9]
\d
[^0-9]
\w
[a-zA-Z0-9_]
\w
\s
\s
\b
\b
理解并熟练运用这些元字符,是编写高效、准确正则表达式的关键。我记得有一次,在处理一个日志文件时,需要提取特定错误码,如果不是对
\d+
\b
在实际开发中,我们不仅仅是想知道一个模式是否匹配,更重要的是从匹配的文本中提取出我们需要的数据。这时候,捕获组、非捕获组和反向引用就显得尤为重要。它们是正则表达式中非常强大的特性,我个人在处理复杂数据提取任务时,几乎离不开它们。
捕获组 ()
()
preg_match
$matches
preg_replace
当你使用
preg_match
preg_match_all
$matches
$matches[0]
$matches[1]
$matches[2]
示例:提取日期和时间 假设我们有一个日志条目:"2023-10-27 14:35:01 - User login successful.",我们想提取日期和时间。
$logEntry = "2023-10-27 14:35:01 - User login successful.";
$pattern = '/^(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2}:\d{2})/'; // 两个捕获组,分别捕获日期和时间
if (preg_match($pattern, $logEntry, $matches)) {
    echo "日期: " . $matches[1] . "\n"; // 输出: 2023-10-27
    echo "时间: " . $matches[2] . "\n"; // 输出: 14:35:01
}这里,
(\d{4}-\d{2}-\d{2})(\d{2}:\d{2}:\d{2})非捕获组 (?:...)
(?:...)
$matches
$matches
示例:分组但不捕获 假设我们要匹配 "cat" 或 "dog",后面跟着 "food",但我们只关心 "food" 前面的动物。
$text = "I like cat food and dog food.";
$pattern = '/(?:cat|dog) food/'; // (?:cat|dog) 是非捕获组
preg_match_all($pattern, $text, $matches);
print_r($matches);
/*
Array
(
    [0] => Array
        (
            [0] => cat food
            [1] => dog food
        )
)
*/
// 注意:$matches 中只有 $matches[0],没有 $matches[1] 来捕获 'cat' 或 'dog'。
// 如果用捕获组,则会有 $matches[1]
// $pattern_capture = '/(cat|dog) food/';
// preg_match_all($pattern_capture, $text, $matches_capture);
// print_r($matches_capture);
/*
Array
(
    [0] => Array ( [0] => cat food [1] => dog food )
    [1] => Array ( [0] => cat [1] => dog )
)
*/可以看到,使用非捕获组后,
$matches
反向引用 \n
$n
\1
\2
$1
$2
示例:模式中的反向引用 匹配重复的单词,比如 "hello hello"。
$text = "This is a test test string with repeated words.";
$pattern = '/\b(\w+)\s+\1\b/i'; // \1 引用第一个捕获组 (\w+) 的内容
if (preg_match($pattern, $text, $matches)) {
    echo "找到重复单词: " . $matches[1] . "\n"; // 输出: test
}这里
\1
示例:替换字符串中的反向引用 我记得有一次需要把
firstname lastname
lastname, firstname
$name = "John Doe"; $pattern = '/(\w+)\s+(\w+)/'; // 第一个捕获组是名,第二个是姓 $replacement = '$2, $1'; // 使用 $2 (姓) 和 $1 (名) 进行替换 $formattedName = preg_replace($pattern, $replacement, $name); echo "格式化后的名字: " . $formattedName . "\n"; // 输出: Doe, John
反向引用在数据格式转换、字符串重排等方面提供了极大的便利和灵活性。掌握这些概念,能让你在处理复杂文本数据时事半功倍。
在处理包含中文、日文、韩文或其他Unicode字符的字符串时,PHP的正则表达式如果不加注意,很容易遇到编码问题。我曾经在一个处理用户评论的系统里,因为没加
U
编码问题背景 PHP的
preg_
.
.
以上就是PHP正则表达式怎么用_正则表达式匹配详细教程的详细内容,更多请关注php中文网其它相关文章!
                        
                        PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
                
                                
                                
                                
                                
                                
                                Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号