正向預查(?=pattern)(?<=pattern)
反向預查(?!=pattern)(?<!pattern)
(?=pattern)
正向預查,在任何匹配 pattern 的字符串開始處匹配查找字符串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以後使用。表示的後面必須有
一個例子 (?=pattern)
<?php
$regex = '/iphone(?=3|4|5)\d/';
$str = 'iphone3 iphone4 iphone8';
if(preg_match_all($regex, $str, $matches)){
var_dump($matches);
}
?>
打印出來
array 0 => array 0 => 'iphone3' (length=7) 1 => 'iphone4' (length=7)
還有一個例子(?<=pattern)
<?php
$str = '<div class=aa name=wahaha>11111</div><div class=pp name=yoursister>11111</div><div class=aa name=cc>11111</div>';
$regex = '/(?<=class\=)aa\s*name=([a-z]*)/';
//打印 查找class爲aa 的name
if(preg_match_all($regex, $str, $matches)){
var_dump($matches[1]);
}
?>
打印出來
(?<=pattern)
負向預查,在任何不匹配 pattern 的字符串開始處匹配查找字符串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以後使用
一個例子
<?php
$str = 'iphone 3000,samsung 4000,huawei 5000,moto 6000';
$regex = '/(^|,)(?!samsung)[a-z]+\s(\d+)/';
//打印 查找除了samsung的所有價格
if(preg_match_all($regex, $str, $matches)){
var_dump($matches[2]);
}
?>
打印結果
array 0 => '3000' (length=4) 1 => '5000' (length=4) 2 => '6000' (length=4)
(?<!pattern)
<?php
$str = 'iphone5000,samsung5000,moto5000,huawei5000,xiaomi1000';
$regex = '/([a-z]+)(?<!samsung)5000/';
//打印 查找價格5000非samsung的東東
if(preg_match_all($regex, $str, $matches)){
var_dump($matches[1]);
}
?>
打印
array 0 => 'iphone' (length=6) 1 => 'moto' (length=4) 2 => 'huawei' (length=6)
捕獲組就是把正則表達式中子表達式匹配的內容,保存到內存中以數字編號或顯式命名的組裏,方便後面引用。當然,這種引用既可以是在正則表達式內部,也可以是在正則表達式外部。
捕獲組有兩種形式,一種是普通捕獲組,另一種是命名捕獲組,通常所說的捕獲組指的是普通捕獲組。
一個簡單的例子
<?php
$str = '111111111111111';
$str1 = '12222222222';
$regex = '/^(\d)\1+$/';//匹配這個字符串的數字全是一樣的
preg_match_all($regex, $str, $matches);
echo $matches[0][0]."<br>"; //能夠匹配到
preg_match_all($regex, $str1, $matches);
echo empty($matches[0]); //不能夠匹配到了
?>
捕獲是佔內存的,有時候爲了看的明白點會用括號,但是又不想佔用內存,可以用非捕獲
(?:pattern)
一個例子
<?php
$str = '<div id="aaaa">qwewe</div>';
$regex = '/<div\s*(?:id=[\'\"][a-z]+[\'\"])>(.*?)<\/div>/';
$regex1 = '/<div\s*(id=[\'\"][a-z]+[\'\"])>(.*?)<\/div>/';
if(preg_match_all($regex, $str, $matches)){
var_dump($matches[1]);//qwewe
}
if(preg_match_all($regex1, $str, $matches)){
var_dump($matches[1]);//id="aaaa"
}
?>
命名捕獲組
命名捕獲組通過顯式命名,可以通過組名方便的訪問到指定的組,而不需要去一個個的數編號,同時避免了在正則表達式擴展過程中,捕獲組的增加或減少對引用結果導致的不可控。
不過容易忽略的是,命名捕獲組也參與了編號的,在只有命名捕獲組的情況下,捕獲組的編號也是按照“(”出現的順序,從左到右,從1開始進行編號的 。
一個例子
<?php
$str = '2012 12 31';
$regex = '/(?P<year>\d{4})\s*(?P<month>\d{2})\s*(?P<day>\d{2})/';
if(preg_match_all($regex, $str, $matches)){
var_dump($matches["year"]);//2012
var_dump($matches["month"]);//12
var_dump($matches["day"]);//31
}
?>
preg_quote
string preg_quote ( string $str [, string $delimiter ] )
以 str 爲參數並給其中每個屬於正則表達式語法的字符前面加上一個反斜線。
正則表達式的特殊字符包括:. \ + * ? [ ^ ] $ ( ) { } = ! < > | :
$patten = "\ + * ? [ ^ ] $ ( ) { } = ! < > | ";
echo preg_quote($patten);
//輸出爲 \\ \+ \* \? \[ \^ \] \$ \( \) \{ \} \= \! \< \> \|
preg_replace
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit ] )
在 subject 中搜索 pattern 模式的匹配項並替換爲 replacement 。如果指定了 limit ,則僅替換 limit 個匹配,如果省略 limit 或者其值爲 -1,則所有的匹配項都會被替換。
replace強大的地方在支持反向引用,被捕獲的東西可以用$n來獲取, $0表示整體匹配的東西,$1表示第一個小括號裏面的東西,$2就是第2個小括號裏面的東西,依次類推.....。當讓 替換是建立在正則匹配成功的基礎上,匹配不成功不經行替換.
一些例子
$str = "aaaaaaaaaa";
echo preg_replace("/bbb(c)/","$1",$str);
//匹配失敗 不經行替換
$str = "aa bb cc dd";
echo preg_replace("/aa/","$0$0$0",$str);
//aaaaaa bb cc dd
//匹配成功 $0表示匹配整個內容 3個$0就是 3個aa 就打出了6個aa
$str = "c4444c223355bbbbbbb666";
echo preg_replace("/(b)\d+/","$1",$str);
//cc223355bbbbbbb
//$1是匹配一個捕獲組裏面的東西,是b,然後整體匹配出的是b666,要替換成$1(就是b), 所以只有b後面的數字全部不見了
$str = '<a id="cc" class="xx">a</a><a href="#" class="xx">b</a><div class="vv"></div><a class=\'b\'>c</a><p class="bbbbb">d</p>';
echo preg_replace("/(<a.*?class=)(['\"]).*?\\2/","$1\"T_T\"",$str);
//把所有a 標籤的class 替換成 T_T
preg_replace_callback
mixed preg_replace_callback ( mixed $pattern , callback $callback , mixed $subject [, int $limit ] )
用回調函數執行正則表達式的搜索和替換
本函數的行爲幾乎和 preg_replace() 一樣,除了不是提供一個 replacement 參數,而是指定一個 callback 函數。該函數將以目標字符串中的匹配數組作爲輸入參數,並返回用於替換的字符串。
回調函數只有一個參數 是個數組 比如是$matches $matches[0]是整體的匹配項,$matches[1]是第一個捕獲組裏面的東西.
這是一個好東西 對於一些特殊需要很有好處,比如說把 <div>裏面的正數顯示紅色 ,負數顯示綠色,0顯示黑色
$str = "<div>123</div><div>-0.1</div><div>-23</div><div>0</div><div>0.1</div>";
function cb($matches){
$num = (float)$matches[1];
if($num>0){
$color = "#f00";
}else if($num==0){
$color = "#000";
}else{
$color = "#0F0";
}
return '<div style="color:'.$color.'">'.$matches[1].'</div>';
}
echo preg_replace_callback("/<div>(.*?)<\/div>/","cb",$str);
preg_match
int preg_match ( string $pattern , string $subject [, array $matches [, int $flags ]] )
進行正則表達式匹配。
在 subject 字符串中搜索與 pattern 給出的正則表達式相匹配的內容。
如果提供了 matches ,則其會被搜索的結果所填充。$matches[0] 將包含與整個模式匹配的文本,$matches[1] 將包含與第一個捕獲的括號中的子模式所匹配的文本,以此類推。
preg_match返回1或者0,0表示不匹配.
一個字符串裏面符合查找條件的可能很多, 但是preg_match只查找第一個.
$str = '<div class="xx">1111</div><span>xxx</span><div class="gg">ggg</div><div>xxx</div><div class="xx">222</div>';
$patten = '/<div class="xx">(.*?)<\/div>/';
print_r(preg_match($patten,$str,$matches));
print_r($matches); //查找說有div class爲xx的內容
preg_match_all
int preg_match_all ( string $pattern , string $subject , array $matches [, int $flags ] )
會搜索字符串中所有的匹配項
$matches[0]是整個的匹配項 是數組,$matches[1]是一個捕獲的匹配項 是數組,一次類推........
preg_match_all返回的匹配項的數組的長度
$str = "<span>1111</span><span>2222</span><span><div>3333</div></span><span>4444444</span><p>555555</p><span>6666666</span>";
$patten = '/<span>(.*?)<\/span>/';
print_r(preg_match_all($patten,$str,$matches));
print_r($matches[0]);
print_r($matches[1]);