PHP 正則表達式詳解

因為比較重要,
所以還是單獨拿出來作一篇文章粘招,
好好學習一下稿存。

正則表達式:Regular expression

定義:是負責對字符串做解析對比,從而分析出字符串的構(gòu)成著瓶,以便進一步對字符串做相關(guān)的處理联予。

注:正則表達式允許用戶通過使用某種特殊字符構(gòu)建匹配模式,然后把匹配模式與文件中的數(shù)據(jù)材原、程序輸入或者Web頁面的表單輸入等目標對象進行比較沸久,根據(jù)這些輸入中是否包含匹配模式,來執(zhí)行相應的程序余蟹。

正則表達式的語法:(基礎(chǔ))

元字符:
^ :匹配指定字符串開頭的字符串
$ :匹配指定字符串結(jié)尾的字符串
. :匹配除\n之外的任何單個字符卷胯,代替任何字符
[] :匹配指定范圍內(nèi)的單個字符,代替指定字符
| :在多項之間選擇一個進行匹配
\ :轉(zhuǎn)義字符
() :標記子表達式的開始和結(jié)束位置
* :匹配其左邊的子表達式0次或多次
+ :匹配其左邊的子表達式1次或多次
? :匹配其左邊的子表達式0次或1次

限定符:
{n}:表示匹配該限定符左邊字符n次
{n,}:表示匹配該限定符左邊至少n次
{n,m}:表示匹配該限定符左邊至少n次威酒,最多m次

轉(zhuǎn)義字符:
\n :一個換行符窑睁。等價于\x0a和\cJ
\r :一個回車符。等價于\x0d和\cM
\s :任何空白字符葵孤,包括空格担钮、制表符、換頁符等尤仍。等價于[\f\n\r\t\v]
\S :任何非空白字符裳朋。等價于[^\f\n\r\t\v]
\t :一個制表符。等價于\x09和\cI
\v :一個垂直制表符。等價于\x0b和\cK
\f :一個換頁符鲤嫡。等價于\x0c和\cL
\cx :由x指明的控制字符送挑。

字符類:
[[:alpha:]] :匹配任何字母
[[:digit:]] :匹配任何數(shù)字
[[:alnum:]] :匹配任何字母和數(shù)字
[[:space:]] :匹配任何空白字符
[[:upper:]] :匹配任何大寫字母
[[:lower:]] :匹配任何小寫字母
[[:punct:]] :匹配任何標點符號
[[:xdigit:]] :匹配任何16進制數(shù)字,相當于[0-9a-fA-F]
[[:blank:]] :匹配空格和Tab暖眼,等價于[\t]
[[:cntrl:]] :匹配所有ASCII 0到31之間的控制符
[[:graph:]] :匹配所有的可打印字符惕耕,等價于[^ \t\n\r\f\v]
[[:print:]] :匹配所有的可打印字符和空格,等價于[^\t\n\r\f\v]

反義:
\W :匹配任意不是字母诫肠,數(shù)字司澎,下劃線或漢子的字符
\S :匹配任意不是空白符的字符
\D :匹配任意非數(shù)字的字符
\B :匹配不是單詞開頭或結(jié)束的位置

//模式:舉例

^once  //匹配給定模式開頭的字符串

PHP$   //匹配給定模式結(jié)尾的字符串 

^Python$  //精確定位:指定字符串

b.s   //這個單詞可以是bes、bis栋豫、bos....

b[eiou]s //這個單詞只匹配 bes挤安、bis、bos丧鸯、bus

b(a|e|i|o|oo)s  //這個單詞匹配bas蛤铜、bes、bis丛肢、bos围肥、boos

pe* //匹配perl、peel蜂怎、pet穆刻、port...

co+  //匹配come、code杠步、cool氢伟、co...

a{3}  //匹配aaa、cacaaad幽歼、aacoaaao...

a{3,}  //匹配aaa腐芍、aaab、caaaaa...

a{1,3}b  //匹配ab试躏、aab猪勇、aaab...

