PHP 正则表达式

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

什么是正则表达式

正则表达式通常称为“ regex ”或“ 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,Perl,Python等语言使用相同的符号来查找文本模式。

预定义字符类

一些字符类(例如数字,字母和空格)被频繁使用,以至于它们都有快捷方式名称。下表列出了那些预定义的字符类:

捷径它能做什么
.匹配除换行符\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";
//替换空格,换行符和制表符
echo preg_replace($pattern, $replacement, $text);
echo "<br>";
//仅替换空格
echo str_replace(" ", "-", $text);
?>
测试看看

重复量词

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

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

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

匹配两次或超过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);
 
//循环遍历$parts数组并显示子字符串
foreach($parts as $part){
    echo $part . "<br>";
}
?>
测试看看

位置锚

在某些情况下,您希望在行、词或字符串的开头或结尾进行匹配。 要做到这一点,您可以使用锚点。 两个常见的锚点是表示字符串开始的插入符号(^)和表示字符串结束的美元符号($)。

正则表达式它能做什么
^p与行首的字母p匹配。
p$与行尾的字母p匹配。

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

<?php
$pattern = "/^J/";
$names = array("Jhon Carter", "Clark Kent", "John Rambo");
$matches = preg_grep($pattern, $names);
 
//遍历$matches数组并显示匹配的名称
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开头的单词,并匹配cart, carrot, 或 cartoon,但不匹配oscar。

同样,正则表达式/car\b/匹配以模式car结尾的单词,并且匹配scar, oscar, 或  supercar,但不匹配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表单验证的教程。