PHP筆記 | 正則表達(dá)式詳析 與 諸多運(yùn)用實(shí)例

1. PHP正則表達(dá)式(PCRE)定義

  • 正則表達(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)字符模式是否存在


2. 正則表達(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 '匹配成功';
}

正則表達(dá)式模式修飾符詳細(xì)參考:
參考文1;
參考文2;

demo:

<?php
//請(qǐng)修改變量p的正則表達(dá)式,使他能夠匹配BBC
$p = '/bbc/i';
$str = "BBC是英國(guó)的一個(gè)電視臺(tái)";
if (preg_match($p, $str)) {
    echo '\'/bbc/i\'   匹配成功'.'<br>'.'<br>';
}   

$p = 'http://';
$p = '/'.preg_quote($p, '/').'/';
echo $p.'<br>'.'<br>';
$str = "http://www.imooc.com/";
if (preg_match($p, $str)) {
    echo '\'/http\:\/\//\'     匹配成功'.'<br>'.'<br>';
}   


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

運(yùn)行結(jié)果:

'/bbc/i'   匹配成功

/http\:\/\//

'/http\:\/\//'     匹配成功

'http/i'    匹配成功



3. 元字符與轉(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è)可選分支
) 子組的結(jié)束標(biāo)記

##下面三個(gè)元字符與貪婪特性和懶惰特性有關(guān)(下節(jié)講釋?zhuān)?br> ?作為量詞,表示 0 次或 1 次匹配。
 位于量詞后面用于改變量詞的貪婪特性。 (查閱量詞)
* 量詞,0 次或多次匹配
+ 量詞,1 次或多次匹配

{自定義量詞開(kāi)始標(biāo)記
}自定義量詞結(jié)束標(biāo)記
\s匹配任意的空白符,包括空格,制表符,換行符
[^\s]代表非空白符
\w匹配字母或數(shù)字或下劃線(xiàn)

  • 下面的\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á)式'/[\w\.\-]+@[a-z0-9\-]+\.(com|cn)/'中的[\w\.\-]的意義是,
被匹配的字符串中對(duì)應(yīng)位置的字符,只要符合\w\.、\-三個(gè)正則符號(hào)中的其中一個(gè),即可成功匹配;
也就是說(shuō)其實(shí)[\w\.\-]就是將括號(hào)之中的\w、\.\-三個(gè)符號(hào)做了一個(gè)并運(yùn)算;
+則是量詞,指定了前面的[\w\.\-]的匹配次數(shù);

demo:

<?php
//請(qǐng)修改變量p的正則表達(dá)式,使他能夠匹配str中的電話(huà)
$p = '/\d+\-\d+/';
$str = "我的電話(huà)是010-12345678";
preg_match($p, $str, $match);
echo $match[0].'<br>'.'<br>';

$p = '/^我[^\s]+(蘋(píng)果|香蕉)$/';
$str = "我喜歡吃蘋(píng)果";
if (preg_match($p, $str, $match)) {
    echo '匹配成功'.'結(jié)果是:'.$match[0].'<br>'.'<br>';
}

$p = '/^我.+(蘋(píng)果|香蕉)$/';
$str = "我喜歡吃蘋(píng)果";
if (preg_match($p, $str, $match)) {
    echo '匹配成功'.'結(jié)果是:'.$match[0].'<br>'.'<br>';
}

//下面的\w匹配字母或數(shù)字或下劃線(xiàn)。
$p = '/[\w\.\-]+@[a-z0-9\-]+\.(com|cn)/';
$str = "我的郵箱是Spark.eric@imooc.com";
preg_match($p, $str, $match);
echo '匹配成功'.'結(jié)果是:'.$match[0].'<br>';

運(yùn)行結(jié)果:

010-12345678

匹配成功結(jié)果是:我喜歡吃蘋(píng)果

匹配成功結(jié)果是:我喜歡吃蘋(píng)果

匹配成功結(jié)果是:Spark.eric@imooc.com



4. 貪婪模式與懶惰模式

