PHP強(qiáng)化之11 - PCRE正則表達(dá)式

----- 最近更新【2021-12-15】-----

PHP強(qiáng)化系列--目錄

一、簡介

正則表達(dá)式是一種描述字符串結(jié)果的語法規(guī)則,是一個(gè)特定的格式化模式盈咳,可以匹配圃伶、替換怜校、截取匹配的字符串胎围。

二、語法

當(dāng)使用 PCRE 函數(shù)的時(shí)候药版,模式需要由分隔符閉合包裹辑舷。分隔符可以使任意非字母數(shù)字喻犁、非反斜線槽片、非空白字符。經(jīng)常使用的分隔符是正斜線(/)肢础、hash符號(hào)(#) 以及取反符號(hào)(~)还栓。

合法模式示例:

/<\/\w+>/
#^[^0-9]$#
|(\d{3})-\d+|Sm       ## 可以在結(jié)束分隔符后面增加模式修飾符
/^(?i)php[34]/
{^\s+(\s+)?$}       ## 括號(hào)樣式的分隔符,左括號(hào)和右括號(hào)分別作為 開始和結(jié)束 分隔符传轰。
%[a-zA-Z0-9_-]%

非法模式示例:

/href='(.*)'     ## 缺失結(jié)束分隔符
/\w+\s*\w+/J     ## 未知模式修飾符"J"
1-\d3-\d3-\d4|     ## 缺失開始分隔符

如果分隔符需要在模式內(nèi)進(jìn)行匹配剩盒,它必須使用反斜線進(jìn)行轉(zhuǎn)義。如果分隔符經(jīng)常在 模式內(nèi)出現(xiàn)慨蛙, 一個(gè)更好的選擇就是是用其他分隔符來提高可讀性辽聊。

/http:\/\//
#http://#

三、正則表達(dá)式

由上面介紹的合法分隔符所包含的部分期贫,就是我們主要去了解的正則表達(dá)式部分了跟匆。下面我將對(duì)一些常用的部分做一下歸類:

1、 原子
原子是組成正則表達(dá)式的基本單位通砍,在分析正則表達(dá)式時(shí)玛臂,應(yīng)作為一個(gè)整體。
包括以下內(nèi)容:
> 單個(gè)字符封孙、數(shù)字迹冤,如a-z,A-Z虎忌,0-9泡徙。
> 模式單元,如(ABC)可以理解為由多個(gè)原子組成的大的原子膜蠢。
> 原子表锋勺,如 [ABC]蚀瘸。
> 重新使用的模式單元,如:\1
> 普通轉(zhuǎn)義字符庶橱,如:\d贮勃, \D, \w
> 轉(zhuǎn)義元字符苏章,如:\*寂嘉,\.
> 元字符

2、元字符

  • ^ 斷言目標(biāo)的開始位置(或在多行模式下是行首)
  • $ 斷言目標(biāo)的結(jié)束位置(或在多行模式下是行尾)
  • . 表示任意一個(gè)除換行符之外的字符
  • [] 表示單個(gè)字符的原子表
    [^] 表示除中括號(hào)內(nèi)原子之外的任何字符 是[]的取反
    [-] 表示允許的范圍枫绅,如[0-9]表示任意一位數(shù)字
  • {m} 表示對(duì)前面原子的數(shù)量控制泉孩,表示是m次
    {m,} 表示對(duì)前面原子的數(shù)量控制,表示是至少m次
    {m,n}表示對(duì)前面原子的數(shù)量控制并淋,表示是m到n次
  • * 量詞寓搬,0 次或多次匹配,等價(jià)于{0,}
  • + 量詞县耽,1 次或多次匹配句喷,等價(jià)于{1,}
  • ? 作為量詞,表示 0 次或 1 次匹配兔毙,等價(jià)于{0,1} 唾琼。位于量詞后面用于改變量詞的貪婪特性。
  • () 表示一個(gè)整體原子澎剥,【還有一個(gè)子存儲(chǔ)單元的作用】锡溯。 也可以使用?:來拒絕子存儲(chǔ)。 (?:.*?)
  • | 開始一個(gè)可選分支

3哑姚、常用轉(zhuǎn)義字符

說明
\d 匹配一個(gè)數(shù)字祭饭;等價(jià)于[0-9]
\D 匹配除數(shù)字以外任何一個(gè)字符;等價(jià)于[^0-9]
\w 匹配一個(gè)英文字母叙量、數(shù)字或下劃線倡蝙;等價(jià)于[0-9a-zA-Z_]
\W 匹配除英文字母、數(shù)字和下劃線以外任何一個(gè)字符宛乃;等價(jià)于[^0-9a-zA-Z_]
\s 匹配一個(gè)空白字符悠咱;等價(jià)于[\f\n\r\t\v]
\S 匹配除空白字符以外任何一個(gè)字符;等價(jià)于[^\f\n\r\t\v]
\n 匹配一個(gè)換行符
\r 匹配一個(gè)回車符

4征炼、模式修整符

  • i 表示不區(qū)分大小寫析既;
    如:"/[a-zA-Z]/" 等價(jià)于 "/[a-z]/i"
  • s 表示匹配視為單行
    如果設(shè)置了這個(gè)修飾符,模式中的點(diǎn)號(hào)元字符匹配所有字符谆奥,包含換行符眼坏。如果沒有這個(gè) 修飾符,點(diǎn)號(hào)不匹配換行符。
  • U 表示拒絕貪婪匹配
    通過量詞后緊跟? 的方式可以使其成為貪婪的宰译,注意這和 模式修整符U 是不能同時(shí)使用的檐蚜,只能取其一。
  • x 忽略空白字符

5沿侈、惰性匹配

函數(shù)符 描述
*? 零次或多次闯第,但盡可能少的匹配
+? 一次或多次,但盡可能少的匹配
?? 0次或1次缀拭,但盡可能少的匹配
{n,}? 至少n次咳短,但盡可能少的匹配
{n,m}? n到m次 ,但盡可能少的匹配

四蛛淋、相關(guān)函數(shù)

1咙好、preg_match
int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )
搜索subject與pattern給定的正則表達(dá)式的一個(gè)匹配。

