PHP 正则表达式

在本教程中,你将学习正则表达式如何工作,以及如何使用它们在 PHP 中以有效的方式执行模式匹配。

什么是正则表达式

正则表达式,通常称为** Regular Express** 或 RegExp,是一种特殊格式的文本字符串,用于查找文本中的模式。正则表达式是当今最有效和最有效的文本处理和操作的强大工具之一。例如,它可用于验证用户输入的数据格式(即姓名,电子邮件,电话号码等)是否正确,在文本内容中查找或替换匹配的字符串,等等。

PHP(5.3 及以上版本)通过其 preg_ 函数系列支持 Perl 样式的正则表达式。为什么 Perl 样式正则表达式? 因为 Perl 是第一种为正则表达式提供集成支持的主流编程语言,因其对正则表达式及其非凡的文本处理和操作功能的强大支持而众所周知。

在深入研究正则表达式的世界之前,我们先简单概述一下常用的 PHP 内置模式匹配函数。

功能 它能做什么
preg_match() 执行正则表达式匹配。
preg_match_all 执行全局正则表达式匹配。
preg_replace() 执行正则表达式搜索和替换。
preg_grep() 返回与模式匹配的输入数组的元素。
preg_split() 使用正则表达式将字符串拆分为子字符串。
preg_quote() 引用字符串中的正则表达式字符。

注意: PHP preg_match() 函数在找到第一个匹配项后停止搜索,而 preg_match_all() 函数继续搜索直到字符串结尾并找到所有可能的匹配项,而不是在第一个匹配项时停止。

正则表达式语法

正则表达式语法包括使用特殊字符(不要与 HTML 特殊字符 混淆)。在正则表达式中赋予特殊含义的字符是: . * ? + [ ] ( ) { } ^ $ | \ 。每当你想要按字面意思使用它们时,你需要反斜杠这些字符。例如,如果你想匹配 .,你必须写 \. 。所有其他字符自动采用其字面含义。

以下部分描述了可用于制定模式的各种选项:

字符类

围绕字符图案的方括号称为字符类,例如 [abc] 。字符类始终匹配指定字符列表中的单个字符,这意味着表达式 [abc] 仅匹配 a,b 或 c 字符。

还可以定义否定字符类,以匹配除括号中包含的字符之外的任何字符。通过在开始括号后面放置一个插入符号(^) 来定义一个否定的字符类,就像这样 [^abc]

你还可以使用字符类中的 - 字符来定义一系列字符,例如 [0-9] 。我们来看一些字符类的例子:

正则表达式 它能做什么
[abc] 匹配字符 a,b 或 c 中的任何一个。
[^abc] 匹配除 a,b 或 c 之外的任何一个字符。
[a-z] 匹配从小写 a 到小写 z 的任何一个字符。
[A-Z] 匹配从大写 a 到大写 z 的任何一个字符。
[a-Z] 匹配从小写字母 a 到大写字母 Z 的任何一个字符。
[0-9] 匹配 0 到 9 之间的单个数字。
[a-z0-9] 匹配 a 和 z 之间或 0 到 9 之间的单个字符。

以下示例将向你展示如何使用正则表达式和 PHP preg_match() 函数查找字符串中是否存在模式 :

<?php
$pattern = "/ca[kf]e/";
$text = "He was eating cake in the cafe.";
if(preg_match($pattern, $text)){
    echo "Match found!";
} else{
    echo "Match not found.";
}
?>

同样,你可以使用该 preg_match_all() 函数查找字符串中的所有匹配项:

<?php
$pattern = "/ca[kf]e/";
$text = "He was eating cake in the cafe.";
$matches = preg_match_all($pattern, $text, $array);
echo $matches . " matches were found.";
?>

提示: 正则表达式不是 PHP 独有的。诸如 Java,PerlPython等语言使用相同的表示法来查找文本中的模式。

预定义的字符类

一些字符类(如数字,字母和空格)经常使用,因此有快捷方式名称。下表列出了这些预定义的字符类:

捷径 它能做什么
. 匹配除换行符 \n 之外的任何单个字符。
\d 匹配任何数字字符。与 [0-9] 一样
\D 匹配任何非数字字符。与 [^0-9] 一样
\s 匹配任何空白字符(空格,制表符,换行符或回车符)。与 [ \t\n\r] 一样
\S 匹配任何非空白字符。与 [^ \t\n\r] 一样
\w 匹配任何单词字符(定义为 a 到 z,A 到 Z,0 到 9 和下划线)。与 [a-zA-Z_0-9] 一样
\W 匹配任何非单词字符。与 [^a-zA-Z_0-9] 一样

以下示例将向你展示如何使用正则表达式和 PHP preg_replace() 函数在字符串中使用连字符字符查找和替换空格 :