ab*  //和ab{0,}同義,a颠蕴、ab泣刹、abb...

ab+  //和ab{1,}同義,ab犀被、abb...

ab?  //和ab{0,1}同義椅您,a、ab

a?b+$  //匹配ab寡键、abb...

a(bc)*  //匹配a掀泳、abc、abcbc...

[ab]  //與a|b同義,匹配a员舵、b

[a-d]  //與a|b|c|d及[abcd]同義脑沿,匹配a、b马僻、c庄拇、d。

^[a-zA-Z_]$  //匹配所有的只有字母和下劃線的字符串韭邓。如果不加^和$措近,凡是含有字母和下劃線的字符都會被匹配。

^[a-zA-Z0-9_]{1,}$  //匹配所有包含一個以上的字母女淑、數(shù)字或下劃線的字符串瞭郑。

^[0-9]{1,}$  //匹配所有正數(shù)

^\-{0,1}[0-9]{1,}$  //匹配所有的整數(shù)

^\-{0,1}[0-9]{0,}\.{0,1}[0-9]{0,}$  //匹配所有小數(shù)

PHP有兩大類函數(shù)支持正則表達式,
一類是POSIX擴展函數(shù)(PHP5.2之后棄用)鸭你,
另一類是Perl兼容的正則表達式函數(shù)(PHP4.0后支持)屈张。

POSIX擴展正則表達式函數(shù)(PHP5后棄用):

ereg() :字符串的正則匹配函數(shù)
ereg_replace() :區(qū)分大小寫的正則表達式替換
eregi() :不區(qū)分大小寫的正則表達式匹配
eregi_replace() :不區(qū)分大小寫的正則表達式替換
split() :用正則表達式將字符串分割到數(shù)組中
spliti() :用正則表達式不區(qū)分字母大小寫將字符串分割到數(shù)組中
sql_regcase() :產(chǎn)生用于不區(qū)分大小的正則表達式

//正則表達式匹配函數(shù)
int ereg(string $pattern, string $string [, array &regs]);  //區(qū)分大小寫
int eregi(string $pattern, string $string [, array &regs]);  //不區(qū)分大小寫

<?php
$arr_date = array(
'2008-06-01',
'1996-11-29',
'2005-0x-10',
'12-12-12',
'2012-12-25 00:10:20'
);

for ($i=0; $i<5; ++$i){
      $date = $arr_date[$i];
      if(ereg("([0-9]){4})-([0-9]{1,2})-([0-9]{1,2})", $date , $regs)){
              echo "日期字符串$date 符合'YYYY-MM-DD'格式:";
              echo "$regs[1].$regs[2].$regs[3]<br/><br/>";
      }else{
              echo "<b>日期字符串$date 不符合'YYYY-MM-DD'格式</b><br/><br/>";
      }
}
?>

//替換匹配字符串的函數(shù)
string ereg_replace(string $pattern, string $replacement, string $string);  //區(qū)分大小寫
string eregi_replace(string $pattern, string $replacement, string $string);  //不區(qū)分大小寫

<?php
$str = "You have a car , I have a Car , We have cARs!"  //源字符串
echo "<b>替換前字符串為:</b><br/>";
echo $str;
echo "<br/>";
echo "<br/>";

$pattern = "car";    //匹配字符串
$replacement = "Apple";   //替換后字符串
$str_rpc = eregi_replace($pattern,$replacement,$str);
echo "<b>替換后字符串為:</b><br/>";
echo $str_rpc;
?>

//根據(jù)正則表達式分割字符串函數(shù)
array split(string $pattern, string $string [, int $limit]);

<?php
$str = "aaa~bbb~ccc~ddd";  //定義字符串變量
echo "字符串截取前:$str";
echo "<br/>";
echo "<br/>";

$sep_arr = split("~",$str);
echo "<b>字符串截取后:</b><br/>";  //分割字符串變量$str
echo "<pre>";

print_r($str_arr);
?>

