PHP 正則表達(dá)式

什么叫正則表達(dá)式

正則表達(dá)式是對(duì)字符串進(jìn)行操作的一種邏輯公式涉波,就是用一些特定的字符組合成一個(gè)規(guī)則字符串该面,稱(chēng)之為正則匹配模式翼悴。

$p = '/apple/';
$str = "apple banna";
if (preg_match($p, $str)) {
    echo 'matched';
}

其中字符串'/apple/'就是一個(gè)正則表達(dá)式,他用來(lái)匹配源字符串中是否存在apple字符串谍椅。

PHP中使用PCRE庫(kù)函數(shù)進(jìn)行正則匹配,比如上例中的preg_match用于執(zhí)行一個(gè)正則匹配雏吭,常用來(lái)判斷一類(lèi)字符模式是否存在杖们。

正則表達(dá)式的基本語(yǔ)法

PCRE庫(kù)函數(shù)中,正則匹配模式使用分隔符與元字符組成摘完,分隔符可以是非數(shù)字描焰、非反斜線(xiàn)栅螟、非空格的任意字符。經(jīng)常使用的分隔符是正斜線(xiàn)(/)力图、hash符號(hào)(#) 以及取反符號(hào)(~)吃媒,例如:

/foo bar/
#^[^0-9]$#
~php~

如果模式中包含分隔符,則分隔符需要使用反斜杠(\)進(jìn)行轉(zhuǎn)義赘那。

/http:\/\//

如果模式中包含較多的分割字符募舟,建議更換其他的字符作為分隔符,也可以采用preg_quote進(jìn)行轉(zhuǎn)義拱礁。

$p = 'http://';
$p = '/'.preg_quote($p, '/').'/';
echo $p;

分隔符后面可以使用模式修飾符,模式修飾符包括:i, m, s, x等吴超,例如使用i修飾符可以忽略大小寫(xiě)匹配:

$str = "Http://www.imooc.com/";
if (preg_match('/http/i', $str)) {
    echo '匹配成功';
}

元字符與轉(zhuǎn)義

正則表達(dá)式中具有特殊含義的字符稱(chēng)之為元字符鸯乃,常用的元字符有:

\ 一般用于轉(zhuǎn)義字符
^ 斷言目標(biāo)的開(kāi)始位置(或在多行模式下是行首)
$ 斷言目標(biāo)的結(jié)束位置(或在多行模式下是行尾)
. 匹配除換行符外的任何字符(默認(rèn))
[ 開(kāi)始字符類(lèi)定義
] 結(jié)束字符類(lèi)定義
| 開(kāi)始一個(gè)可選分支
( 子組的開(kāi)始標(biāo)記
) 子組的結(jié)束標(biāo)記
? 作為量詞,表示 0 次或 1 次匹配赘娄。位于量詞后面用于改變量詞的貪婪特性遣臼。 (查閱量詞)
* 量詞,0 次或多次匹配
+ 量詞揍堰,1 次或多次匹配
{ 自定義量詞開(kāi)始標(biāo)記
} 自定義量詞結(jié)束標(biāo)記

//下面的\s匹配任意的空白符屏歹,包括空格,制表符蝙眶,換行符。[\s]代表非空白符式塌。[\s]+表示一次或多次匹配非空白符友浸。

$p = '/^我[^\s]+(蘋(píng)果|香蕉)$/';
$str = "我喜歡吃蘋(píng)果";
if (preg_match($p, $str)) {
    echo '匹配成功';
}

元字符具有兩種使用場(chǎng)景,一種是可以在任何地方都能使用武学,另一種是只能在方括號(hào)內(nèi)使用伦意,在方括號(hào)內(nèi)使用的有:

\ 轉(zhuǎn)義字符
^ 僅在作為第一個(gè)字符(方括號(hào)內(nèi))時(shí),表明字符類(lèi)取反
- 標(biāo)記字符范圍

其中^在反括號(hào)外面沛鸵,表示斷言目標(biāo)的開(kāi)始位置缆八,但在方括號(hào)內(nèi)部則代表字符類(lèi)取反,方括號(hào)內(nèi)的減號(hào)-可以標(biāo)記字符范圍栏妖,例如0-9表示0到9之間的所有數(shù)字奖恰。

//下面的\w匹配字母或數(shù)字或下劃線(xiàn)宛裕。

$p = '/[\w\.\-]+@[a-z0-9\-]+\.(com|cn)/';
$str = "我的郵箱是Spark.eric@imooc.com";
preg_match($p, $str, $match);
echo $match[0];

貪婪模式與懶惰模式

正則表達(dá)式中每個(gè)元字符匹配一個(gè)字符揩尸,當(dāng)使用+之后將會(huì)變的貪婪屁奏,它將匹配盡可能多的字符,但使用問(wèn)號(hào)?字符時(shí)勇边,它將盡可能少的匹配字符折联,既是懶惰模式。

  • 貪婪模式:在可匹配與可不匹配的時(shí)候奕坟,優(yōu)先匹配
    //下面的\d表示匹配數(shù)字
$p = '/\d+\-\d+/';
$str = "我的電話(huà)是010-12345678";
preg_match($p, $str, $match);
echo $match[0]; //結(jié)果為:010-12345678
  • 懶惰模式:在可匹配與可不匹配的時(shí)候清笨,優(yōu)先不匹配
$p = '/\d?\-\d?/';
$str = "我的電話(huà)是010-12345678";
preg_match($p, $str, $match);
echo $match[0]; //結(jié)果為:0-1

當(dāng)我們確切的知道所匹配的字符長(zhǎng)度的時(shí)候,可以使用{}指定匹配字符數(shù)

$p = '/\d{3}\-\d{8}/';
$str = "我的電話(huà)是010-12345678";
preg_match($p, $str, $match);
echo $match[0]; //結(jié)果為:010-12345678

使用正則表達(dá)式進(jìn)行匹配

使用正則表達(dá)式的目的是為了實(shí)現(xiàn)比字符串處理函數(shù)更加靈活的處理方式,因此跟字符串處理函數(shù)一樣跌帐,其主要用來(lái)判斷子字符串是否存在绊率、字符串替換、分割字符串脸狸、獲取模式子串等藐俺。
PHP使用PCRE庫(kù)函數(shù)來(lái)進(jìn)行正則處理,通過(guò)設(shè)定好模式卿啡,然后調(diào)用相關(guān)的處理函數(shù)來(lái)取得匹配結(jié)果菱父。
preg_match用來(lái)執(zhí)行一個(gè)匹配剑逃,可以簡(jiǎn)單的用來(lái)判斷模式是否匹配成功官辽,或者取得一個(gè)匹配結(jié)果,他的返回值是匹配成功的次數(shù)0或者1萤捆,在匹配到1次以后就會(huì)停止搜索乓梨。

$subject = "abcdef";
$pattern = '/def/';
preg_match($pattern, $subject, $matches);
print_r($matches); //結(jié)果為:Array ( [0] => def )

上面的代碼簡(jiǎn)單的執(zhí)行了一個(gè)匹配扶镀,簡(jiǎn)單的判斷def是否能匹配成功,但是正則表達(dá)式的強(qiáng)大的地方是進(jìn)行模式匹配臭觉,因此更多的時(shí)候蝠筑,會(huì)使用模式:

$subject = "abcdef";
$pattern = '/a(.*?)d/';
preg_match($pattern, $subject, $matches);
print_r($matches); //結(jié)果為:Array ( [0] => abcd [1] => bc )

通過(guò)正則表達(dá)式可以匹配一個(gè)模式,得到更多的有用的數(shù)據(jù)挽封。

查找所有匹配結(jié)果

preg_match只能匹配一次結(jié)果臣镣,但很多時(shí)候我們需要匹配所有的結(jié)果,preg_match_all可以循環(huán)獲取一個(gè)列表的匹配結(jié)果數(shù)組点待。

$p = "|<[^>]+>(.*?)</[^>]+>|i";
$str = "<b>example: </b><div align=left>this is a test</div>";
preg_match_all($p, $str, $matches);
print_r($matches);

可以使用preg_match_all匹配一個(gè)表格中的數(shù)據(jù):

$p = "/<tr><td>(.*?)<\/td>\s*<td>(.*?)<\/td>\s*<\/tr>/i";
$str = "<table> <tr><td>Eric</td><td>25</td></tr> <tr><td>John</td><td>26</td></tr> </table>";
preg_match_all($p, $str, $matches);
print_r($matches);

$matches結(jié)果排序?yàn)?matches[0]保存完整模式的所有匹配, $matches[1] 保存第一個(gè)子組的所有匹配弃舒,以此類(lèi)推聋呢。

