原文链接: Getting Started with PHP Regular Expressions
Last-Modified: 2019年5月10日16:23:19译者注:
本文是面向0正则基础的phper, 很多正则的高级使用都没有涉及到, 仅仅是一份简单的入门.
对于有基础的, 可直接查看本文末尾的正则表达式语法快速一览表(图) (不涉及修饰符)
译者追加 - 语法速览表
1. 什么是正则表达式
正则表达式(regex 或 regexp)的主要目的在于有效地搜索给定文本中的模式. 这些搜索模式使用正则表达式解析器理解的特殊格式编写。
正则表达式源自Unix系统中一个名为grep的程序,该程序是用于帮助用户处理字符串和操作文本。 通过遵循一些基本规则,我们可以创建非常复杂的搜索模式。
例如,你被赋予一项任务: 检查电子邮件或电话号码是否具有正确的格式。通过使用一些简单的命令,这些问题可以通过正则表达式轻松解决。 正则语法初学时并不那么简单,但是一旦你学会了它,你就会意识到你可以轻松地进行复杂搜索,只需键入简短的字符就可以从不同的角度处理问题。
2. Perl兼容的正则表达式
PHP已经实现了很多使用不同解析引擎的正则函数。PHP中主要有两个正则解析器,一个称为POSIX,另一个称为PCRE(Perl Compatible Regular Expression, Perl兼容正则表达式)。
POSIX的PHP函数前缀是 ereg_
。自从PHP 5.3发布后,这个引擎已被弃用,但让我们来看看更优,更快的PCRE引擎。
在PHP中,每个PCRE函数都以 preg_
开头,例如 preg_match 或 preg_replace。您可以阅读PHP文档中的完整功能列表。
3. 基础语法
要使用正则表达式,你首先需要学习语法。该语法包含一系列字母,数字,点,连字符和特殊符号,我们可以使用不同的括号将它们组合在一起。
在PHP中,每个正则表达式模式都是使用符合 Perl 格式的字符串。在 Perl 中,在正斜杠之间写入正则表达式模式,例如 /hello/
。在PHP中则是一个字符串 '/hello/'
。
现在,让我们看看一些运算符,它们是正则表达式的基本构建块。
语法 | 说明 | |
---|---|---|
^ | ^ 标志着模式的开始,尽管在某些情况下它可以省略 | |
$ | 与 ^ 符号对应,$ 符号标志着搜索模式的结束 | |
. | 匹配任何单个字符 | |
? | 它将匹配前面的模式 0 或 1 次 | |
+ | 它将匹配前面的模式 1 或 更多 次 | |
* | 它将匹配前面的模式 0 或 更多次 | |
\ | 布尔 或 | |
– | 匹配范围内的元素 | |
() | 将不同的模式元素组合在一起 | |
[] | 匹配中括号之间的任何单个字符 | |
{min, max} | 它用于匹配确切的字符数 | |
d | 匹配任何单个数字 | |
D | 匹配任何单个非数字 | |
w | 匹配单词字符, 包括下划线 _ | |
W | 匹配任何非单词字符 | |
s | 匹配空白符 |
作为PHP中的一个补充,使用简单的斜杠 \
来转义正斜杠字符。示例:'/he\/llo/'
为了简要了解如何使用这些运算符,让我们看一些示例:
示例 | 说明 | |
---|---|---|
'/hello/' |
匹配单词 hello |
|
'/^hello/' |
匹配处于字符串开头的 hello . 可能的匹配比如 hello , helloworld , 但不会匹配 worldhello |
|
'/hello$/' |
匹配处于字符串结尾的 hello |
|
'/he.o/' |
匹配任何位于 he 和 o 的任何字符, 比如 helo , helo , heyo , 但不会匹配 hello |
|
'/(he)?llo/' |
匹配如 llo 或 hello |
|
'/(hello)+/' |
匹配 hello 一次或多次, 如 hello ,hellohello |
|
'/(he)*llo/' |
匹配 llo , hello , hehello , 但不会匹配 hellooo |
|
`'/hello\ | world/'` | 匹配单词 hello 或 world |
'/[A-Z]/' |
匹配从 A 到 Z 的大写字母 |
|
'/[abc]/' |
匹配 a, b, c 中任意一个字符* | |
'/abc{1}/' |
在 ab 后精确匹配一个 c 字符, 如 abc , 但不匹配 abcc |
|
'/abc{1,}/' |
在 ab 后匹配一个或多个 c 字符, 如 abc , abcc |
|
'/abc{2,4}/' |
在 ab 后匹配 2~4 个 c , 如 abcc , abccc , abcccc , 但不匹配 abc |
译者注: 上面示例中原文存在一些错误, 此处已修正.
除了运算符之外,还有正则表达式修饰符,可以全局改变搜索模式的行为。
正则表达式修饰符放在模式之后,就像 '/hello/i'
一样,它们由单个字母组成,例如 i
表示模式不区分大小写, x
表示忽略模式中的空白字符。 关修饰符的完整列表,请访问PHP的在线文档。
正则表达式的真正功能在于组合这些运算符和修饰符,从而创建相当复杂的搜索模式。
4. 在 PHP 中使用正则
在PHP中,我们总共有九个PCRE函数可以使用。这是列表:
- preg_filter – 执行一个正则表达式搜索和替换
- preg_grep – 返回匹配模式的数组条目
- preg_last_error – 返回最后一个PCRE正则执行产生的错误代码
- preg_match – 执行匹配正则表达式
- preg_match_all – 执行一个全局正则表达式匹配
- preg_quote – 转义正则表达式字符
- preg_replace – 执行一个正则表达式的搜索和替换
- preg_replace_callback – 执行一个正则表达式搜索并且使用一个回调进行替换
- preg_split – 通过一个正则表达式分隔字符串
最常用的两个函数是 preg_match
和 preg_replace
。
让我们首先创建一个测试字符串,我们将在其上执行正则表达式搜索。经典的 Hello World 示例:
$test_string = 'hello world';
如果我们只是想搜索单词hello或world,那么搜索模式将如下所示:
preg_match('/hello/', $test_string);
preg_match('/world/', $test_string);
如果我们希望查看字符串是否以单词 hello
开头,我们只需将 ^
字符放在搜索模式的开头,如下所示:
preg_match('/^hello/', $test_string);
请注意,正则表达式区分大小写,上面的模式与单词 hElLo
不匹配。 如果我们希望模式不区分大小写,则应该应用以下修饰符:
preg_match('/^hello/i', $test_string);
注意模式末尾正斜杠后面的字符 i
现在让我们来看一个更复杂的搜索模式。如果我们要确认字符串中的前五个字符由字母, 数字 组合,该怎么办?
preg_match('/^[A-Za-z0-9]{5}/', $test_string);
让我们剖析一下这种搜索模式 . 首先,通过使用 ^
,我们指定该字符串必须以字母, 数字开头。这由 [A-Za-z0-9]
来指定。
A-Z
表示从A到Z的所有字符, a-z
则表示从 a到z的所有小写字符.
{5}
告知正则表达式解析器此处刚好有五个字符。如果是六个而不是五个,解析器匹配不到任何东西.
上述正则表达式可以优化为以下形式:
preg_match('/^\w{5}/', $test_string);
\w
表示任何字母, 数字, 包括下划线字符 _
5. 该章节不存在
译者注: 原文没有 5... 的确没有
6. 有用的正则函数
以下是一些使用正则表达式的PHP函数,您可以每天使用它们。
译者注: 实际上有其他更为方便的替代函数比如验证邮箱可以使用
filter_var($email,FILTER_VALIDATE_EMAIL)
想了解更多的点击此处
6.1 验证e-mail
此函数将验证给定的电子邮件地址字符串,以查看其是否具有正确的格式。
function validate_email($email_address)
{
if( !preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+
([a-zA-Z0-9\._-]+)+$/", $email_address))
{
return false;
}
return true;
}
6.2 验证URL
function validate_url($url)
{
return preg_match('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?
(/.*)?$|i', $url);
}
6.3 移除重复的单词
我经常在文本中找到重复的单词,比如 this this
。这个方便的函数功能可以删除这些重复的单词。
function remove_duplicate_word($text)
{
return preg_replace('/\b(\w+)\s\1/i', "$1", $text);
}
译者注: 原文处的正则表达式有误, 此处已修正. 以下是原文给出的函数:
function remove_duplicate_word($text) { return preg_replace("/s(w+s)1/i", "$1", $text); }
6.4 验证字母数字,短划线,下划线和空格
function validate_alpha($text)
{
return preg_match("/^[A-Za-z0-9_- ]+$/", $text);
}
6.5 验证美国邮政编码
function validate_zip($zip_code)
{
return preg_match("/^([0-9]{5})(-[0-9]{4})?$/i",$zip_code);
}
7. 正则速查表
7.1 元字符
元字符 | Description | |
---|---|---|
^ | 标记字符串的开头 | |
$ | 标记字符串的结尾 | |
. | 匹配任意单个字符 | |
\ | 布尔或 | |
() | 组元素 | |
[abc] | 匹配 a,b,c 中任意一个 | |
[^abc] |
匹配除 a,b,c 外的任意一个 | |
s | 空白字符 | |
a? | 0 个或 1 个 a , 等同于 a{0,1} |
|
a* | 0 个或 多个 a |
|
a+ | 1 个或 多个 a |
|
a{2} | 精确匹配 2 个 a |
|
a{,5} | 最多 5 个 a |
|
a{5,10} | 匹配 5~10 个 a |
|
w | 单词字符, 等同于 [A-Za-z0-9_] |
|
W | 任何非单词字符 | |
s | 任何空白字符 | |
S | 任何非空白字符 | |
d | 任何数字, 等同于 [0-9] |
|
D | 任何非数字, 等同于 [^0-9] |
7.2 模式修饰符
模式修饰符 | 说明 |
---|---|
i | 忽略大小写 |
m | 多行模式 |
S | 模式的额外分析 |
u | 模式字符串被认为是 UTF-8 编码 |
译者注: 上述模式修饰符是大小写敏感的.还有一部分修饰符原文没有列举出来, 毕竟只是面向入门
8. 相关参考书目
- 15 PHP Regular Expression for Web Developers
- Mastering Regular Expressions in PHP
- Introduction to PHP Regex
9. Author: Joel Reyes
译者注: 该部分不翻译
Joel Reyes Has been designing and coding web sites for several years, this has lead him to be the creative mind behind Looney Designer a design resource and portfolio site that revolves around web and graphic design.
Write for Us! We are looking for exciting and creative articles, if you want to contribute, just send us an email.