貪婪模式與懶惰模式,說(shuō)到底就是元字符的特性
?作為量詞,表示 0 次或 1 次匹配。
* 量詞,0 次或多次匹配
+ 量詞,1 次或多次匹配


  • 正則表達(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

換句話(huà)說(shuō),
懶惰模式是在匹配最近的一個(gè)標(biāo)志,
貪婪模式是匹配到最遠(yuǎn)的一個(gè)標(biāo)志。

  • 當(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

demo:

<?php
//請(qǐng)修改變量p的正則表達(dá)式,使他能夠匹配str中的姓名
$p = '/\w+\s\w+/';
$str = "name:steven jobs";
preg_match($p, $str, $match);
echo $match[0].'<br>'.'<br>'; //結(jié)果為:steven jobs
$p1 = '/\w+[^\s]\w+\s\w+/';
preg_match($p1, $str, $match);
echo $match[0].'<br>'.'<br>'; 

//下面的\d表示匹配數(shù)字
$p = '/\d+\-\d+/';
$str = "我的電話(huà)是010-12345678";
preg_match($p, $str, $match);
echo $match[0].'<br>'.'<br>'; //結(jié)果為:010-12345678

$p = '/\d?\-\d?/';
$str = "我的電話(huà)是010-12345678";
preg_match($p, $str, $match);
echo $match[0].'<br>'.'<br>';  //結(jié)果為:0-1

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

運(yùn)行結(jié)果:

steven jobs

name:steven jobs

010-12345678

0-1

010-123456



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

使用正則表達(dá)式的目的是為了實(shí)現(xiàn)比字符串處理函數(shù)更加靈活的處理方式,
因此跟字符串處理函數(shù)一樣,

其主要用來(lái)

  • 判斷子字符串是否存在;
  • 實(shí)現(xiàn)字符串替換、分割字符串;
  • 獲取模式子串等。
  • PHP使用PCRE庫(kù)函數(shù)來(lái)進(jìn)行正則處理,
    通過(guò)設(shè)定好模式,然后調(diào)用相關(guān)的處理函數(shù)來(lái)取得匹配結(jié)果。

  • preg_match用來(lái)執(zhí)行一個(gè)匹配,
    1.可以簡(jiǎn)單的用來(lái)判斷模式是否匹配成功;
    2.或者取得一個(gè)匹配結(jié)果,
    3.他的返回值匹配成功的次數(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 )

注意:
添加的圓括號(hào)相當(dāng)于要匹配的內(nèi)容分組
preg_match()是把整體匹配分組匹配內(nèi)容都輸出了;
具體的可以參考下方demo的實(shí)驗(yàn)結(jié)果。

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

  • 關(guān)于表達(dá)式(.*?)的理解:
    1、 . 匹配任意除換行符“\n”外的字符;
    2、 * 表示匹配前一個(gè)字符0次或無(wú)限次;
    3、+*后跟?表示非貪婪匹配,即盡可能少的匹配,如*?重復(fù)任意次,但盡可能少重復(fù);
    4、 .*? 表示匹配任意數(shù)量的重復(fù),但是在能使整個(gè)匹配成功的前提下使用最少的重復(fù)。

  • 也就是說(shuō),
    .*匹配的往往是一個(gè)字符串,
    而有時(shí)候符合匹配的 / 可以作為匹配結(jié)果的字符串有很多,
    這時(shí)候在后面的?便起到了作用——
      在這些滿(mǎn)足條件的諸多字符串中,挑出一個(gè)最短的字符串(即盡可能少地匹配)作為(.*?)的最終匹配結(jié)果。(所謂?引領(lǐng)的懶惰模式

    具體的可以看看下面這個(gè)例子:
    以上我們可見(jiàn),

字符串$subject中其實(shí)符合$pattern的匹配有兩個(gè):abcd/abccccd;
然而匹配的結(jié)果是前者,其原因便是方才所說(shuō)的懶惰模式了。

綜合demo:

<?php
$subject = "my email is spark@imooc.com";
//在這里補(bǔ)充代碼,實(shí)現(xiàn)正則匹配,并輸出郵箱地址
$pattern = '/[\w\.]+@[\w\.]+/';
echo '匹配成功的次數(shù): '.preg_match($pattern, $subject, $matches).'<br>';
print_r($matches).'<br>'.'<br>'; //
echo $matches[0].'<br>'.'<br>';


echo '----------------------------------------------'.'<br>';
echo '$pattern = \'/a(.*?)d/\''.'<br>';
$subject = "abcdef";
$pattern = '/a(.*?)d/';
preg_match($pattern, $subject, $matches);
print_r($matches).'<br>'.'<br>'.'<br>'; //
echo '----------------------------------------------'.'<br>';

echo '$pattern = \'/a(.*)d/\''.'<br>';
$subject = "abcdef";
$pattern = '/a(.*)d/';
preg_match($pattern, $subject, $matches);
print_r($matches).'<br>'.'<br>'.'<br>'; //
echo '----------------------------------------------'.'<br>';

$subject = "abcccccdef";
$pattern = '/a(.*)d/';
preg_match($pattern, $subject, $matches);
print_r($matches).'<br>'.'<br>'.'<br>'; //
echo '----------------------------------------------'.'<br>';


$subject = "abcdef";
$pattern = '/ad/';
preg_match($pattern, $subject, $matches);
print_r($matches).'<br>'.'<br>'.'<br>'; //
echo '----------------------------------------------'.'<br>';

$subject = "abcdef";
$pattern = '/a?d/';
preg_match($pattern, $subject, $matches);
print_r($matches).'<br>'.'<br>'; //
echo '----------------------------------------------'.'<br>';

$subject = "abcccdeeeef";
$pattern = '/a(.*)d(.*)f/';
preg_match($pattern, $subject, $matches);
print_r($matches).'<br>'.'<br>'.'<br>'; //
echo '----------------------------------------------'.'<br>';

運(yùn)行結(jié)果:

匹配成功的次數(shù): 1
Array
(
    [0] => spark@imooc.com
)
spark@imooc.com

----------------------------------------------
$pattern = '/a(.*?)d/'
Array
(
    [0] => abcd
    [1] => bc
)
----------------------------------------------
$pattern = '/a(.*)d/'
Array
(
    [0] => abcd
    [1] => bc
)
----------------------------------------------
Array
(
    [0] => abcccccd
    [1] => bccccc
)
----------------------------------------------
Array
(
)
----------------------------------------------
Array
(
    [0] => d
)
----------------------------------------------
Array
(
    [0] => abcccdeeeef
    [1] => bccc
    [2] => eeee
)
----------------------------------------------



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

  • preg_match只能匹配一次結(jié)果,但很多時(shí)候我們需要匹配所有的結(jié)果,preg_match_all可以循環(huán)獲取一個(gè)列表的匹配結(jié)果數(shù)組。
  • 可以使用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)?code>$matches[0]保存完整模式的所有匹配, $matches[1]保存第一個(gè)子組的所有匹配,以此類(lèi)推。



<?php
$userinfo = "Name: <b>PHP</b> <br> Title: <b>Programming Language</b>";
preg_match_all ("/<b>(.*)<\/b>/U", $userinfo, $pat_array);
print_r($pat_array);
?>

運(yùn)行結(jié)果:(結(jié)果中標(biāo)簽<b>被略去是因?yàn)槟秸n瀏覽器的原因,然而事實(shí)上這個(gè)標(biāo)簽是存在于匹配結(jié)果的)



<?php
$userinfo = "Name: <b>PHP</b> <br> Title: <b>Programming Language</b>";
preg_match_all ("/<b>(.*)<\/b>/U", $userinfo, $pat_array);
print_r($pat_array[0]);
?>

運(yùn)行結(jié)果:

Array
(
    [0] => <b>PHP</b>
    [1] => <b>Programming Language</b>
)



  • [^>]表示除了>以外的任意一個(gè)字符
<?php
//\\2是一個(gè)后向引用的示例. 這會(huì)告訴pcre它必須匹配正則表達(dá)式中第二個(gè)圓括號(hào)(這里是([\w]+))
//匹配到的結(jié)果. 這里使用兩個(gè)反斜線(xiàn)是因?yàn)檫@里使用了雙引號(hào).
$html = "<b>bold text</b><a href=howdy.html>click me</a>";
 
preg_match_all("/(<([\w]+)[^>]*>)(.*?)(<\/\\2>)/", $html, $matches, PREG_SET_ORDER);
 
foreach ($matches as $val) {
    echo "matched: " . $val[0] . "\n";
    echo "part 1: " . $val[1] . "\n";
    echo "part 2: " . $val[2] . "\n";
    echo "part 3: " . $val[3] . "\n";
    echo "part 4: " . $val[4] . "\n\n";
}
?>

運(yùn)行結(jié)果:

matched: <b>bold text</b>
part 1: <b>
part 2: b
part 3: bold text
part 4: </b>

matched: <a href=howdy.html>click me</a>
part 1: <a href=howdy.html>
part 2: a
part 3: click me
part 4: </a>

分析輸出結(jié)果,應(yīng)該是:
1.首先,$matches[0]放第一段標(biāo)簽,$matches[1]放第二段標(biāo)簽;正所謂循環(huán)獲取匹配結(jié)果列表;
2.接著,$matches[0]同且$matches[1]都是一個(gè)Array類(lèi)型元素,各自在里面完成,完整匹配結(jié)果(整段標(biāo)簽)以及 各小分組匹配結(jié)果的存儲(chǔ);
(當(dāng)然這個(gè)邏輯僅僅屬于PREG_SET_ORDER這個(gè)flag,同函數(shù)默認(rèn)的排序不一,可見(jiàn)demo3.0&3.1)



demo2.1(個(gè)人修改版, 借慕課網(wǎng)平臺(tái)調(diào)試結(jié)果):

$html = "<b>bold text</b><a href=howdy.html>click me</a>";
 
preg_match_all("/(<([\w]+)[^>]*>)(.*?)(<\/\\2>)/", $html, $matches, PREG_SET_ORDER);
print_r($matches);
echo '<br>'.'<br>'.'<br>'.'----------------------------------------------'.'<br>';
preg_match("/(<([\w]+)[^>]*>)(.*?)(<\/\\2>)/", $html, $matches);
print_r($matches);

運(yùn)行結(jié)果(同樣的,結(jié)果中標(biāo)簽<b>被略去是因?yàn)槟秸n瀏覽器的原因,然而事實(shí)上這個(gè)標(biāo)簽是存在于匹配結(jié)果的):

  • demo2.1 這里分別寫(xiě)了preg_match_all以及preg_match兩種匹配方式并附上對(duì)應(yīng)的輸出結(jié)果,這里我們便可以具體形象地理解下面這段話(huà)了:

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



