PHP 正则表达式
在本教程中,您将了解正则表达式的工作原理,以及如何使用它们在 PHP 中高效地执行模式匹配。
什么是正则表达式
正则表达式,通常称为"regex"或"RegExp",是一种特殊格式的文本字符串,用于在文本中查找模式。 正则表达式是当今最强大的工具之一,可用于有效和高效的文本处理和操作。 例如,可用于验证用户输入的姓名、电子邮件、电话号码等数据的格式是否正确,在文本内容中查找或替换匹配的字符串等。
PHP(5.3 及以上版本)通过其 preg_
系列函数支持 Perl 风格的正则表达式。 为什么使用 Perl 风格的正则表达式? 因为 Perl(Practical Extraction and Report Language)是第一个为正则表达式提供集成支持的主流编程语言,并且以其对正则表达式的强大支持以及非凡的文本处理和操作能力而闻名。
在深入研究正则表达式的世界之前,让我们先简要概述一下常用的 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";
// 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。 |
以下示例中的正则表达式将使用 PHP preg_grep()
函数仅显示名称数组中以字母"J"开头的那些名称:
<?php
$pattern = "/^J/";
$names = array("Jhon Carter", "Clark Kent", "John Rambo");
$matches = preg_grep($pattern, $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 开头的单词,将匹配 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 表单验证 教程。