如果提供了參數(shù)matches褐荷,它將被填充為搜索結(jié)果勾效。 $matches[0]將包含完整模式匹配到的文本, $matches[1] 將包含第一個(gè)捕獲子組匹配到的文本叛甫,以此類推层宫。

函數(shù)返回值為0或1。

如:

$label = 'content/112abc';
$a = preg_match('#content/(\d+)(\w*)#i', $label, $mc);
var_dump($a);
var_dump($mc);

結(jié)果:

int(1)
array(3) {
  [0] =>
  string(14) "content/112abc"
  [1] =>
  string(3) "112"
  [2] =>
  string(3) "abc"
}

注意:
preg_match() 第一次匹配成功后就會(huì)停止匹配合溺,如果要實(shí)現(xiàn)全部結(jié)果的匹配卒密,即搜索到subject結(jié)尾處缀台,則需使用preg_match_all() 函數(shù)棠赛。

2、preg_match_all
int preg_match_all ( string $pattern , string $subject [, array &$matches [, int $flags = PREG_PATTERN_ORDER [, int $offset = 0 ]]] )
搜索subject中所有匹配pattern給定正則表達(dá)式 的匹配結(jié)果并且將它們以flag指定順序輸出到matches中膛腐。在第一個(gè)匹配找到后, 子序列繼續(xù)從最后一次匹配位置搜索睛约。

該函數(shù)返回完整匹配次數(shù)(可能是0),或者如果發(fā)生錯(cuò)誤返回FALSE哲身。

參數(shù)說明:

參數(shù) 說明
pattern 正則表達(dá)式
subject 需要匹配檢索的對(duì)象
matches 存儲(chǔ)匹配結(jié)果的數(shù)組
flags 可選辩涝,指定匹配結(jié)果放入 matches 中的順序,可供選擇的標(biāo)記有:
1)PREG_PATTERN_ORDER:默認(rèn)勘天,對(duì)結(jié)果排序使 $matches[0] 為全部模式匹配的數(shù)組怔揩,$matches[1] 為第一個(gè)括號(hào)中的子模式所匹配的字符串組成的數(shù)組,以此類推
2)PREG_SET_ORDER:對(duì)結(jié)果排序使 $matches[0] 為第一組匹配項(xiàng)的數(shù)組脯丝,$matches[1] 為第二組匹配項(xiàng)的數(shù)組商膊,以此類推
3)PREG_OFFSET_CAPTURE:如果設(shè)定本標(biāo)記,對(duì)每個(gè)出現(xiàn)的匹配結(jié)果也同時(shí)返回其附屬的字符串偏移量