demo3.0(獲取<li>標(biāo)簽對(duì)中的內(nèi)容):

<?php
$str = "<ul>
            <li>item 1</li>
            <li>item 2</li>
        </ul>";
//在這里補(bǔ)充代碼,實(shí)現(xiàn)正則匹配所有l(wèi)i中的數(shù)據(jù)
$p = "/<li>(.*)<\/li>/i";
preg_match_all($p, $str, $matches);
print_r($matches[1]);

print_r($matches);

運(yùn)行結(jié)果:

Array
(
    [0] => item 1
    [1] => item 2
)
Array
(
    [0] => Array
        (
            [0] => <li>item 1</li>
            [1] => <li>item 2</li>
        )

    [1] => Array
        (
            [0] => item 1
            [1] => item 2
        )

)

demo3.1(附加標(biāo)簽PREG_SET_ORDER,調(diào)整輸出順序):

<?php
$str = "<ul>
            <li>item 1</li>
            <li>item 2</li>
        </ul>";
//在這里補(bǔ)充代碼,實(shí)現(xiàn)正則匹配所有l(wèi)i中的數(shù)據(jù)
$p = "/<li>(.*)<\/li>/i";
preg_match_all($p, $str, $matches,PREG_SET_ORDER);
print_r($matches[1]);

