个人正则笔记

断言

格式

1
2
3
正向预查:(?=)  相对应的    (?!)表示否定意思
反向预查:(?<=) 相对应的 (?<!)表示否定意思
前后紧跟字符
1
2
3
4
5
6
7
$regex = '/(?<=c)d(?=e)/';  /* d 前面紧跟c, d 后面紧跟e*/
$str = 'abcdefgk';

if(preg_match($regex, $str, $matches))
{
var_dump($matches);
}

结果:

1
2
array (size=1)
0 => string 'd' (length=1)

否定意义:

1
2
3
4
5
6
7
$regex = '/(?<!c)d(?!e)/';  /* d 前面不紧跟c, d 后面不紧跟e*/
$str = 'abcdefgk';

if(preg_match($regex, $str, $matches))
{
var_dump($matches);
}

字符宽度

1
2
3
4
5
6
7
8

$regex = '/HE(?=L)LO/i';
$str = 'HELLO';

if(preg_match($regex, $str, $matches))
{
var_dump($matches);
}

找不到字符串!;

1
2
3
4
5
6
7
$regex = '/HE(?=L)LLO/i';
$str = 'HELLO';

if(preg_match($regex, $str, $matches))
{
var_dump($matches);
}

(?=L)意思是HE后面紧跟一个L字符。但是(?=L)本身不占字符,要与(L)区分,(L)本身占一个字符。

捕获数据

没有指明类型而进行的分组,将会被获取,供以后使用。

指明类型指的是通配符。所以只有圆括号起始位置没有问号的才能被捕捉。

在同一个表达式内的引用叫做反向引用。
调用格式: \编号(如\1)。

1
2
3
4
5
6
7
$regex = '/^(today)[\w\s!]+\1$/';    
$str = 'today is today';

if(preg_match($regex, $str, $matches))
{
var_dump($matches);
}

不捕获分组

格式: (?:pattern) #不捕获分组 比较(X)和(?:X)前者是捕获分组,后者不捕获
优点:将使有效反向引用数量保持在最小,代码更加、清楚。

1
2
3
4
5
6
7
8
$regex = '/(?:a)(b)(c)/';

$str = 'abcabc';

if(preg_match($regex, $str, $matches))
{
var_dump($matches);
}

命名捕获分组

格式:(?P<组名>) 调用方式 (?P=组名)

1
2
3
4
5
6
7
8
$regex = '/(?P<name>sui)[\s]Is[\s](?P=name)/i';

$str = 'author:sui Is sui';

if(preg_match($regex, $str, $matches))
{
var_dump($matches);
}

惰性匹配

格式:限定符?

原理:"?":如果前面有限定符,会使用最小的数据。如“*”会取0个,而“+”会取1个,如过是{3,5}会取3个。
1
2
3
4
5
6
$regex = '/heL*/i';
$str = 'heLLLLLLLLLLLLLLLL';
if(preg_match($regex, $str, $matches))
{
var_dump($matches);
}

结果:

1
2
array (size=1)
0 => string 'heLLLLLLLLLLLLLLLL' (length=18)
1
2
3
4
5
6
$regex = '/heL*?/i';
$str = 'heLLLLLLLLLLLLLLLL';
if(preg_match($regex, $str, $matches))
{
var_dump($matches);
}

结果:

1
2
array (size=1)
0 => string 'he' (length=2)

?前面有限定符*

使用{3,5}

1
2
3
4
5
6
$regex = '/heL{3,5}?/i';
$str = 'heLLLLLLLLLLLLLLLL';
if(preg_match($regex, $str, $matches))
{
var_dump($matches);
}

结果:

1
2
array (size=1)
0 => string 'heLLL' (length=5)

正则表达式中 . 与 (.?) 的区别

简单说是贪婪匹配与非贪婪匹配的区别。

比如说匹配输入串A: 101000000000100

使用 1.*1 将会匹配到1010000000001, 匹配方法: 先匹配至输入串A的最后, 然后向前匹配, 直到可以匹配到1, 称之为贪婪匹配。

使用 1.?1 将会匹配到101, 匹配方法: 匹配下一个1之前的所有字符, 称之为非贪婪匹配。

所有带有量词的都是非贪婪匹配: .*?, .+?, .{2,6}? 甚至 .??

纵有疾风起,人生不言弃!