正则 , 其实就是字符串规则表达式 , 比如说大家熟悉的 "*" 代表的是所有字符 . 所以它的主要作用就是 , 通过规则 , 找出你想要找的东西,即分割、查找、匹配、替换

基本原理

  1. 描述规则
  2. 执行规则

简单示例

$str = 'hello world!';
//取出wo
$patt = '/wo/';//规则
//PHP 函数 preg_match、preg_match_all 执行正则表达式的查找
preg_match($patt, $str, $match);
print_r($match);

PHP操作函数自行前往PHP文档查看,在这儿不做赘述 正则表达式(兼容 Perl)")

语法

正则表达式

字符边界

/ 左右开始边界
^ 匹配字符串的开始
$ 匹配字符串的结尾
b 匹配单词的开始和结尾 ( 边界 )
B 匹配单词的非边界

正则表达式 b B的详细用法

//每一个\b就相当于一个空格,如“hello world!”那么,这句中有好几个\b, 
//每个单词的前后都有一个\b,所以你用 `\bhello\b` 可以匹配上面这个hello,
//但如果hello 不是一个单词,而是一个单词的一部分,如 ahelloa, 这样的话,
//用hello可以匹配,用'\bhello\b'就不能区配了,因为ad后面没有\b。
//所以 ahelloa 中的hello 不会被匹配。\B就是反过来,代表非字间。 (同\d代表数字, \D代表非数字异曲同工)
$str = 'hello world!';
//$str = 'ahelloa world!';
//取出含有hello的单词
$patt = '/\bhello\b/';//规则
// 把包括在单词内部的hello 找出来
//$patt = '/\Bhello\B/';//规则
//PHP 函数 preg_match、preg_match_all 执行正则表达式的查找
preg_match($patt, $str, $match);
print_r($match);

常用字符簇


代表
.任意字符,不换行
w[a-zA-Z0-9_ ]
Ww的补集
s所有空白符,包括nrtv
S非空白符
d[0-9]
D非数字

字符的集合与补集

与数学中类集合与补集类似,字符集合:[]中包含关键字,例如[abc]、[0123456789]的含义是匹配abc、匹配0123456789,字符补集 1 不在 qxz 范围内

$str = 'hello world!';
$patt = '/[hero]/';//匹配出‘hello world!’中h、e、r、o
$patt = '/[^hero]/';//匹配出‘hello world!’中h、e、r、o以外的部分
preg_match_all($patt,$str,$match);
print_r($match);

字符范围

格式:{},例如:查找纯字母组成的单词

// 找纯字母组成的单词
$str = 'i am1 jacy2 li3 Me';
//$patt = '/\b[a-zA-Z]{1}\b/';//匹配出i
//$patt = '/\b[a-zA-Z]{2}\b/';//匹配Me
$patt = '/\b[a-zA-Z]{1,2}\b/';//匹配i,Me
preg_match_all($patt,$str,$match);
print_r($match);

或者的用法

$str = 'hello world! 2019';
$patt = '/\b[a-zA-Z]+|[0-9]+\b/';
preg_match_all($patt,$str,$match);
print_r($match);

() 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 ( 和 ) 。

// 查询苹果系统的产品
$str = 'ipad,iphone,imac,ipod,iamsorry';
/* 思路:匹配到i后边的单词与苹果系列的相同 同样需设置多个规则 */
$patt = '/\bi(pad|mac|pad|phone)\b/';
preg_match_all($patt,$str,$match);
print_r($match);

贪婪与非贪婪

* 、 + 和 ? 限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个 ? 就可以实现非贪婪或最小匹配。

'*' 匹配前面的子表达式零次或多次。
'+' 匹配前面的子表达式一次或多次。
'?' 匹配前面的子表达式零次或一次。

贪婪模式:

// 把 g 与 d 之间的任意字符给替换成 god
$str = 'oh my god good goooood , goooood,what,wrong';
// 思路 : 匹配 g+d 的单词 , 任意字符使用 . 匹配多个用 *
$patt = '/\bg.*d\b/'; // 使用 .* 会尽可能的多匹配
preg_match_all($patt,$str,$match);//打印god good goooood , goooood
print_r($match);
// 找到之后替换
echo preg_replace($patt,'god',$str);//oh my god,what,wrong全部替换

非贪婪模式:

// 非贪婪只需要在 .* 后加 ?
// 把 g 与 d 之间的任意字符给替换成 god
$str = 'oh my god good goooood , goooood,what,wrong';
// 思路 : 匹配 g+d 的单词 , 任意字符使用 . 匹配多个用 *
$patt = '/\bg.*?d\b/'; // 使用 .* 会尽可能的多匹配
// 找到之后替换
echo preg_replace($patt,'god',$str);

反向引用