正則表達(dá)式的搜索和替換

正則表達(dá)式的搜索與替換在某些方面具有重要用途,比如調(diào)整目標(biāo)字符串的格式削锰,改變目標(biāo)字符串中匹配字符串的順序等喂窟。

例如我們可以簡(jiǎn)單的調(diào)整字符串的日期格式:

$string = 'April 15, 2014';
$pattern = '/(\w+) (\d+), (\d+)/i';
$replacement = '$3, ${1} $2';
echo preg_replace($pattern, $replacement, $string); //結(jié)果為:2014, April 15

其中${1}與$1的寫(xiě)法是等效的央串,表示第一個(gè)匹配的字串碗啄,$2代表第二個(gè)匹配的。

通過(guò)復(fù)雜的模式饲宿,我們可以更加精確的替換目標(biāo)字符串的內(nèi)容胆描。

$patterns = array ('/(19|20)(\d{2})-(\d{1,2})-(\d{1,2})/',
                   '/^\s*{(\w+)}\s*=/');
$replace = array ('\3/\4/\1\2', '$\1 =');//\3等效于$3,\4等效于$4,依次類(lèi)推
echo preg_replace($patterns, $replace, '{startDate} = 1999-5-27'); //結(jié)果為:$startDate = 5/27/1999

//詳細(xì)解釋下結(jié)果:(19|20)表示取19或者20中任意一個(gè)數(shù)字短绸,(\d{2})表示兩個(gè)數(shù)字醋闭,(\d{1,2})表示1個(gè)或2個(gè)數(shù)字,(\d{1,2})表示1個(gè)或2個(gè)數(shù)字乐埠。^\s{(\w+)\s=}表示以任意空格開(kāi)頭的囚企,并且包含在{}中的字符,并且以任意空格結(jié)尾的,最后有個(gè)=號(hào)的烦衣。
用正則替換來(lái)去掉多余的空格與字符:

$str = 'one     two';
$str = preg_replace('/\s+/', ' ', $str);
echo $str; // 結(jié)果改變?yōu)?one two'
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末掩浙,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子衅澈,更是在濱河造成了極大的恐慌谬墙,老刑警劉巖经备,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件侵蒙,死亡現(xiàn)場(chǎng)離奇詭異傅蹂,居然都是意外死亡份蝴,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)浸卦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)请敦,“玉大人,你說(shuō)我怎么就攤上這事萤皂∠灰” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵入录,是天一觀的道長(zhǎng)僚稿。 經(jīng)常有香客問(wèn)我蟀伸,道長(zhǎng),這世上最難降的妖魔是什么蠢络? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任迟蜜,我火速辦了婚禮,結(jié)果婚禮上髓霞,老公的妹妹穿的比我還像新娘酸茴。我一直安慰自己,他們只是感情好笼痹,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布凳干。 她就那樣靜靜地躺著被济,像睡著了一般。 火紅的嫁衣襯著肌膚如雪只磷。 梳的紋絲不亂的頭發(fā)上钮追,一...
    開(kāi)封第一講書(shū)人閱讀 48,970評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音轧叽,去河邊找鬼刊棕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛网严,可吹牛的內(nèi)容都是我干的嗤无。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼休雌,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了杈曲?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤趣钱,失蹤者是張志新(化名)和其女友劉穎胚宦,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體井联,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡烙常,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年鹤盒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了侦锯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡终议,死狀恐怖葱蝗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情皂甘,我是刑警寧澤悼凑,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站渐夸,受9級(jí)特大地震影響渔欢,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜苫幢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一韩肝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧哀峻,春花似錦、人聲如沸漾峡。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至锋谐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間乾戏,已是汗流浹背三热。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工就漾, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人摆出。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像首妖,于是被迫代替她去往敵國(guó)和親偎漫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

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

  • 正則表達(dá)式介紹 正則表達(dá)式簡(jiǎn)介 正則表達(dá)式是用于描述字符排列和匹配模式的一種語(yǔ)法規(guī)則有缆。它主要用于字符串的模式分割象踊、...
    dptms閱讀 10,907評(píng)論 1 9
  • 正則表達(dá)式是php中一個(gè)非常重要的知識(shí)點(diǎn)舌仍,通常用來(lái)查找和替換字符串,驗(yàn)證用戶(hù)輸入的信息格式是否符合規(guī)范通危,如郵件格式...
    雷雪松的簡(jiǎn)書(shū)閱讀 700評(píng)論 0 7
  • 因?yàn)楸容^重要,所以還是單獨(dú)拿出來(lái)作一篇文章灌曙,好好學(xué)習(xí)一下菊碟。 正則表達(dá)式:Regular expression 定義...
    齊舞647閱讀 983評(píng)論 3 7
  • 正則表達(dá)式是程序開(kāi)發(fā)中一個(gè)重要的元素,它提供用來(lái)描述或匹配文本的字符串逆害,如特定的字符、詞或算式等蚣驼。但在某些情況下魄幕,...
    sara_org閱讀 1,085評(píng)論 1 5
  • 今天的日常示范坐椅子,龍龍按照示范走到椅子前颖杏,站好纯陨,往后看一看,坐下留储,小腳并并攏翼抠,小手放在膝蓋上,龍龍坐椅子的姿勢(shì)...
    a81c671c0ae2閱讀 312評(píng)論 0 0