<?php
$pattern = "/\s/";
$replacement = "-";
$text = "Earth revolves around\nthe\tSun";
// Replace spaces, newlines and tabs
echo preg_replace($pattern, $replacement, $text);
echo "<br>";
// Replace only spaces
echo str_replace(" ", "-", $text);
?>

重复量词

在上一节中,我们学习了如何以各种方式匹配单个字符。但是如果你想匹配多个字符怎么办? 例如,假设你要查找包含字母 p 的一次或多次的单词,或包含至少两个 p 的单词,依此类推。这就是量词开始发挥作用的地方。使用量词,你可以指定正则表达式中的字符应匹配的次数。

下表列出了量化特定模式的各种方法:

正则表达式 它能做什么
p+ 匹配字母 p 的一次或多次出现。
p* 匹配字母 p 的零次或多次出现。
p? 匹配字母 p 的零次或一次出现。
p{2} 匹配恰好两次出现的字母 p。
p{2,3} 匹配至少两次出现的字母 p,但不超过三次出现的字母 p。
p{2,} 匹配字母 p 的两次或多次出现。
p{,3} 匹配最多三次出现的字母 p

以下示例中的正则表达式将使用 PHP preg_split() 函数以逗号,逗号序列,空格或其组合拆分字符串 :

<?php
$pattern = "/[\s,]+/";
$text = "My favourite colors are red, green and blue";
$parts = preg_split($pattern, $text);
 
// Loop through parts array and display substrings
foreach($parts as $part){
    echo $part . "<br>";
}
?>

位置限定锚

在某些情况下,你希望在行,单词或字符串的开头或结尾处进行匹配。为此,你可以使用锚点。两个常见的锚是 ^ ,它代表字符串的开头,而 $ 符号代表字符串的结尾。

正则表达式 它能做什么
^p 匹配一行开头的字母 p。
p$ 匹配一行末尾的字母 p。

以下示例中的正则表达式将仅显示 names 数组中使用 PHP preg_grep() 函数以字母 J 开头的名称 :

<?php
$pattern = "/^J/";
$names = array("Jhon Carter", "Clark Kent", "John Rambo");
$matches = preg_grep($pattern, $names);
 
// Loop through matches array and display matched names
foreach($matches as $match){
    echo $match . "<br>";
}
?>

模式修饰符

模式修饰符允许你控制模式匹配的处理方式。模式修饰符直接放在正则表达式之后,例如,如果要以不区分大小写的方式搜索模式,可以使用 i 修饰符,如下所示: /pattern/i 。下表列出了一些最常用的模式修饰符。

修改 它能做什么
i 使匹配不区分大小写的方式。
m 更改 ^$ 的行为来匹配新行边界(即多行字符串中每行的开头或结尾),而不是字符串边界。
g 执行全局匹配,即查找所有匹配项。
o 仅对表达式求值一次。
s 更改 . 的行为以匹配所有字符,包括换行符。
x 允许你在正则表达式中使用空格和注释以便清晰。

以下示例将向你展示如何使用 i 修饰符和 PHP preg_match_all() 函数执行全局不区分大小写的搜索。

<?php
$pattern = "/color/i";
$text = "Color red is more visible than color blue in daylight.";
$matches = preg_match_all($pattern, $text, $array);
echo $matches . " matches were found.";
?>

类似地,以下示例显示如何使用 ^ 锚点和 m 修饰符与 PHP preg_match_all() 函数在多行字符串中的每一行的开头匹配。

<?php
$pattern = "/^color/im";
$text = "Color red is more visible than \ncolor blue in daylight.";
$matches = preg_match_all($pattern, $text, $array);
echo $matches . " matches were found.";
?>

词边界

单词边界字符(\b)可帮助你搜索以模式开头和/或结尾的单词。例如,正则表达式 /\bcar/ 匹配以模式 car 开头的单词,并且匹配 cartcarrotcartoon,但不匹配 oscar

同样,正则表达式 /car\b/ 匹配以模式 car 结尾的单词,并且匹配 scaroscarsupercar,但不匹配 cart。同样, /\bcar\b/ 匹配以模式 car 开头和结尾的单词,并且只匹配单词 car

以下示例将突出以粗体显示以 car 开头的单词:

<?php
$pattern = '/\bcar\w*/';
$replacement = '<b>$0</b>';
$text = 'Words begining with car: cart, carrot, cartoon. Words ending with car: scar, oscar, supercar.';
echo preg_replace($pattern, $replacement, $text);
?>

我们希望你已了解正则表达式的基础知识。要了解如何使用正则表达式验证表单数据,请查看有关 [PHP 表单验证]/tutorial/php/php-form-validation/) 的教程。