所谓反向引用其实就是 1、2 ... ... 这些,他的作用相当于引用“一组规则”;那么什么叫一组规则呢?举个例子:/([a-z]\d)-(123)\1/这里有两组小括号(),每一组小括号就是所谓的一组,因此这个正则中的1指的便是([a-z]\d)

//找首尾字母相同的单词
$str = 'txt hello,high,bom,mum';
// 简化 , 先找到首尾字母都是 t 的
$patt = '/\bt\w+t\b/';
preg_match_all($patt,$str,$match);
print_r($match);
// 第 n 个小括号内的子表达式 , 命中的内容 , 后面就用 \n 来引用
$patt = '/\b([a-z])\w+\1\b/';
//1. 单词开始和结束 \b\b
//2. 开始的 [a-z] 都可以 .\b[a-z]\b
//3. 后面跟什么都行 , 不管 . 并且字数不限 \b[a-z]\w+\b
//4. 最后一个应该和第一个相同 .\b([a-z])\w+\b  子表达式 , 放在下面另一个数组里面 , 最后一
//个引用子表达式匹配出来的结果 \b([a-z])\w+\1\b
preg_match_all($patt,$str,$match);
print_r($match);

模式修饰符

正则表达式中常用的模式修正符有i、m、s、U、x、a、D、e 等。(只强调PHP,别的语言不一定适用)

修正符含义
i同时匹配大小写字母
m匹配其中的换行符的之后和之前
s模式中的圆点元字符(.)匹配所有的字符,包括换行符(一般情况下‘.’是不能匹配‘n’的)
x模式中的空白字符除了被转义的或在字符类中 的以外完全被忽略,在未转义的字符类之外的 # 以及下一个换行符之间的所有字符,包括两头,也都被忽略。
epreg_replace() 在替换字符串中对逆向引用作正常的替换,将其作为 PHP 代码求值,并用其结果来替换所搜索的字符串。
A模式被强制为“anchored”,即强制仅从目标字符串的开头开始匹配。
D如果设定了此修正符,模式中的美元元字符仅匹配目标字符串的结尾。没有此选项时,如果  最后一个字符是换行符的话,美元符号也会匹配此字符之前(但不会匹配任何其它换行符之前)。如果设定了 m 修正符则忽略此选项。Perl 中没有与其等价的修正符。
S当一个模式将被使用若干次时,为加速匹配起见值得先对其进行分析。如果设定了此修正符则会进行额外的分析。目前,分析一个模式仅对没有单一固定起始字符的 non-anchored 模式有用。
U本修正符反转了匹配数量的值使其不是默认的重复,而变成在后面跟上“?”才变得重复。这和 Perl 不兼容。也可以通过在模式之中设定 (?U) 修正符或者在数量符之后跟一个问号(如 .*?)来启用此选项。
X此修正符启用了一个 PCRE 中与 Perl 不兼容的额外功能。模式中的任何反斜线后面跟上一个没有特殊意义的字母导致一个错误,从而保留此组合以备将来扩充。默认情况下,和 Perl 一样,一个反斜线后面跟一个没有特殊意义的字母被当成该字母本身。当前没有其它特性受此修正符控制。
u此修正符启用了一个 PCRE 中与 Perl 不兼容的额外功能。模式中的任何反斜线后面跟上一个没有特殊意义的字母导致一个错误,从而保留此组合以备将来扩充。默认情况下,和 Perl 一样,一个反斜线后面跟一个没有特殊意义的字母被当成该字母本身。当前没有其它特性受此修正符控制。

预查

包括正向预查和反向预查,正向或反向预查都是非获取匹配,不进行存储供以后使用
PHP7 PHP5为例

1、正向预查
(?:pattern) 匹配结果。PHP(?:7|5)等效于PHP7|PHP7,结果PHP7 PHP5
(?=pattern) 正向匹配。PHP(?=7),匹配后面跟着7的PHP,即第一个PHP
(?!pattern) 正向不匹配。PHP(?!7),匹配后面不跟着7的Java,即第二个PHP

2、反向预查
(?<=pattern) 反向匹配。(?<=PHP)7,匹配紧跟PHP后面的7
(?<!pattern) 反向不匹配。(?<!PHP)7,不匹配紧跟字母PHP后面的7,结果PHP

这里有腾讯招聘的一个例子:
如何给一串数字用千分制表示?比如9999999999变成9,999,999,999。这样一个问题你会怎么答呢?

$str = '9999999999';
$patt = '/(\d{1,3})(?=(\d{3})+$)/';
preg_match_all($patt,$str,$match);
print_r($match);
echo preg_replace($patt,'$1,',$str);

分析一下:(\d{1,3})匹配出1~3位的数字,(\d{3})+$)预查最后数字是否三位

over.


  1. qxz