//生成正則表達式的函數(shù)
string sql_regcase(string $string);   //不區(qū)分大小正則表達式

<?php
$str = "K#V3050"
echo "<b>原字符串:</b><br/>$str";    //定義字符串變量
echo "<br/>";
echo "<br/>";

$reg_str = sql_regcase($str);
echo "<b>生成的正則表達式為:</b><br/>";  //生成正則表達式
echo $reg_str;
?>

PERL兼容正則表達式函數(shù)(PHP4后支持,重點)

PERL兼容正則表達式使用修正符苇本,
所謂修正符袜茧,是指正則表達式最后的補充說明菜拓。
另外瓣窄,
PERL兼容正則表達式中所有的模式前后都需要加/

修正符
i :匹配時忽略大小寫
m :除了匹配^$整個字符串開頭和結(jié)尾,還匹配其中的換行符(\n)的之后和之前
s :使原點字符(.)匹配任意一個字符同時也匹配換行符
x :模式中的空白字符除了被轉(zhuǎn)義的或在字符類中的以外完全被忽略
e :preg_replace()在替換字符串中對逆向引用作正常的替換纳鼎,將其作為PHP代碼求值俺夕,并用其結(jié)果來替換所搜索的字符串
A :模式被強制為“anchored”,即強制僅從目標字符串的開頭開始匹配
D :模式中的行結(jié)束($)僅匹配目標字符串的結(jié)尾贱鄙,否則包含換行符
S :為加速匹配而對其進行分析劝贸,分析一個模式僅對沒有單一固定其實字符的nonanchored模式有用
U :使“?”的默認匹配成為貪婪狀態(tài)
X :一個反斜線后面跟一個沒有特殊意義的字母被當成該字母本身
u :模式字符串被當成UTF-8

preg_grep() :返回與模式匹配的數(shù)組單元的正則表達式函數(shù)
preg_match() :進行正則表達式匹配的函數(shù)
preg_match_all() :進行全局正則表達式匹配的函數(shù)
preg_replace() :執(zhí)行正則表達式的搜索和替換的函數(shù)
preg_split() :用正則表達式分割字符串的函數(shù)

//返回與模式匹配的數(shù)組單元的正則表達式函數(shù)
array preg_grep(string $pattern, array $input [, int $flag]);

<?php
$test_preg = array(
"AK47",
"163.com",
"happy new year",
"EX0000",
"007 in USA",
"abc123",
"TEST-abc-315",
"123654789",
"Euapa00!"
);

echo "<b>原數(shù)組:</b>";
echo "<pre>";
print_r($test_preg);
echo "</pre>";

$preg_arr = preg_grep("/^[A-Z].*[0-9]$/",$test_preg);  //正則表達式
echo "<br>";
echo "<b>將原數(shù)組中以任意大寫字母開頭的、中間任意個字符逗宁、最后以數(shù)字結(jié)尾的字符串找出:</b>";
echo "<pre>";
print_r($preg_arr);  //輸出匹配的元素
echo "</pre>";
?>


//進行正則表達式匹配的函數(shù)
int preg_match(string $pattern , string $subject [, arrayy $matches [, int $flag]]);

<?php
$str_arr = array(
"PHP 是優(yōu)秀的Web腳本語言",
"Perl的文本處理功能很強大"
);

foreach($str_arr as $str){
      //使用了修正符
      if(preg_match("/php/i",$str)){
            echo "在字符串'$str'中找到對'php'的匹配";
            echo "<br/>";
            echo "<br/>";
      }else{
             echo "在字符串'$str'中<b>未</b>找到對'php'的匹配";
            echo "<br/>";
            echo "<br/>";           
      }
}
?>


//進行全局正則表達式匹配的函數(shù)
int preg_match_all (string $pattern, string $subject, array $matches [,int $flag]);

<?php
$html = "<b>粗體字符</b><a href=index.html>可點擊的連接</a>";

