日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

PHP基础系列之正则表达式(一)

發(fā)布時間:2025/3/19 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PHP基础系列之正则表达式(一) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

正則表達(dá)式的定義

正則表達(dá)式就是描述字符排列模式的一種自定義的語法規(guī)則。
由于正則表達(dá)式本身具有一套非常完整的、可以編寫模式的語法體系,提供了一種靈活且直觀的字符串處理方法,故正則表達(dá)式也稱為模式表達(dá)式。

正則表達(dá)式的特點

  • 正則表達(dá)式并不是PHP特有的,JavaScript、Java、Perl、MySQL中都可以應(yīng)用到正則表達(dá)式。
  • 正則表達(dá)式通過構(gòu)建具有特定規(guī)則的模式,與輸入的字符串信息進(jìn)行比較,從而實現(xiàn)字符串的匹配、查找、替換及分割等操作。
  • 例子:

    "/^https?:\/\/(([a-zA-Z0-9_-])+(\.)?)*(:\d+)?(\/((\.)?(\?)?=?&?[a-zA-Z0-9_-](\?)?)*)*$/i" // 匹配網(wǎng)址URL的正則表達(dá)式 "/<(\S*?)[^>]*>.*?<\/\\1>|<.*?/>/i" // 匹配HTML標(biāo)記的正則表達(dá)式 "/\w+([-+.]\w)+*@\w+([-.]\w+)*\.\w+([-.]\w+)*/" // 匹配E-mail地址的正則表達(dá)式 "/^<img\s+[^>]*\s*src\s*=\s*([']?)(?<url>\S+)'?[^>l ]*>$/" // 匹配img標(biāo)簽

    注意

  • 正則表達(dá)式是由普通字符與具有特殊意義的字符組成字符串
  • 效率問題,如果可以使用字符串函數(shù)完成任務(wù),那盡量不使用正則表達(dá)式函數(shù)
  • 對于一些復(fù)雜操作,如表單驗證,計算發(fā)布文章中有多少個句子,抓取網(wǎng)頁中某種格式的句子等使用正則表達(dá)式以及相關(guān)函數(shù)能夠更好地實現(xiàn)
  • 正則表達(dá)式具有一定的編寫規(guī)則(語義),是一種模式
  • 若正則表達(dá)式不與 相應(yīng)的正則表達(dá)式函數(shù)使用,那么正則表達(dá)式僅僅是字符串,要達(dá)成匹配、查找、替換以及分割功能,正則表達(dá)式必須與相應(yīng)的正則表達(dá)式函數(shù)配套使用。
  • PHP中兩套支持正則表達(dá)式的函數(shù)庫

  • PCRE(Perl Compatible Regular Expression)

    由PCRE庫提供,與Perl語言兼容的正則表達(dá)式、使用"preg_"為前綴命名的函數(shù),而且表達(dá)式都應(yīng)被包含在定界符中。

  • POSIX(Portable Operation System Interface)

    自從PHP5.3.0開始廢棄.使用一套"ereg_"為前綴命名的函數(shù)。

  • 注意

    1. 兩套 函數(shù)庫功能類似,執(zhí)行效率不同,一般來說,實現(xiàn)相同功能,使用 PCRE庫提供的正則表達(dá)式效率略占優(yōu)勢。 2. PCRE 函數(shù)需要模式以定界符閉合。 3. 不像POSIX,PCRE 擴展沒有專門用于大小寫不敏感匹配的函數(shù)。取而代之的是,支持使用i (PCRE_CASELESS) 模式修飾符完成同樣的工作。 其他模式修飾符同樣可用于改變匹配策略。 4. POSIX 函數(shù)從最左面開始尋找最長的匹配,但是 PCRE 在第一個合法匹配后停止。如果字符串 不匹配這沒有什么區(qū)別,但是如果匹配,兩者在結(jié)果和速度上都會有差別。 為了說明這個不同, 考慮下面的例子(來自Jeffrey Friedl 的《精通正則表達(dá)式》一書)。 使用模式 one(self)?(selfsufficient)? 在字符串oneselfsufficient 上匹配,PCRE 會匹配到oneself,但是使用 POSIX,結(jié)果將是整個字符串 oneselfsufficient。兩個子串都匹配原始字符串,但是 POSIX 將 最長的作為結(jié)果。

    函數(shù)對比

    POSIXPCRE
    ereg_replace()preg_replace()
    ereg()preg_match()
    eregi_replace()preg_replace()
    eregi()preg_match()
    split()preg_split()
    spliti()preg_split()
    sql_regcase()無對等函數(shù)
    可參照PHP Manual

    正則表達(dá)式語法規(guī)則

    正則表達(dá)式描述了一種字符串的匹配模式,通過這個模式在特定的函數(shù)中對字符串進(jìn)行匹配、查找、替換以及分割等操作。

    正則表達(dá)式作為一個匹配的模板,是由定界符,原子(普通字符,例如a-z)、有特殊功能的字符(稱為元字符,例如*、+、?等),
    以及模式修正符等部分組成的文字模式。

    例子:

    "/^https?\/\/(([a-zA-Z0-9_-])+(\.)?)*(\d+)?(\/((\.)?(\?)?=?&?[a-zA-Z0-9_-](\?)?)*)*$/i/"

    或者

    '/^<a.*?(?|\\t|\\r|\\n)?href=[\'"]?(.+?)[\'"]?(?(?|\\t|\\r|\\n)+.*?)?>(.+?)<\/a.*?>$/sim'

    1. 定界符中使用的是兩個斜線"/",將模式放在它之間說明。 2. 原子用到了<、a、href、=、'、"、/、>等普通字符和\t、\r、\n等轉(zhuǎn)義字符。 3. 元字符使用了[]、()、|、.、?、*、+等具有特殊含義的字符。 4. 用到模式修正符是在定界符最后一個斜線之后的三個字符"s"、"i"、"m"。

    定界符

    定界符為PCRE不同于POSIX的特點之一。

    除了字母、數(shù)字和反斜線以外的字符皆可為定界符

    例子:
    { }、# #、||、!!等

    /<\/w+>/ // 使用反斜線作為定界符號 合法 |(\d{3})-\d+|Sm // 使用豎線"|"作為定界符號 合法 !^(?i)PHP[34]! // 使用感嘆號"!"作為定界符 合法 {^\s+(\s+)?$} // 使用花括號"{}"作為定界符號 合法 /href='(.*)' // 非法定界符,缺少結(jié)束定界符 1-\d3-\d3-\d4/ // 非法定界符號,缺少起始定界符

    注意

    如果沒有特殊要求,一般使用//作為定界符

    定界符是成對的,有開始符號,也有結(jié)束符號。

    原子

    原子是正則表達(dá)式中最基本的組成單位,而且在每個模式中最少要包含一個原子。

    原子是所有那些未顯式指定為元字符的打印(可以在屏幕上輸出的字符)和非打印字符(看不到的)組成的。
    簡單地說,能夠在正則表達(dá)式中單獨使用的字符就可稱為原子

    將其劃分為五類

    1. 普通字符作為原子

    普通字符是編寫正則表達(dá)式時最常見的原子,包括所有的大寫和小寫字母字符、所有數(shù)字等,例如:a-z、A-Z、0-9。

    2. 非打印字符(看不到的)作為原子

    原子字符 \x09 含義描述+ \cx 匹配由x指明的控制符。例如,\c\M匹配一個Control-M或者回車符。x的值必須為A-Z或a-z之一,否則,將c視為一個原義的'c'字符。+ \f 匹配一個換頁符。等價于\x0c和\cL+ \n 匹配一個換行符。等價于\x0a和\cJ+ \r 匹配一個回車符。等價于\x0d和\cM+ \t 匹配一個制表符。等價于\x09和\cI+ \v 匹配一個垂直制表符。等價于\x0b和\cK

    3.通用字符類型做為原子

    前面介紹的原子,都是一個原子只能匹配一個字符。但是有時候我們需要一個原子可以匹配一類字符。

    在正則表達(dá)式中可以直接使用一些代表范圍的原子

    原子字符 含義描述\d 匹配任意一個十進(jìn)制數(shù)字,等價于[0-9]\D 匹配任意一個除十進(jìn)制數(shù)字以外的字符,等價于[^0-9]\w 匹配任意一個數(shù)字、字母、下劃線,等價于[0-9a-zA-Z_]\W 匹配除數(shù)字、字母、下劃線以外的任意一個字符,等價于[^0-9a-zA-Z_]\s 匹配任意一個空白字符,等價于[\f\t\n\v\r]\S 匹配除空白字符以外的任何一個字符,等價于[^\t\f\n\v\r]

    4. 自定義原子表([])作為原子

    有些時候,上面六個通用字符并不能滿足我們的需求,我們需要自定義一類原子,比如說奇數(shù)(1,3,5,7,9).
    所以這時候需要我們自定義一類原子(稱之為類原子),使用原子表"[]"就可以定義一組彼此平等的原子,
    只能匹配原子表中一個字符。

    1表示匹配除表內(nèi)原子外的任意字符,通常稱之為排除原子表。

    此外,在原子表中可以使用連字符(-)連接一組按照ASCII碼順序排列的原子,可簡化書寫。

    例子

    '/[apj]sp/' // 可以匹配asp、jsp、PSP三種,從原子表中僅選擇一個作為原子 '/[^apj]sp/' // 可以匹配除了asp、PSP、jsp三種以外的字符串,如xsp,ysp,zsp等 '/0[xX][0-9a-fA-F]/' // 可以匹配一個簡單的十六進(jìn)制數(shù),如0x2f、0X3AE或0x4aB等

    5. 一些特殊字符和元字符作為原子

    在正則表達(dá)式中,任何一個符號都可以作為原子使用,但如果該符號在正則表達(dá)式中有特殊意義,可以使用轉(zhuǎn)義字符""
    取消它的特殊意義,作為一個普通字符使用。 如 "\. \* \+ \? \( \<\>"

    " "轉(zhuǎn)義字符可以將有意義的字符轉(zhuǎn)成沒意義的字符,還可以將沒意義的字符轉(zhuǎn)為有意義的字符

    元字符

    元字符是用于構(gòu)建正則表達(dá)式的具有特殊含義的字符,如"*"、"+"、"?"等。

    元字符不能單獨出現(xiàn),必須用來修飾原子。

    如果要在正則表達(dá)式中使用包含元字符本身,為了使其失去特殊含義,則必須在前面加上""進(jìn)行轉(zhuǎn)義

    正則表達(dá)式的元字符

    元字符 含義描述\* 匹配0次,1次或者多次其前面的原子\+ 匹配1次或多次其前的原子? 匹配0次或者1次其前的原子. 匹配除了換行符外的任意一個字符| 匹配兩個或多個分支選擇{n} 表示其前面的原子恰好出現(xiàn)n次{n,} 表示其前面的原子出現(xiàn)不少于n次{n,m} 表示其前面的原子至少出現(xiàn)n次,最多出現(xiàn)n次^或\A 匹配輸入字符串的開始位置(或在多行模式下行的開頭,即緊隨一換行符后)$或\Z 匹配輸入字符串(或者在多行模式下行的結(jié)尾,即緊隨一換行符后)\b 匹配單詞的邊界\B 匹配除單詞邊界以外的部分[] 匹配方括號中指定的任意一個原子[^] 匹配除方括號中的原子以外的任意一個字符,排除原子表() 匹配其整體為一個原子,即模式單元。可以理解為由多個單個原子組成的大原子\xn 匹配n,其中n為十六進(jìn)制轉(zhuǎn)義值。十六進(jìn)制轉(zhuǎn)義值必須為確定的兩個數(shù)字長。例如,`"\x41"`匹配`A`。`"\x041"`則等價于`"\x04&1"`。正則表達(dá)式中可以使用ASCII編碼。

    1. 限定符

    限定符用來指定正則表達(dá)式的一個給定原子必須要出現(xiàn)多少次才能滿足匹配。

    總共有"*"、"+"、"?"、"{n}"、"{n,}"、"{n,m}"六種限定符,他們之間的區(qū)別主要是重復(fù)匹配的次數(shù)不同。

    其中"*"、"+"、"{n,}"限定符是貪婪的,因為它們會盡可能地匹配文字。

    注意

    元字符 "*" 表示0次、1次或多次匹配其前的原子,也可以使用"{0,}"完成同樣的匹配

    "+"可以使用"{1,}"表示,

    "?"可以使用"{0,1}"表示。

    2. 邊界限制(斷言)

    用來限定字符串或單詞的邊界范圍,以便獲得更準(zhǔn)確的匹配結(jié)果。元字符"^"或("\A")和"$"或("\Z")
    分別指字符串的開始于結(jié)束,而"\b"用于描述字符串中每個單詞的前或者后邊界,
    與之相反的元字符"\B"表示非單詞邊界。

    例如:

    有一個字符串 "this is a test", 使用邊界限制如下:"/^this/" 匹配此字符是否以字符串"this"開始的,匹配成功"/test$/" 匹配此字符是否以字符串"test"結(jié)束的,匹配成功"/\bis\b/" 匹配此字符串中是否含有單詞"is",因為在字符串"is"兩邊都需要有邊界"/\Bis\b/" 查找字符串"is"時,左邊不能有邊界而右邊必須右邊界,如"this"匹配成功

    3. 句號(.)

    在字符類以外,模式中的圓點可以匹配目標(biāo)中的任何一個字符,包括不可打印字符。但不匹配換行符號(默認(rèn)情況下),相當(dāng)于"[^\n]"(UNIX系統(tǒng))或者"[^\n\r]"(Windows系統(tǒng))。

    但是如果設(shè)定了模式修正符"s",則圓點也會匹配換行符。

    處理圓點與處理^和$是完全獨立的,唯一的聯(lián)系是涉及換行

    注意

    1. `".*?"`或者`".+?"`組合來匹配除換行符以外的任何字符串。例如:`"/<b>.*?<\/b>/"`可以匹配以`<b>`,`</b>`標(biāo)簽開始于結(jié)束的任何不包括換行符的任意字符串

    4. 模式選擇符(|)

    豎線字符"|"用來分隔多選一模式,在正則表達(dá)式中匹配兩個或更多的選擇之一。

    因|的優(yōu)先級是最低的,所以應(yīng)在最后考慮其功能。

    例如:LAMP | J2EE表示匹配LAMP,也可以匹配J2EE,由于|其優(yōu)先級最低,所以并
    不表示匹配'LAMP2EE'或者'LAMJEE'。

    也可以像這樣使用 "/Linux|Apache|MySQL|PHP/",表示可以從中任意匹配一組。

    5. 模式單元

    模式單元是使用元字符"()"將多個原子組成大原子使用。

    一個模式單元中的表達(dá)式將被優(yōu)先匹配

    例子:

    '/(very)*good/' //可以匹配good、very good、very very good

    6. 后向引用

    后向引用是一個正則表達(dá)式中一個重要的應(yīng)用點。

    使用()標(biāo)記的開始和結(jié)束的多個原子,不僅僅是一個獨立的單元,也是一個子表達(dá)式(也稱之為子模式)。

    **對于一個正則表達(dá)式模式或部分模式兩邊添加圓括號將導(dǎo)致相關(guān)匹配存儲到一個臨時緩沖區(qū)中,可以被捕獲供

    以后使用**。

    所捕獲的每個子匹配都按照正則表達(dá)式模式中從左之后所遇到的內(nèi)容存儲。存儲子匹配的緩沖區(qū)編號從1開始,
    連續(xù)編號直至最大99個表達(dá)式。

    每個緩沖區(qū)都可以使用\n訪問,其中n為一個便是特定緩沖區(qū)的一位或兩位十進(jìn)制數(shù)。

    例如:"\1"、"\2"、"\3"等形式的引用,在正則表達(dá)式模式中使用時還需要在前面加上一個反斜線,
    將反斜線再次轉(zhuǎn)義,
    例如:"\\1"、"\\2"、"\\3"等形式的引用。

    如下所示:

    '/^\d{4}\W\d{2}\W\d{2$}/' // 這是一個匹配日期的格式,如2008-08/08或者2008/08-08 等 '/^\d{4}(\W)\d{2}\\1\d{2$}/' // 這是一個匹配日期的格式,如2008-08-08或者2008/08/08 等

    當(dāng)你要使用模式單元而又不想存儲匹配結(jié)果時,可以使用非捕獲元字符"?:"、"?="或"?!"來忽略對相關(guān)匹配的保存。

    注意

    在一些正則表達(dá)式中,使用非存儲模式單元是必要的,可以改變其后向引用的順序。

    `/(Windows)(Linux)\\2OS/` --- 使用"\2"再次引用第二個緩沖區(qū)中的字符串"Linux" `/(?:Windows)(Linux)\\1OS/` --- 使用"?:"忽略了第一個子表達(dá)式的存儲,所以"\1"引用的就是"Linux"

    7. 模式匹配的優(yōu)先級

    在使用正則表達(dá)式時,需要注意匹配的書序。通常相同優(yōu)先級從左到右進(jìn)行運算,不同優(yōu)先級的運算先高后低。

    ** 順 序 ** ** 元 字 符 ** ** 描 述 **1 \ 轉(zhuǎn)義符號2 ()、(?:)、(?=)、[] 模式單元和原子表3 *、+、?、{n}、{n,}、{n,m} 重復(fù)匹配4 ^、$、\b、\B、\A、\Z 邊界限制5 | 模式選擇

    模式修正符

    模式修正符在正則表達(dá)式定界符之外使用(最后一個斜線"/"之后)。

    模式修正符可以調(diào)整正則表達(dá)式的解釋,擴展了正則表達(dá)式在匹配、替換等操作時的某些功能;
    而且模式修正符可以組合使用,更增強了正則表達(dá)式處理能力

    模式修正符可以單個使用,也可以多個組合使用

    模式修正符

    **模式修正符** **功能描述**i 在和模式進(jìn)行匹配時不區(qū)分大小寫m 將字符串視為多行。默認(rèn)開的正則開始`"^"`和`"$"`將目標(biāo)字符串作為單一的一"行"字符(甚至其中包含有換行符也是如此)。如果在修飾符中加上`"m"`,那么開始和結(jié)束將會指字符串的每一行,每一行的開頭就是`"^"`,結(jié)尾就是`"$"`。s 如果設(shè)定了次修正符,則模式中的圓點元字符`"."`匹配所有的字符,包括換行符。即將字符串視為單行,換行符作為普通字符看待。x 模式中的空白忽略不計,除非它已經(jīng)被轉(zhuǎn)義。e **只有在`preg_replace()`函數(shù)中,在替換字符串對逆向引用做正常的替換,將其作為PHP代碼求值,并且其結(jié)果來替換所搜索的字符串**U 本修正符反轉(zhuǎn)了匹配數(shù)量的值使其使其不是默認(rèn)的重復(fù),而變成在后面跟上`"?"`才變得重復(fù)。**__這和Perl語言不兼容__**。也可以通過在模式中設(shè)定(U)修正符或者數(shù)量符之后跟一個問號`"?"`(例如.*?)來使用此選項。D 模式中的美元元字符僅匹配目標(biāo)字符串的結(jié)尾。沒有此選項時,如果最后一個字符是換行符,則美元符號也會匹配次字符之前的內(nèi)容。如果設(shè)定了m修正符,則忽略此選項

    注意:

  • 模式 "/Web Server/ix"可以用來匹配字符串"webserver",忽略大小寫和空白。
  • 貪婪匹配,在匹配成功的前提下,盡可能多的去匹配*,+,{n,},.*是貪婪的,例如:/a.*e/去匹配字符串"abcd fsdfsdfsesfdfsdfsesdfedfsdfses",由于'.*'是貪婪的匹配,會從這個字符串中匹配出"abcd fsdfsdfsesfdfsdfsesdfedfsdfse",從第一個a開始,知道最后一個字母e結(jié)束,都屬于'.*'內(nèi)容。如果想取消這種貪婪模式,可以使用模式修正符"U"或者在模式中使用.*?,在.*后面加個?。為了兼容Perl正則函數(shù),可能會沒有模式修正符"U",我們建議使用在".*"后加"?"來實現(xiàn)懶惰模式(即非貪婪模式)如果"U"與"?"同時使用,像這樣"/a.*?e/U",則匹配"abcdfsdfsdfsesfdfsdfsesdfedfsdfse",相當(dāng)于又啟用了貪婪模式。
  • 惰性模式,在匹配成功的前提下,盡可能少的去匹配(注意點同上)
  • 模式"/^is/m"可以匹配字符串"this\nis\nais\ntest"中的'is',因為使用模式修正符"m"將字符串視為多行,第二行出現(xiàn)的"is"匹配成功。默認(rèn)的正則開始^和結(jié)束'$'將目標(biāo)字符串作為單一的一“行”(甚至包含換行符也是如此)。
  • Note:

    看到這里是不是懵逼了?沒錯,我也懵逼。
    不過沒有關(guān)系,秉承Learning by doing的準(zhǔn)則,
    在接下來的教程中,我會一一演示。

    更多文章請訪問我的博客:Noapes

    實例

    /*** 無亂碼截取中文字符* @param $str* @param int $start* @param $length* @param string $charset* @param bool|true $suffix* @return string|void*/function msubstr($str, $start=0, $length, $charset="utf-8", $suffix=true) {if(function_exists("mb_substr"))return mb_substr($str, $start, $length, $charset);elseif(function_exists('iconv_substr')) {return iconv_substr($str,$start,$length,$charset);}$re['utf-8'] = "/[x01-x7f]|[xc2-xdf][x80-xbf]|[xe0-xef][x80-xbf]{2}|[xf0-xff][x80-xbf]{3}/";$re['gb2312'] = "/[x01-x7f]|[xb0-xf7][xa0-xfe]/";$re['gbk'] = "/[x01-x7f]|[x81-xfe][x40-xfe]/";$re['big5'] = "/[x01-x7f]|[x81-xfe]([x40-x7e]|xa1-xfe])/";preg_match_all($re[$charset], $str, $match);$slice = join("",array_slice($match[0], $start, $length));if($suffix) return $slice;return $slice; }echo msubstr('哈哈哈你好啊啊',2,3,'gb2312');
  • sdf ?
  • 與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

    總結(jié)

    以上是生活随笔為你收集整理的PHP基础系列之正则表达式(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。