如:

$userinfo = "Name: <b>PHP</b> <br> Title: <b>Programming Language</b>";
preg_match_all ("/<b>(.*)<\/b>/U", $userinfo, $pat_array);
print_r($pat_array[0]);

結(jié)果:

Array
(
    [0] => <b>PHP</b>
    [1] => <b>Programming Language</b>
)

3宠进、preg_replace
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
搜索subject中匹配pattern的部分晕拆, 以replacement進(jìn)行替換。

$string = 'April 15, 2003';
$pattern = '/(\w+) (\d+), (\d+)/i';
$replacement = '${1}1,$3';
echo preg_replace($pattern, $replacement, $string);
//輸出:April1,2003

4材蹬、preg_split
通過一個(gè)正則表達(dá)式分隔給定字符串.
array preg_split ( string $pattern , string $subject [, int $limit = -1 [, int $flags = 0 ]] )

如:

//使用逗號(hào)或空格(包含" ", \r, \t, \n, \f)分隔短語
$keywords = preg_split("/[\s,]+/", "hypertext language, programming");
print_r($keywords);

結(jié)果:

Array
(
    [0] => hypertext
    [1] => language
    [2] => programming
)

5实幕、其它
1)preg_grep
array preg_grep ( string $pattern , array $input [, int $flags = 0 ] )
返回給定數(shù)組input中與模式pattern 匹配的元素組成的數(shù)組

2)preg_quote
string preg_quote ( string $str [, string $delimiter = NULL ] )
轉(zhuǎn)義正則表達(dá)式字符

五吝镣、經(jīng)典實(shí)例

1、關(guān)于URL
1)從url中取得主機(jī)名

$url = "http://blog.nosee123.com/index.php";
preg_match("/^(http:\/\/)?([^\/]+)/i",$url, $matches);
$host = $matches[2]; 
echo $host;  // 結(jié)果為:string(15) "blog.nosee123.com"

2)判斷字符串是否為url

/^http(s?):\/\/([\w]+\.?)++\/*[\w\.]*\??[\w=&\+\%]*/is

2昆庇、關(guān)于Email
1)判斷字符串是否是郵箱

/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/
^[a-zA-Z0-9][a-zA-Z0-9._-]*@[a-zA-Z0-9]+\.[a-zA-Z0-9\.]+$

2)只允許英文字母末贾、數(shù)字、下劃線整吆、英文句號(hào)未舟、以及中劃線組成

//gaozihang-001@gmail.com 
^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$

3、關(guān)于字符
1)任意一位大小字母或數(shù)字下劃線:

[A-Za-z0-9_]   等價(jià)于  \w

4掂为、數(shù)字相關(guān)
1)手機(jī)號(hào)碼

 [1][3-8][0-9]{9}    //粗略匹配
^((13[0-9])|147|(15[0-35-9])|180|182|(18[5-9]))[0-9]{8}$

Or:

# 中國大陸手機(jī)號(hào) (移動(dòng)/聯(lián)通/電信):
/^1(3[0-9]|4[5-9]|5[0-35-9]|66|7[013-8]|8[0-9]|9[89])\d{8}$/
# 中國移動(dòng):
/^1(34[0-8]|3[5-9\d]|440|4[78]\d|5[0-27-9]\d|70[356]|78\d|8[2-478]\d|98\d)\d{7}$/
# 中國聯(lián)通:
/^1(3[0-2]\d|4[56]\d|5[56]\d|66\d|70[4789]|71|7[56]\d|8[56]\d)\d{7}$/
# 中國電信:
/^1(3[3]\d|349|410|49\d|53\d|70[0-2]|7[37]\d|740|8[019]\d|99\d)\d{7}$/