preg_match_all("/(<([\w]+)[^>]*>)(.*)(<\/\\2>)/", $html , $matches);

for ($i=0;$i<count($matches[0]);$i++){
      echo "匹配:".$matches[0][$i]."\n";
      echo "第一部分:".$matches[1][$i]."\n";
      echo "第二部分:".$matches[2][$i]."\n";
      echo "第三部分:".$matches[3][$i]."\n\n";
}
?>

//執(zhí)行正則表達式的搜索和替換的函數(shù)
mixed preg_replace(mixed $pattern,mixed $replacement,mixed $subject [, int $limit]);

<?php
$string = "The quick brown fox jumped over the lazy dog.";  
echo "原字符串:<br/>";
echo $string;
echo "<br/><br/>";

$patterns[0] = "/quick/";
$patterns[1] = "/brown/";
$patterns[2] = "/fox/";

$replacements[2] = "bear";
$replacements[1] = "black";
$replacements[0] = "slow";

$str1 = preg_replace($patterns,$replacements,$string);  //替換字符串
echo "使用函數(shù)ksort()之前字符串替換為:<br/>";
echo $str1;
echo "<br/><br/>";

ksort($patterns);        //排序
ksort($replacements);    //排序

$str2 = preg_replace($patterns,$replacements,$string);
echo "使用函數(shù)ksort()之后字符串替換為:<br/>";
echo $str2;
echo "<br/><br/>";
?>


//用正則表達式分割字符串的函數(shù)
array preg_split(string $pattern,string $subject [,int $limit [, int $flag]]);
//參數(shù)$limit=-1,$flag參數(shù)如下:
PREG_SPLIT_NO_EMPTY:只返回非空的部分
PREG_SPLIT_DELIM_CAPTURE:界定符模式中的括號表達式會被捕捉返回
PREG_SPLIT_OFFSET_CAPTURE:對每個出現(xiàn)的匹配結(jié)果同時返回其附屬的字符串偏移量映九。注意,這改變了返回的數(shù)組的值瞎颗,使其中的每個單元也是一個數(shù)組件甥,其中第一項為匹配字符串,第二項為它在$subject中的偏移量

<?php
$str = 'PHP language programming in Web';  //定義字符串變量
echo "<b>原字符串:</b><br/>";
echo $str;
echo "<br/><br/>";

$chars = preg_split('/ /',$str,-1,PREG_SPLIT_OFFSET_CAPTURE);  //分割字符串
echo "<b>調(diào)用函數(shù)preg_split()后:</b>";
echo "<pre>";
print_r($chars);
?>

幾例常見的正則表達式分析

  • 實例1:檢查IP地址的正則表達式:
    直接上代碼:
<?php
$arr_ip = array(  //定義了一個數(shù)組
  "192.168.1.100",
  "-12.255.0.10",
  "256.1.2.255",
  "10.9c.132.69",
  "255.255.255.255",
  "123.0.0.0.1"
);

foreach ($arr_ip as $ip ) {  //驗證數(shù)組里的IP
  if (validateIp($ip)) {  //驗證ip
    echo "<b>$ip 是正確的IP地址</b>";
    echo "<br/><br/>";
  }else {
    echo "$ip 不是正確的IP地址";
    echo "<br/><br/>";
  }
}

function validateIp($ip){  //驗證ip的函數(shù)
  $iparray = explode(".",$ip);
  for ($i=0; $i < count($iparray); $i++) {
    if ($iparray[$i]>255) {
      return (0);
    }
    return preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/",$ip);
  }
}
?>
  • 實例2:檢查中文字符的正則表達式:
    直接上代碼
<?php
$str_arr = array( //測試數(shù)組
  "I am very happy",
  "快樂編程快樂生活",
  "PHP編程",
  "1997年香港回歸",
  "英語學習ABC",
  "123456789"
);

$patt_ch = chr(0xa1)."-".chr(0xff); //匹配中文字符的ASCII范圍