print_r($matches);

運(yùn)行結(jié)果:

Array
(
    [0] => item 2
    [1] => item 2
)
Array
(
    [0] => Array
        (
            [0] => <li>item 1</li>
            [1] => item 1
        )

    [1] => Array
        (
            [0] => <li>item 2</li>
            [1] => item 2
        )

demo3.2(稍改動(dòng),觀察再一種情況):

<?php
$str = "<ul>
            <li>item 1</li><li>item 2</li>
        </ul>";
//在這里補(bǔ)充代碼,實(shí)現(xiàn)正則匹配所有l(wèi)i中的數(shù)據(jù)
$p = "/<li>(.*)<\/li>/i";
preg_match_all($p, $str, $matches,PREG_SET_ORDER);
print_r($matches[1]);

print_r($matches);

運(yùn)行結(jié)果:

Array
(
    [0] => Array
        (
            [0] => item 1item 2
            [1] => item 1item 2
        )

)



7. 正則表達(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

分析一下正則表達(dá)式$patterns的意義 :
(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'

綜合demo:

<?php
$str = '主要有以下幾個(gè)文件:index.php, style.css, common.js';
//將目標(biāo)字符串$str中的文件名替換后增加em標(biāo)簽
$p = '/\w+\.\w+/i';
$str = preg_replace($p, '<em>$0</em>', $str);
echo $str.'<br>'.'<br>'.'<br>';
echo '----------------------------------------------'.'<br>';

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

$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
echo '<br>'.'<br>'.'----------------------------------------------'.'<br>';

$str = 'one     two';
$str = preg_replace('/\s+/', ' ', $str);
echo $str; // 結(jié)果改變?yōu)?one two'
echo '<br>'.'<br>'.'----------------------------------------------'.'<br>';
  • $0指的是$str里所有的匹配結(jié)果;
  • <em>標(biāo)簽修飾的內(nèi)容都是用斜體字來(lái)顯示;

運(yùn)行結(jié)果:
主要有以下幾個(gè)文件:index.php, style.css, common.js


----------------------------------------------
2014, April 15


----------------------------------------------
$startDate = 5/27/1999

----------------------------------------------
one two

----------------------------------------------



8. 正則匹配常用案例

  • 正則匹配常用在表單驗(yàn)證上,一些字段會(huì)有一定的格式要求,
    比如用戶(hù)名一般都要求必須是字母、數(shù)字下劃線(xiàn)組成,
    郵箱、電話(huà)等也都有自己的規(guī)則,
    因此使用正則表達(dá)式可以很好的對(duì)這些字段進(jìn)行驗(yàn)證。

通過(guò)一下的demo觀察一般的用戶(hù)注冊(cè)頁(yè),都怎樣對(duì)字段進(jìn)行驗(yàn)證:

  • die() 函數(shù) 輸出一條消息,并退出當(dāng)前腳本;
  • empty() 判斷一個(gè)變量是否被認(rèn)為是空的;
  • preg_match()返回匹配成功的次數(shù),
    使用合法格式的模板作為參數(shù),
    若函數(shù)返回為0說(shuō)明沒(méi)有匹配成功過(guò)一次,那便是對(duì)應(yīng)字符串不合法了。
<?php
$user = array(
    'name' => 'spark1985',
    'email' => 'spark@imooc.com',
    'mobile' => '13312345678'
);
//進(jìn)行一般性驗(yàn)證
if (empty($user)) {
    die('用戶(hù)信息不能為空');
}
if (strlen($user['name']) < 6) {
    die('用戶(hù)名長(zhǎng)度最少為6位');
}
//用戶(hù)名必須為字母、數(shù)字與下劃線(xiàn)
if (!preg_match('/^\w+$/i', $user['name'])) {
    die('用戶(hù)名不合法');
}
//驗(yàn)證郵箱格式是否正確
if (!preg_match('/^[\w\.]+@\w+\.\w+$/i', $user['email'])) {
    die('郵箱不合法');
}
//手機(jī)號(hào)必須為11位數(shù)字,且為1開(kāi)頭
if (!preg_match('/^1\d{10}$/i', $user['mobile'])) {
    die('手機(jī)號(hào)不合法');
}
echo '用戶(hù)信息驗(yàn)證成功';

運(yùn)行結(jié)果:

用戶(hù)信息驗(yàn)證成功

主要參考資料(慕課網(wǎng).PHP進(jìn)階篇)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 新士相是我置頂公眾號(hào)里不看的幾個(gè)之一,置頂是因?yàn)樗鶚?biāo)榜的“我們終究改變潮水的方向”,我想看看它是怎么去改變的。在...
    晨夕記閱讀 272評(píng)論 0 5
  • 十三歲以前,我都沒(méi)有坐過(guò)公交車(chē)。十三歲以前,我養(yǎng)過(guò)兩只狗。 寒暑假是漫長(zhǎng)的,往往開(kāi)學(xué)的時(shí)候我會(huì)很期待。因?yàn)榧倨陔m然...
    搖擺的野馬閱讀 694評(píng)論 0 3
  • #幸福是需要修出來(lái)的~每天進(jìn)步1%~幸福實(shí)修13班~22唐潔# 20171129(2/60) 【幸福三朵玫瑰】 昨...
    你謝謝閱讀 192評(píng)論 3 0
  • 在南方的清晨里醒來(lái),天氣非常悶熱。他打電話(huà)過(guò),對(duì)她說(shuō),他在長(zhǎng)途汽車(chē)站,要去一個(gè)小城看工廠,問(wèn)她是否有空和他一起同去...
    Keviniss閱讀 424評(píng)論 0 1
  • 一年又這么渾渾噩噩的過(guò)去了,想想在今年年初興誓旦旦立下的那些雄心壯志,勢(shì)要建一番的豐功偉業(yè),結(jié)果,每年到了這個(gè)時(shí)候...
    好姑娘小包同學(xué)閱讀 731評(píng)論 0 50

友情鏈接更多精彩內(nèi)容