正则表达式详解:从基础到高级应用,掌握JavaScript、Java、PHP中的正则使用技巧
概述

正则表达式是描述字符串结果的语法规则。它是一种特定的格式化模式,可以匹配、替换和拦截匹配的字符串。常用的语言基本上都有正则表达式,比如JavaScript、Java等,其实只要了解了一种语言的正则使用,使用其他语言的正则规则就比较简单。正文主要解决以下问题。
① 常用的转义字符有哪些?
② 什么是限定符和定位符?
③ 什么是单词定位器?
④ 特殊字符有哪些?
⑤ 什么是反向引用以及如何使用
⑥ 搭配图案
⑦ php中如何使用正则表达式
⑧ php哪些方面需要用到正则规则?
⑨ 如何进行邮箱匹配、url匹配、手机匹配
⑩ 如何使用正则表达式替换字符串中的某些字符
⑪ 贪婪匹配和惰性匹配的区别
⑫ 正则表达式的回溯和扎实分组
⑬ 规律性的优点和缺点是什么?
正则表达式基础知识总结
行定位符(^ 和 $)
行定位符用于描述字符串边界。 “$”表示行尾,“^”表示行首,如“^de”表示以de开头的字符串。 “de$”表示以de结尾的字符串。
单词分隔符
当我们搜索一个单词时,比如an是否存在于字符串“gril and body”中,很明显,如果匹配的话,an肯定可以匹配字符串“gril and body”。我们怎样才能让它匹配呢?单词,而不是单词的一部分呢?这时候我们就可以使用一个单词分隔符\b。
如果\ban\b匹配“gril and body”,会提示无法匹配。
当然,还有一个大写的\B,它的意思与\b正好相反。它匹配的字符串不能是一个完整的单词,而是其他单词或字符串的一部分。如\Ban\B。
选择字符(|),表示或
选择表示“或”的字符。例如,Aa|aA表示Aa或aA。注意“[]”和“|”的区别就是“[]”只能匹配单个字符,而“|”可以匹配任意长度的字符串。使用“[]”时,常与连接字符“-”一起使用,如[ad],表示a或b或c或d。
排除字符、排除操作
正则表达式提供“^”来排除不匹配的字符。 ^一般放在[]中。例如[^1-5],这个字符不是1到5之间的数字。
限定符 (?*+{n, m})
限定符主要用于限制每个字符串出现的次数。
合格角色
意义
?
零次或一次
零次或多次
一次或多次
{n}
n次
{n,}
至少n次
{n,m}
n 到 m 次
例如,(D+)代表一个或多个D
点运算符
匹配任何字符(不包括换行符)
表达式中的反斜杠 (\)
表达式中的反斜杠有多种含义,例如转义、指定预定义字符集、定义断言以及显示不可打印字符。
转义字符
转义字符主要是将一些特殊字符转换为普通字符。这些常用的特殊字符包括“.”、“?”、“\”等。
指定预定义的字符集
特点
意义
\d
任意十进制数 [0-9]
\D
任何非十进制数
\s
任何空白字符(空格、换行、换页、回车、制表符)
\S
任何非空白字符
\w
任何单词字符
\W
任意数量的非单词字符
###显示不可打印的字符
特点
意义
\一个
打电话叫警察
\b
退格键
\f
页面变更
\n
换行符
\r
进入
\t
特点
括号字符()
正则表达式中括号的主要作用是:
更改限定符的范围,例如 (|、*、^)
例如,(my|your)baby,如果没有“()”,|将匹配我的或你的宝宝。如果加上括号,它将匹配 mybaby 或 yourbaby。
分组以便于反向引用
反向引用
反向引用依赖于子表达式的“记忆”功能来匹配连续的字符串或字符。例如,(dqs)(pps)\1\2 表示匹配字符串 dqsppsdqspps。在下面的PHP应用中,我将详细了解反向引用。
模式修饰符
模式修饰符的作用是设置模式,即如何解释正则表达式。 php中的主要模式如下:
修饰语
阐明
忽略大小写
多文本模式
单行文本模式
忽略空白字符
正则表达式在php中的应用
php中的字符串匹配
所谓字符串匹配,言下之意就是判断一个字符串是否包含或者等于另一个字符串。如果我们不使用正则表达式,我们可以使用PHP中提供的很多方法来进行这样的判断。
不要使用正则匹配
strstr 函数
string strstr ( string haystack,mixedneedle [, bool $before_needle = false ])
注1:haystack是正在讨论的字符串,needle是正在搜索的字符串。该函数区分大小写。
注2:返回值是从针头到针尾的值。
注3:关于$needle,如果不是字符串,则将其视为整数,并用作字符的序列号。
注4:如果before_needle为true,则返回之前的东西。
stristr 函数与 strstr 函数相同,只是不区分大小写
strpo 函数
int strpos ( string haystack,mixedneedle [, int $offset = 0 ] )
注 1:可选的 offset 参数可用于指定从 haystack 中的哪个字符开始搜索。返回的数字位置是相对于干草堆的起始位置的。
stripos - 查找字符串的第一次出现(对大小不敏感)
strrpos - 计算指定字符串在目标字符串中最后一次出现的位置
strripos - 计算指定字符串在目标字符串中最后一次出现的位置(不区分大小写)
使用正则表达式进行匹配
php中提供了preg_math()和preg_match_all函数用于正则匹配。这两个函数的原型如下:
int preg_match|preg_match_all ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )
搜索主题和模式给定的正则表达式之间的匹配项。
pattern:要搜索的模式,字符串类型。
主题:输入字符串。
matches:如果提供了参数matches,它将被填充为搜索结果。 matches[0] 将包含与完整模式匹配的文本,matches[1] 将包含与第一个捕获的子组匹配的文本,依此类推。
flags:flags 可以设置为以下标志值: PREG_OFFSET_CAPTURE 如果传递此标志,则每次出现匹配时都会返回字符串偏移量(相对于目标字符串)。注意:这将更改 matches 参数中填充的数组,以便每个元素变成一个字符串,其中第 0 个元素是匹配的字符串,第 1 个元素是匹配的字符串在目标字符串主题中的偏移量。 。
offset:通常情况下,从目标字符串的开头开始搜索。可选参数offset用于指定从目标字符串中的未知点开始搜索(单位为字节)。
返回值: preg_match() 返回模式的匹配数。它的值将为 0(不匹配)或 1,因为 preg_match() 将在第一个匹配后停止搜索。 preg_match_all() 与此不同,它会搜索主题,直到到达末尾。如果发生错误 preg_match() 返回 FALSE。
例子
实施例1
判断字符串“”是否包含csdn?
解决方案1(不使用正则表达式):
如果正则性不适用,我们可以使用 strstr 或 strpos。在这里,我将使用 strstr 函数。代码如下:
$str='http://blog.csdn.net/hsd2012';
function checkStr1($str,$str2)
{
return strstr1($str,$str2)?true:false;
}
echo checkStr($str,'csdn');
解决方案 2:使用常规规则
因为我们只需要判断是否存在,所以选择preg_match。
$str='http://blog.csdn.net/hsd2012';
$pattern='/csdn/';
function checkStr2($str,$str2)
{
return preg_match($str2,$str)?true:false;
}
echo checkStr2($str,$pattern);
示例 2(检查单词分隔符)
判断字符串“I am a good boy”是否包含go这个词
首先判断是一个单词,而不是一个字符串。因此,比较的时候需要比较是否包含‘go’,即字符串go前后有空格。
分析:如果使用非常规比较,只需要调用上面的checkStr1()函数即可。注意第二个参数前后必须加一个空格,即‘go’。如果您使用正则表达式,
我们可以考虑使用单词分隔符\b,则$pattern='/\bgo\b/';然后调用 checkStr2 函数。
示例 3(检查反向引用)
判断字符串“I am a good boy”是否包含3个相同的字母
分析:这个时候如果我们不使用正则表达式的话,会很难判断,因为字母太多了,我们不可能将所有字母与字符串进行比较,这也会需要大量的工作。这次涉及到当前的反向引用。在PHP正则表达式中,\n用于表示第n个匹配结果。例如\5代表第五个匹配结果。然后 $pattern='/(\w).*\1.*\1/';
主要需要注意的是,使用反向匹配时需要使用()。进行反向匹配时,匹配()中出现的字符或字符串。
PHP中的字符串替换
不要使用正则表达式
PHP中替换字符串时,如果正则表达式不适用,我们通常使用substr、mb_substr、str_replace、substr_replace。这些功能之间的差异如下。
函数运算符
功能
描述
str_replace(查找、替换、字符串、计数)
使用字符串替换字符串中的其他字符。
找到需要的。指定要查找的值。需要更换。指定要替换 find 中的值的值。需要字符串。指定要搜索的字符串。计数可选。计算替换次数的变量。
substr_replace(字符串,替换,开始,长度)
将字符串的一部分替换为另一个字符串。适合在自定义位置替换字符串。
需要字符串。指定要检查的字符串。需要更换。指定要插入的字符串。需要启动。指定字符串中开始替换的位置。
使用常规
如果使用正则替换,PHP 提供了 preg_replace _callback 和 preg_replace 函数。 preg_replace原型如下:
mixed preg_replace ( mixed pattern,mixedreplacement , mixed subject[,intlimit = -1 [, int &count]])
功能说明:在字符串主题中查找pattern,然后使用replacement进行替换。如果有限制,就意味着限制更换的数量。 pregreplacecallback 与 pregreplace 具有相同的功能。不同的是pregreplaceback使用的是回调函数callback而不是replacement。 − 示例1 将字符串“hello, China”中的hello替换为“hello”;如果不使用正则表达式:str='hello, China';
str=strreplace(′hello′,′你好′,str)
或者使用
str=substrreplace(str,'你好',0,5)
使用常规
pattern=′/hello/′;str=preg_replace (pattern,′你好′,str);
- 示例2
删除字符串“gawwenngeeojjgegop”中连续的相同字母
$str='gawwenngeeojjgegop';
$pattern='/(.)\1/';
$str=preg_replace($pattern,'',$str);
分析:当然有可能发生这种情况。第一次删除重复字符串后,重复字符串再次出现。比如字符串flavor'gewwenngeeojjgegop',对于这个问题,当然在这种情况下,通过判断继续进行替换。
实施例3
更改字符串“age13gegep3iorji65k65k”中出现的两个连续数字;改为第二个数字,例如字符串中的13变为3
$str='age13gegep3iorji65k65k';
$pattern='/(\d)(\d)/';
$str=preg_replace($pattern,'$2', $str);
分析: $n 在正则表达式之外使用了反向引用。 n表示匹配结果的数量。
PHP中的字符串分割
不要使用正则表达式
PHP提供了explode函数来分割字符串,它的对应函数是implode。 Explode的原型如下:
array explode ( string delimiter,stringstring [, int $limit ] )
delimiter:边界上的分隔符。
字符串:输入字符串。
limit:如果设置了limit参数并且为正数,则返回的数组最多包含limit个元素,最后一个元素将包含字符串的其余部分。如果 limit 参数为负数,则返回除最后一个 -limit 元素之外的所有元素。如果 limit 为 0,则将被视为 1。
使用常规
关于通过正则表达式分割字符串,PHP提供了split和preg_split函数。 preg_split() 函数通常是 split() 的更快替代方法。
array preg_split ( string pattern,stringsubject [, int limit=−1[,intflags = 0 ]] )
例子
根据“/”分割字符串“”
解决方案一:
$str='http://blog.csdn.net/hsd2012/article/details/51152810';
$str=explode('/', $str);
解决方案二:
$str='http://blog.csdn.net/hsd2012/article/details/51152810';
$pattern='/\//'; /*因为/为特殊字符,需要转移*/
$str=preg_split ($pattern, $str);
php中的贪婪匹配和惰性匹配
贪心匹配:匹配尽可能多的字符。
例如,在正则表达式 m.*n 中,它将匹配以 m 开头、以 n 结尾的最长字符串。如果您使用它来搜索 manmpndegenc,它将匹配的字符串是 manmpndegen 而不是 man。你可以这样想,当m匹配时,它会从后到前匹配字符n。
惰性匹配:匹配尽可能少的字符。
有时候,我们不需要贪婪地匹配,而是尽可能少地匹配。这时候就需要转为惰性匹配。如何将贪婪匹配转化为惰性匹配?加个“?”就可以了在它之后。例如,m.*?n 将匹配 manmpndegenc,匹配的字符串为 man。
函数运算符
描述
零次或多次,但匹配次数尽可能少
一次或多次,但匹配次数尽可能少
0 或 1 次,但匹配次数尽可能少
{n,}?
至少n次,但匹配次数尽可能少
{n,m}?
n 到 m 次,但匹配次数尽可能少
PHP正则表达式回溯和实体分组
回溯
首先,我们需要了解什么是回溯。回溯就像走在岔路口。当你遇到岔路口时,首先在每个路口做一个标记。如果你遇到了死胡同,你可以原路返回,直到你遇到你之前制作的标志,标志着一条你还没有尝试过的路。如果走不了那条路,可以继续往回走,找到下一个标记,重复,直到找到出路,或者走完所有未尝试过的路。首先我们看一下例子
$str='aageacwgewcaw';
$pattern='/a\w*c/i';
$str=preg_match($pattern, $str);
看到上面的程序,你可能知道什么意思了,就是匹配$str是否包含由“a+0个或多个字母+c”组成的不区分大小写的字符串。但至于程序如何搭配呢?匹配过程中你回溯了多少次?
匹配过程
接下来的操作说明
'a\w*c' 中的 a 匹配 'aageacwgewcaw' 中的第一个字符 a
\w 匹配下一个字符
因为 \w 是贪心匹配,所以它会匹配到 'aageacwgewcaw' 中的最后一个字符 w
c 匹配下一个字符时
在 'a\w*c' 中,c 找不到匹配项
所以\w匹配第一次回溯,匹配倒数第二个字符a
在'a\w*c'中,c发现仍然没有匹配到。
所以 \w 匹配第二次回溯,匹配到倒数第三个字符 c
'a\w*c' 中的 c 匹配成功
匹配结束后返回结果
现在,如果我们将模式更改为pattern='/a\w*?c/i';,我们会回溯多少次?正确答案是回溯四次。
固态包
扎实分组的目的是减少回溯次数。如果在 (?>...) 括号中匹配时生成替代状态,则一旦离开括号,引擎就会放弃该替代状态。典型的例子是: '\w+:' 表达式的匹配过程如下。它会优先匹配所有匹配\w的字符。如果字符串末尾没有“:”,则不匹配。当找到冒号时,就会触发回溯机制。它将强制前面的 \w+ 释放该字符,并在返回的字符中重试与 ':' 的比较。但问题就出现在这里:\w不包含冒号,所以显然无论如何都不会匹配成功,但是根据回溯机制,引擎仍然要向前看,这就浪费了资源。所以我们要避免这种回溯。这样做的方法就是将之前匹配的内容固化下来,不让它存储备份状态! ,那么引擎将不得不结束匹配过程,因为没有可用的备份状态。大大减少回溯次数。
下面的代码不会回溯:
$str='nihaoaheloo';
$pattern='/(?>\w+):/';
$rs=preg_match($pattern, $str);
当然,有时需要谨慎使用固定分组。如下,我想检查 $str 是否包含以 a 结尾的字符串。明明是包含了,但是因为使用了solid grouping,所以无法达到我们想要的效果。影响
$str='nihaoahelaa';
$pattern1='/(?>\w+)a/';
$pattern2='/\w+a/';
$rs=preg_match($pattern1, $str);//0
$rs=preg_match($pattern2, $str);//1
php中其他常用的字符串操作函数
字符串拦截拦截
string substr ( string string,intstart [, int length])stringmbsubstr(stringstr , int start[,intlength = NULL [, string $encoding = mb_internal_encoding() ]] )
字符串中的大小写转换
strtoupper
strtolower
ucfirst
ucwords
字符串比较
-strcmp、strcasecmp、strnatcmp
字符串过滤
字符串翻转
strrev($str);
对字符串进行随机排序
string str_shuffle ( string $str )
补充
如何进行邮箱匹配、url匹配、手机匹配
使用preg_match函数进行匹配,以下是从TP复制的。
邮箱验证
pattern=′/\w+([−+.]\w+)∗@\w+([−.]\w+)∗\.\w+([−.]\w+)∗/';
网址匹配
pattern='/^http(s?):\/\/(?:[A-za-z0-9-]+\.)+[A-za-z]{2,4}(:\d+)?(?:[\/\?#][\/=\?%\-&~`@[\]\':+!\.#\w]*)?/';
手机验证
pattern=′/1[3458]\d10/';
希望以上内容对大家有所帮助。如有需要,您可以添加下面的二维码,加入群进行交流和学习新技术。
好文章链接:
如果想和PHP高手交流,加微信进群
如果您想获取更多学习资料,请添加微信,我们将向您发送资源