foreach ($str_arr as $str){
  echo "字符串'$str'是";
  if(preg_match("/[$patt_ch]+/",$str)){  //注意在正則表達式的前后使用界定符
    echo "<b>存在中文</b>";
    echo "<br>";
    echo "<br>";
  }else {
    echo "不存在中文";
    echo "<br>";
    echo "<br>";
  }
}
?>
  • 實例3:檢查Email地址的正則表達式
<?php
$str_arr = array( //測試數(shù)組
  "mymail@somesite.com",
  "my_mail@somesite.com",
  "my-mail@somesite.com",
  "my.mail@somesite.com",
  "mymail@somesite.ccoomm",
  "mymail@site.cn",
  "mymail@@@site.com",
  "mymail@site",
  "MyMail@somesite.com",
  "My2007@somesite.com",
  "163mail_for-me777@somesite.com",
  "510137672@qq.com"
);

$patt_email = "/^[_a-zA-Z0-9-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,4}$/"; //驗證郵箱

foreach ($str_arr as $str){
  echo "字符串'$str'是";
  if(preg_match($patt_email,$str)){  //注意在正則表達式的前后使用界定符
    echo "<b>合法的Email格式</b>";
    echo "<br>";
    echo "<br>";
  }else {
    echo "不合法的Email格式";
    echo "<br>";
    echo "<br>";
  }
}
?>
  • 實例4:檢查URL地址的正則表達式
    直接上代碼:
<?php
$str_arr = array( //測試數(shù)組
  "http://www.liubaiqi.cn",
  "www.liubaiqi.cn",
  "http://www.liubaiqi.cn/login.html",
  "http://liubaiqi.com",
  ":www.liubaiqi.cn"
);

$patt_url = "/^(http:\/\/)?[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)*.+$/"; //驗證URL的正則表達式

foreach ($str_arr as $str){ //遍歷數(shù)組
  echo "字符串'$str'是";
  if(preg_match($patt_url,$str)){  //匹配URL
    echo "<b>合法的URL格式</b>";
    echo "<br>";
    echo "<br>";
  }else {
    echo "不合法的URL格式";
    echo "<br>";
    echo "<br>";
  }
}
?>

小結(jié):正則表達式的內(nèi)容暫時就說這么多哼拔,如果以后遇到問題引有,我再補充。

在使用過程中倦逐,主要記住PERL函數(shù)的語法和正則表達式的格式譬正,
這是現(xiàn)在較為常用的。其他的了解就行。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末曾我,一起剝皮案震驚了整個濱河市粉怕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌您单,老刑警劉巖斋荞,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異虐秦,居然都是意外死亡平酿,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門悦陋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蜈彼,“玉大人,你說我怎么就攤上這事俺驶⌒夷妫” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵暮现,是天一觀的道長还绘。 經(jīng)常有香客問我,道長栖袋,這世上最難降的妖魔是什么拍顷? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮塘幅,結(jié)果婚禮上昔案,老公的妹妹穿的比我還像新娘。我一直安慰自己电媳,他們只是感情好踏揣,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著匾乓,像睡著了一般捞稿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拼缝,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天娱局,我揣著相機與錄音,去河邊找鬼珍促。 笑死铃辖,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的猪叙。 我是一名探鬼主播娇斩,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼仁卷,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了犬第?” 一聲冷哼從身側(cè)響起锦积,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎歉嗓,沒想到半個月后丰介,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡鉴分,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年哮幢,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片志珍。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡橙垢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出伦糯,到底是詐尸還是另有隱情柜某,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布敛纲,位于F島的核電站喂击,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏淤翔。R本人自食惡果不足惜翰绊,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望办铡。 院中可真熱鬧辞做,春花似錦琳要、人聲如沸寡具。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽童叠。三九已至,卻和暖如春课幕,著一層夾襖步出監(jiān)牢的瞬間厦坛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工乍惊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留杜秸,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓润绎,卻偏偏與公主長得像撬碟,于是被迫代替她去往敵國和親诞挨。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

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