最近接触到了正则表达式,感觉一开始有点恶心,然后决定细细研究一下搞懂它。
一.先了解一下正则表达式的组成。它由4个要素组成。
1.定界符:多种都可以,比如// || {},常用//。(后来知道了除了字母,数字和斜线"\"以外,其他任何字符都可以做定界符)
2.原子:最少的一个匹配单位(放在定界符中),在一个正则表达式中至少要有一个原子。
例:假设有这样一个字符串$str = "aaaaaa777bbb8888888";
原子可以是$reg = "/a/" , 也可以是 $reg = "/777/" , 甚至可以是 $reg = "/\d/"(这是一个系列的,取出字符串中所有的数字) ,他们都是原子。
3.元字符:元字符不能单独使用(放在定界符中),修饰原子,用来扩展原子功能和限定功能。
例:假设有这样一个字符串$str = "aaaaaa777bbb8888888";
正则表达式为:$reg = "/ 7{5} /" , 他表示7必须出现5次才能匹配成功,这个{5}对7这个原子产生修饰作用,他就是一个元字符。
4.模式修正符:用来对模式(正则)修正(放在定界符外面,写在右边)。
* 正则表达式用单引号或双引号都可以,但是有些细节需要注意,比如要查找$这个符号,用双引号的话,即使用转义字符也无法成功查询,只能用单引号。还有很多两者的区别以后遇到了具体说吧。
例:假设有这样一个字符串$str = "aaaaaa777bbb8888888";
我们知道正则表达式为:$reg = "/a{5}/" 是匹配5个连续的a (区分大小写), 而我们在后面加个i 形成 $reg = "/a{5}/i" ,它也是匹配5个连续的a(不区分大小写)。通过这个i来对整个模式(正则)进行修饰,它是一个模式修正符。
二.正则表达式的使用
其实,正则表达式的实质也是字符串,所以,如果想使用正则表达式,我们要配合函数使用。现在比较有代表性且常用的是perl语言的正则表达式,所以这里也用他们的函数。
下面介绍一些比较常用的函数:
eg:
- preg_replace(reg,str,目标字符串c):用str替换在字符串c中用 正则表达式reg 所查询到的字符
<?php
$str = "aaaaaa777bbb8888888";
$reg = "/\d/";
echo $str;
echo '<br>';
echo preg_replace($reg,"#",$str);
echo '<br>';
效果图:
- preg_split(正则表达式reg,字符串str):用 正则表达式reg 分离字符串c
eg:
<?php
$str = "aaaaaa7bb6bdc66dd";
$reg = "/\d/";
echo $str;
echo '<br>';
print_r(preg_split($reg,$str));
echo '<br>';
效果图:
- preg_match(正则表达式reg,字符串str,数组arr):在字符串str中查找正则表达式对应的字符,查找到返回true,并将字符放入数组arr中,否则返回false(只返回一次,即匹配到即退出,不会全部匹配)。
eg:
<?php
$str = "aaaaaa777bb6b8888888";
$reg = "/\d/";
echo $str;
echo '<br>';
if(preg_match($reg,$str,$arr)){
echo "正则表达式{$reg}和字符串{$str}匹配成功!";
echo '<br>';
echo "匹配到的字符串部分为:";
print_r($arr);
echo '<br>';
}else{
echo "匹配失败!";
echo '<br>';
}
效果图:
- preg_match_all(正则表达式reg,字符串str,数组arr):在字符串str中查找正则表达式对应的字符,查找到返回true,并将字符放入数组arr中,否则返回false(全部匹配)。
eg:和preg_match对比一下
<?php
$str = "aaaaaa777bb6b8888888";
$reg = "/\d/";
echo $str;
echo '<br>';
if(preg_match($reg,$str,$arr)){
echo "正则表达式{$reg}和字符串{$str}匹配成功!";
echo '<br>';
echo "匹配到的字符串部分为:";
print("<pre>");
print_r($arr);
print("<pre>");
echo '<br>';
}else{
echo "匹配失败!";
echo '<br>';
}
if(preg_match_all($reg,$str,$arr)){
echo "正则表达式{$reg}和字符串{$str}匹配成功!";
echo '<br>';
echo "匹配到的字符串部分为:";
print("<pre>");
print_r($arr);
print("<pre>");
echo '<br>';
}else{
echo "匹配失败!";
echo '<br>';
}
效果图:
三. 正则表达式的细节(深入剖析一下原子和元字符)
原子部分:
- 原子包含打印字符(a-z A-Z 0-9 !@#$%^&*()_+等能打印出来的字符)和 非打印字符(制表,回车,空格等无法显示的字符)
-
转义字符 \ 的作用:
一. 可以将有意义的字符转成无意义的原子字符(将有意义的字符变成原子)
比如:
<?php $str = "this is .a test<br>"; $reg = "/./"; if(preg_match($reg,$str,$arr)){ echo "正则表达式{$reg}和字符串{$str}匹配成功!"."<br>"; echo "匹配部分为:"."<br>"; print_r($arr); }else{ echo "没有匹配到!"; }
当我们 用正则表达式 $reg = "/./"; 来查询时,它会查询所有字符,所以第一个字符t就满足条件并返回。当我们只想查询 . 时,就需要转义了。
-
<?php $str = "this is .a test<br>"; $reg = "/\./"; if(preg_match($reg,$str,$arr)){ echo "正则表达式{$reg}和字符串{$str}匹配成功!"."<br>"; echo "匹配部分为:"."<br>"; print_r($arr); }else{ echo "没有匹配到!"; }
二.可以将没有意义的字符转成有意义的原子
比如:$reg = "/n/"; 是查询n的,我们加上转义就变成查询回车的了。
三. a-z A-Z 0-9 _ 所有没有意义的字符,加上转义也是没意义的
比如:$reg = "/@/"; 和$reg = "/\@/"; 查询效果是一样的。
- 几种常用的由转义符组成特殊系列字符
- \s: 取出任意一个空白(制表,空格等)
- \S: 取出任意一个非空白
- \w: 取出任意一个字(a-z A-Z 0-9 _ 其他特殊符号不算)
- \W: 取出任意一个非字
- \d: 取出任意一个数字
- \D: 取出任意一个非数字
- 自定义原子表
像上面说的,我们用的都是他们定义好的一些系列字符,他们符合一定的规则,当然,我们也可以自己定义规则。比如我们可以自定义原子表 [13579] ,他表示要取奇数1 3 5 7 9中的数,只要查询到目标字符串有一个数是奇数即能成功匹配;
通常,自定义原子表配合 - (表示范围,比如 [a-zA-Z] 表示查找所有英文字母)和 ^(表示除了列表中的,比如 [^a-zA-Z] 表示查找除了英文字母之外的字符)
- . 能代表所有的(它很贪心)
元字符
- 作用:不能在正则表达式中单独使用,用来修饰原子
- 几种常用的元字符:
eg:
$reg分别为:查找中间的is、查找最左边的is、查找最右边的is。
- * :用来修饰其前面的原子可以出现0或1或更多次(任意次)
- + :用来修饰其前面的原子可以出现1或更多次(至少出现1次)
- ?:用来修饰其前面的原子可以出现0或1次(最多出现1次)
- {m}:用来修饰其前面的原子只能出现m次,多一次少一次都不行
- {n,m}:用来修饰其前面的原子出现个数在n到m之间,包括n和m
- {n,}:用来修饰其前面的原子出现个数至少是n次
- {,m}:没有这种用法,但我们可以用{0,m}来实现这种功能
- | :是或的关系,表示他两边的原子只要有一个出现就可以,但是 | 的优先级是最低的
- ^ 或 \A:表示必须以什么开始,这个必须写在正则表达式的最前面
- $ 或 \Z: 表示必须以什么结束,这个必须写在正则表达式的最后面
- \b: 单词边界
- \B: 不是单词边界