2)ip地址

\d+\.\d+\.\d+\.\d+

3)身份證

^(([0-9]{15})|([0-9]{18})|([0-9]{17}x))$

5裕膀、中文匹配

中文匹配:UTF-8漢字編碼范圍是0x4e00-0x9fa5;在ANSI(gb2312)環(huán)境下勇哗,0xb0-0xf7昼扛,0xa1-0xfe。
UTF-8要使用u模式修正符使模式字符串被當(dāng)成UTF-8欲诺,在ANSI(gb2312環(huán)境下)抄谐,使用chr將Ascii碼轉(zhuǎn)換為字符。

[\x{4e00}-\x{9fa5}]    #utf-8中文
[\u4e00-\u9fa5]    #通用

5扰法、HTML頁面的匹配

1)取出頁面中所有img標(biāo)簽的src值

'/<img.*?src=("|\')(.*?)("|\').*?\/?>/i'

2)判斷是否為a鏈接

/<a .*?href="(.*?)".*?>/is

參考:

官方手冊(cè):http://php.net/manual/zh/pcre.pattern.php

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蛹含,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子塞颁,更是在濱河造成了極大的恐慌浦箱,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件祠锣,死亡現(xiàn)場離奇詭異酷窥,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)伴网,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門蓬推,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人澡腾,你說我怎么就攤上這事沸伏。” “怎么了动分?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵毅糟,是天一觀的道長。 經(jīng)常有香客問我刺啦,道長留特,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮蜕青,結(jié)果婚禮上苟蹈,老公的妹妹穿的比我還像新娘。我一直安慰自己右核,他們只是感情好慧脱,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著贺喝,像睡著了一般菱鸥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上躏鱼,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天氮采,我揣著相機(jī)與錄音,去河邊找鬼染苛。 笑死鹊漠,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的茶行。 我是一名探鬼主播躯概,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼畔师!你這毒婦竟也來了娶靡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤看锉,失蹤者是張志新(化名)和其女友劉穎姿锭,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體度陆,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡艾凯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年献幔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了懂傀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蜡感,死狀恐怖蹬蚁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情郑兴,我是刑警寧澤犀斋,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站情连,受9級(jí)特大地震影響叽粹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一虫几、第九天 我趴在偏房一處隱蔽的房頂上張望锤灿。 院中可真熱鬧,春花似錦辆脸、人聲如沸但校。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽状囱。三九已至,卻和暖如春倘是,著一層夾襖步出監(jiān)牢的瞬間亭枷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國打工搀崭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留奶栖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓门坷,卻偏偏與公主長得像宣鄙,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子默蚌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 概述 正則表達(dá)式是一種描述字符串結(jié)果的語法規(guī)則冻晤,是一個(gè)特定的格式化模式,可以匹配绸吸、替換鼻弧、截取匹配的字符串。常用的語...
    醉于麥田閱讀 494評(píng)論 0 0
  • 正則表達(dá)式介紹 正則表達(dá)式簡介 正則表達(dá)式是用于描述字符排列和匹配模式的一種語法規(guī)則锦茁。它主要用于字符串的模式分割攘轩、...
    dptms閱讀 10,910評(píng)論 1 9
  • 關(guān)于PCRE的介紹以及實(shí)現(xiàn)正則表達(dá)式功能的所有說明,都可以在官方手冊(cè)中看到:正則表達(dá)式(兼容 Perl) 一码俩、認(rèn)識(shí)...
    拿破侖蛋糕閱讀 1,609評(píng)論 0 1
  • PHP常用正則表達(dá)式匯總 正則表達(dá)式在 PHP 中的應(yīng)用在 PHP 應(yīng)用中度帮,正則表達(dá)式主要用于: 正則匹配:根據(jù)正...
    DragonRat閱讀 1,459評(píng)論 0 4
  • 原創(chuàng) 2017年12月28日 文/茹云 正如我所遇到的問題一樣,開始對(duì)哲學(xué)或者工具類的書籍總是半截不通稿存。其實(shí)笨篷,...
    茹云閱讀 286評(píng)論 0 2