在更新日志之前,我要說聲抱歉,由于之前幾天準備面試東奔西跑,然后得閑又復習計算機網(wǎng)絡(luò)、數(shù)據(jù)庫、操作系統(tǒng)、java、C還有數(shù)據(jù)結(jié)構(gòu)等一些之前學過的課程知識,加上在PHP文件中解析XML方面又遇到了瓶頸,就一直沒有更新博客。不過我現(xiàn)在想通了,我覺得不可以因為它我搞不懂就一直卡在那兒,我可以越過它繼續(xù)向前,等到某日,說不定再回首就發(fā)現(xiàn)這個問題不是問題了。所以這節(jié)我們將正式開始學習正則表達式。
由于在此之前我從來沒有接觸過正則表達式,而在PHP中正則表達式又是非常非常重要的,所以我將會花較多的精力來掌握正則表達式,所以我也會分成較多的章節(jié)來展開從正則表達式的語法到函數(shù),還有就是它們內(nèi)容也會比較細,不會像之前的那么粗暴。
正則表達式是對字符串操作的一種邏輯公式,就是實現(xiàn)定義好的一些特定字符及這些特定字符的組合,組成一個“規(guī)則字符串”,用來表達對字符串的一種過濾邏輯。例如Email、電話、密碼和生日之類的數(shù)據(jù)都有特定格式,這個時候就可以使用正則表達式驗證數(shù)據(jù)是否有效。
PHP支持兩種類型的正則表達式:POSIX類型和Perl類型。下面是POSIX類型的正則表達式語法:
一、POSIX正則表達式語法
POSIX正則表達式的結(jié)構(gòu)和一般的數(shù)學表達式類似,有多個操作符(元素)組合在一起構(gòu)成一個更復雜的表達式。這種組合不僅可以找到或者匹配表達式(如某個單詞或數(shù)字),還可以找到許多語義不同但語法相似的字符串(如HTML標記)。
POSIX支持以下三種語法來定義正則表達式,分別是中括號、量詞和預定義字符。
1、中括號([])
POSIX正則表達式的中括號([])表示在一定的范圍內(nèi)查找字符,可以在中括號內(nèi)設(shè)置要查找的字符序列。例如,[abc]表示匹配在這3個字符之間的字符串。
可以在中括號內(nèi)使用短橫杠連接兩個字符來表示一個連續(xù)范圍。下面列出了正則表達式常用的字符范圍:
常用形式 說明
[0-9] 匹配任何從0到9之間的十進制數(shù)字
[a-z] 匹配任何從小寫a到z之間的字符
[A-Z] 匹配任何從大寫A到Z之間的字符
[A-Za-z] 匹配任何從大寫A到小寫z之間的字符
2、特殊字符
在中括號中指定字符范圍時有一個很明顯的局限性。比如要判斷某個字符串是否為18位的數(shù)字,就需要“[0-90-90-9……]”這樣重復18次,所以,POSIX正則表達式中定義了一些特殊字符和表達式,用于簡化類似復雜情況下的正則表達式寫法,如下所示:
特殊字符
常用形式 說明
p+ 匹配任何一個至少包含p的字符串
p* 匹配任何包含0個或多個p的字符串
p? 匹配任何包含0個或1個p的字符串
p{2} 匹配任何包含2個p序列的字符串
p{2,3} 匹配任何包含2個或3個p序列的字符串
p{2.} 匹配任何至少包含兩個p序列的字符串
p$ 匹配任何以p結(jié)尾的字符串
^p 匹配任何以p開頭的字符串
[^a-zA-Z] 匹配任何不包含從a到z和從A到Z的字符串
p-p 匹配任何包含字符p、接下來是任何字符串、在接下來又是p的字符串
^.{2}$ 匹配任何只包含兩個字符的字符串
(.*) 匹配任何被和包圍的字符串
p(hp) 匹配任何包含一個p,后面是0個或多個hp的字符串
(a|b) 匹配任何包含a或者b的字符串
注意^符號在中括號之外表示字符串的開頭,
比如^h可以匹配hi,但是不能匹配the。
注意當^符號在中括號內(nèi)表示取反,“非”或“排除”的意思,常用于否定某些字符。
比如^[0-9][0-9]表示第一個字符不是數(shù)字,第二位數(shù)是數(shù)字。因此@2及Y3都是符合匹配的,但14及2W就不能被匹配了。
下面列出了^符號用于排除字符的常規(guī)用法。
# [^0-9]: 匹配除了數(shù)字以外的所有字符。
# [^a-z]: 匹配除了小寫字母以外的所有字符。
# [^A-Z]: 匹配除了大寫字母以外的所有字符。
# [^\\\/\^]: 匹配除了“\”、“/”和“^”以外的所有字符。
# [^\'\']: 匹配除了雙引號和單引號以外的所有字符。
3、預定義字符
在POSIX正則表達式中還可以使用一些預定義的字符表示范圍。預定義字符可以指定整個字符范圍,例如字母或整數(shù)集。下面列出了常用的預定義字符。
預定義字符
字符 描述 擴展
[:alnum:] 字母和數(shù)字字符 [0-9a-zA-Z]
[:alpha:] 字母字符(字母) [a-zA-Z]
[:ascii:] 7位ASCII [\x01-\x7F]
[:blank:] 水平空白符(空格、制表符) [\t]
[:cntrl:] 控制字符 [\x01-\x1F]
[:digit:] 數(shù)字 [0-9]
[:lower:] 小寫字母 [a-z]
[:print:] 可打印字符(原形類家空格和制表符) [\t\x20z-\xFF]
[:punct:] 任意標點符號,如句號(.)和分號(;) [-!'#$%&'()*+,./:;<=>?@[\\\]^_'{|}~]=>
[:space:] 空白(換行、回車、制表符、空格、垂直制表符) [\n\r\t\x0B]
[:upper:] 大寫字母 [A-Z]
[:xdigit:] 十六進制數(shù)字 [0-9a-fA-F]
每一個預定義字符都可以被用于替代一類字符。例如查找任一個小寫字母或者一個數(shù)字,可以使用下面的正則表達式:
[ [ : lower: ] [ : digit: ] ]
但是,不能把一個預定義字符當做一個范圍的終點使用。例如,下面的表達式是錯誤的:
ereg (' [0-[:alnum:] ] ' , '234');
至于ereg()函數(shù),將會在下節(jié)《POSIX正則表達式函數(shù)》詳細展開。
寫在后面:本來正則表達式是想以一篇日志來講解的,但是覺得那樣的話還是篇幅太長了,而且知識點都聚在一起比較籠統(tǒng),所以就決定把它拆分成一個小節(jié)一個小節(jié)去掌握。這樣一來,知識點一目了然,也較有利于記憶。