正则表达式基本知识

概述
正则表达式是一种描述字符串结果的语法规则,是一个特定的格式化模式,可以匹配、替换、截取匹配的字符串。

行定位符( ^ 与 $ )

行定位符是用来描述字符串的边界。

“^”表示行开始,“$”表示行结尾,如"^de"表示以de开头的字符串,  "de$"表示以de结尾的字符串。

单词定界符( \b 与 \B )

我们在查找的一个单词的时候,如an是否在一个字符串”gril and body”中存在,很明显如果匹配的话,可以匹配字符an肯定是串“gril and body”匹配到,怎样才能让其匹配单词,而不是单词的一部分呢?这时候,我们可以是以使用一个单词定界符\b。如:

\ban\b 去匹配”gril and body”的话,就会提示匹配不到。

当然还有一个大写的\B,它的意思,和\b正好相反,它匹配的字符串不能是一个完整的单词,而是其他单词或字符串中的一部分。如:

\Ban\B 去匹配”gril and body”的话,就会可以匹配到。

选择字符( [] 与 | ) ,表示或

选择字符表示或的意思。如Aa|aA,表示Aa或者是aA的意思。注意使用”[]”与”|”的区别,在于”[]”只能匹配单个字符,而”|”可以匹配任意长度的字符串。在使用”[]”的时候,往往配合连接字符”-“一起使用,如:

[a-d],代表a或b或c或d。

排除字符(^),排除操作

正则表达式提供了” ^ ”来表示排除不符合的字符,^一般放在[]中。如:

[^1-5],该字符不是1~5之间的数字。

限定符( ?*+ {n,m} ),限定字符出现的次数

限定符主要是用来限定每个字符串出现的次数。


+号操作符
如(D+)表示一个或多个D
点号操作符
匹配任意一个字符(不包含换行符)
表达式中的反斜杠()
表达式中的反斜杠有多重意义,如转义、指定预定义的字符集、定义断言、显示不打印的字符。
转义字符
转义字符主要是将一些特殊字符转为普通字符。而这些常用特殊字符有”.”,”?”、”\”等。
指定预定义的字符集

###显示不可打印的字符

括号字符()
在正则表达式中小括号的作用主要有:
1、改变限定符如(|、* 、^)的作用范围:
如(my|your)baby,如果没有”()”,|将匹配的是要么是my,要么是yourbaby,有了小括号,匹配的就是mybaby或yourbaby。
2、进行分组,便于反向引用
反向引用
反向引用,就是依靠子表达式的”记忆”功能,匹配连续出现的字串或是字符。如(dqs)(pps)\1\2,表示匹配字符串dqsppsdqspps。\1代表第一个括号里的字串,\2代表第二个括号内的字串。
模式修饰符
模式修饰符的作用是设定模式,也就是正则表达式如何解释。php中主要模式如下表:

正则表达式在php中应用

php中字符串匹配
所谓的字符串匹配,言外之意就是判断一个字符串中,是否包含或是等于另一个字符串。如果不使用正则,我们可以使用php中提供了很多方法进行这样的判断。
不使用正则匹配

strstr函数

string strstr ( string haystack,mixedneedle [, bool $before_needle = false ])

注1:haystack是当事字符串(海),needle是被查找的字符串(针),大海捞针。该函数区分大小写。
注2:返回值是从needle开始到最后。
注3:关于$needle,如果不是字符串,被当作整形来作为字符的序号来使用。
注4:before_needle若为true,则返回前东西。
stristr函数与strstr函数相同,只是它不区分大小写

strpos函数

int strpos ( string haystack,mixedneedle [, int $offset = 0 ] )

注1:可选的 offset 参数可以用来指定从 haystack 中的哪一个字符开始查找。返回的数字位置是相对于 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 ]]] )

搜索subject与pattern给定的正则表达式的一个匹配.
pattern -要搜索的模式,字符串类型。
subject -输入字符串。
matches:如果提供了参数matches,它将被填充为搜索结果。 matches[0]将包含完整模式匹配到的文本,matches[1]将包含第一个捕获子组匹配到的文本,以此类推。
flags -flags可以被设置为以下标记值:PREG_OFFSET_CAPTURE 如果传递了这个标记,对于每一个出现的匹配返回时会附加字符串偏移量(相对于目标字符串的)。 注意:这会改变填充到matches参数的数组,使其每个元素成为一个由 第0个元素是匹配到的字符串,第1个元素是该匹配字符串 在目标字符串subject中的偏移量。
offset -通常,搜索从目标字符串的开始位置开始。可选参数 offset 用于 指定从目标字符串的某个未知开始搜索(单位是字节)。
返回值:preg_match()返回 pattern 的匹配次数。 它的值将是0次(不匹配)或1次,因为 preg_match()在第一次匹配后 将会停止搜索。 preg_match_all()不同于此,它会一直搜索subject直到到达结尾。 如果发生错误 preg_match()返回 FALSE。

实例

实例1
判断字符串”http://blog.csdn.net/hsd2012“中是否包含csdn?
解法一(不使用正则):
如果不适用正则,我们使用strstr或者strpos中任意一个都可以,在此,我将使用strstr函数,代码如下:

$str='http://blog.csdn.net/hsd2012';
function checkStr1($str,$str2)
{
 return strstr1($str,$str2)?true:false;
}
echo checkStr($str,'csdn');

解法二:使用正则
因为我们只需要判断是否存在即可,所以选择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关于这几个函数区别如下表。


使用正则
如果使用正则替换,php中提供了preg_replace _callback和preg_replace 函数,preg_replace 原型如下:

mixed preg_replace ( mixed pattern,mixedreplacement , mixed subject[,intlimit = -1 [, int &count]])

函数功能描述:
在字符串subject中,查找pattern,然后使用replacement 去替换,如果有limit则代表限制替换limit次。pregreplacecallback与pregreplace功能相似,不同的是pregreplaceback使用一个回调函数callback来代替replacement.
−例1
将字符串”hello,中国”中的hello替换为′你好′;
如果不用正则:

$str='hello,中国';
$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);

解析:当然这样可能会遇到,当第一次去除了重复了字符串后,又出来重复的字符串。如字符串味'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:边界上的分隔字符。
string:输入的字符串。
limit:如果设置了 limit 参数并且是正数,则返回的数组包含最多 limit 个元素,而最后那个元素将包含 string 的剩余部分。如果 limit 参数是负数,则返回除了最后的 -limit 个元素外的所有元素。如果 limit 是 0,则会被当做 1。
使用正则
关于通过正则表达式进行字符串分割,php提供了split、preg_split 函数。preg_split() 函数,通常是比 split() 更快的替代方案。

array preg_split ( string pattern,stringsubject [, int limit=−1[,intflags = 0 ]] )

例题
将字符串 "http://blog.csdn.net/hsd2012/article/details/51152810"按照'/'进行分割:

解法一:

$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。

php正则表达式之回溯与固态分组

回溯
首先我们需要清楚什么是回溯,回溯就像是在走岔路口,当遇到岔路的时候就先在每个路口做一个标记。如果走了死路,就可以照原路返回,直到遇见之前所做过的标记,标记着还未尝试过的道路。如果那条路也走不能,可以继续返回,找到下一个标记,如此重复,直到找到出路,或者直到完成所有没有尝试过的路。首先我们看例题

$str='aageacwgewcaw';
$pattern='/a\w*c/i';
$str=preg_match($pattern, $str);

看到上面的程序,可能都清楚是什么意思,就是匹配$str是否包含这样一个由”a+0个或多个字母+c”不区分大小写的字符串。但是至于程序怎样去匹配的呢?匹配的过程中,回溯了多少次呢?



现在,如果我们将pattern改为pattern='/a\w*?c/i';又会回溯多少次呢?正确答案是回溯四次。

固态分组

固态分组,目的就是减少回溯次数, 使用(?>…)括号中的匹配时如果产生了备选状态,那么一旦离开括号便会被立即 引擎抛弃掉。举个典型的例子如: '\w+:'这个表达式在进行匹配时的流程是这样的,会优先去匹配所有的符合\w的字符,假如字符串的末尾没有':',即匹配没有找到冒号,此时触发回溯机制,他会迫使前面的\w+释放字符,并且在交还的字符中重新尝试与':'作比对。但是问题出现在这里: \w是不包含冒号的,显然无论如何都不会匹配成功,可是依照回溯机制,引擎还是得硬着头皮往前找,这就是对资源的浪费。所以我们就需要避免这种回溯,对此的方法就是将前面匹配到的内容固化,不令其存储备用状态!,那么引擎就会因为没有备用状态可用而只得结束匹配过程。大大减少回溯的次数。
如下代码,就不会进行回溯:

$str='nihaoaheloo';
$pattern='/(?>\w+):/';
$rs=preg_match($pattern, $str);

当然有的时候,又需慎用固态分组,如下,我要检查$str中是否包含以a结尾的字符串,很明显是包含的,但是因为使用了固态分组,反而达不到我们想要的效果

$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+)∗/';

url匹配

pattern='/^http(s?):\/\/(?:[A-za-z0-9-]+\.)+[A-za-z]{2,4}(:\d+)?(?:[\/\?#][\/=\?%\-&~`@[\]\':+!\.#\w]*)?/';

手机验证

pattern=′/1[3458]\d10/';
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容

  • 正则表达式概念源于 《神经网事件的表示法》论文中。 正则表达式就是用某种模式去匹配一类字符串的一种公式。 正则表达...
    单板小智阅读 768评论 0 1
  • python的re模块--细说正则表达式 可能是东半球最详细最全面的re教程,翻译自官方文档,因为官方文档写的是真...
    立而人阅读 22,809评论 4 46
  • 正则表达式是php中一个非常重要的知识点,通常用来查找和替换字符串,验证用户输入的信息格式是否符合规范,如邮件格式...
    雷雪松的简书阅读 698评论 0 7
  • Python中的正则表达式(re) import rere.match #从开始位置开始匹配,如果开头没有则无re...
    BigJeffWang阅读 7,030评论 0 99
  • 正则表达式介绍 正则表达式简介 正则表达式是用于描述字符排列和匹配模式的一种语法规则。它主要用于字符串的模式分割、...
    dptms阅读 10,898评论 1 9