關於一些正規筆記 請參考前一篇。這裡直接從範例開始解析正規的順序:
範例字串:
$a = "_func1('abcdef') xxxx _func2('abcdefghijkl') xxxx _func1('1234567890') xxxx";
正規表示式:
/(?P<tag>(?|_func1|_func2))\((?P<quote>(?|'|\"))(?P<content>[^'\"]*)/i
```
看起來很複雜,實際上正規表示式的運作模式大抵上可以這樣解釋:
1. 先做全域比對(這是在 PHP 使用 preg\_match 系列時會這麼做)。
* 再做群組區塊比對,比對區塊 1。
* 比對區塊 2。
* 依此類推。
所以第一次比對時,會比對整條正規表示式:
```
(?P<tag>(?|_func1|func2))\((?P<quote>(?|'|\"))(?P<content>[^'\"]*)
```
所得到的結果會是:
```
[0] => Array (
[0] => \_func1('abcdef
[1] => \_func2('abcdefghijkl
[2] => \_func1('1234567890
)
```
接著比對第一個群組:
```
(?P<tag>(?|_func1|func2))
```
所得到的結果會是:
```
[tag] => Array (
[0] => \_func1
[1] => \_func2
[2] => \_func1
)
[1] => (
[0] => \_func1
[1] => \_func2
[2] => \_func1
)
```
再來繼續比對第二個群組:
```
(?P<quote>(?|'|\"))
```
所得到的結果是:
```
[quote] => Array (
[0] => '
[1] => '
[2] => '
)
[2] => Array (
[0] => '
[1] => '
[2] => '
)
```
最後比對第三個群組:
```
(?P<content>[^'\"]*)
```
所得到的結果是:
```
[content] => Array (
[0] => abcdef
[1] => abcdefghijkl
[2] => 1234567890
)
[3] => Array (
[0] => abcdef
[1] => abcdefghijkl
[2] => 1234567890
)
```
要注意的地方有:
* 請勿在一開始就使用左(右)合(不合)樣式,除非你很清楚你要做什麼。
* 第一次比對若無符合項目,則往後的比對都會直接中斷。
* 比對的順序是由左至右,判斷式與左(右)合(不合)樣式有些例外。
使用 **右不合樣式** 的範例,我們給一個字串:
```
$a = "123123 456456 789789 123000 456000 789000";
```
使用正規表示式:
```
(?>[0-9]{6})(?<![123])/
```
產生結果為:
```
[0] => Array (
[0] => 456456
[1] => 789789
[2] => 123000
[3] => 456000
[4] => 789000
)
```
這個正規在做的事情,大致上是這樣:
1. 我要 0~9 的六碼數字。
* <span style="color:#177fcd;">並且這些數字不會是有包含 123 為右方結尾的字串</font>。
何謂 **右不合**?
意思就是,當我字串符合條件時,從右邊往左比對的結果是不是符合我所需要的判斷。同樣的,左不合的意思就是從左邊往右邊比對的結果,但是,這兩個正規放的地方並不太一樣,底下是 **左不合** 的案例:
使用正規表示式:
```
(?![123])(?>[0-9]{6})
```
產生的結果是:
```
[0] => Array (
[0] => 456456
[1] => 789789
[2] => 456000
[3] => 789000
)
```
這樣看出差異性了嗎?所以,如果要使用判斷式(`(?( ) )` 樣)的話,請先想好你的判斷條件,左(右)合(不合)樣所放置的位置是不一樣的。所以,我們在上一篇的截斷問題,就可以用判斷式來解決。
留個引子吧。
##/(?:(?|_func1|_func2))\(<span style="color:#d41a01;">(?</span><span style="color:#008000;">(?=['])</span><span style="color:#177fcd;">(?:'([^']*))</span><span style="color:#d41a01;">|</span><span style="color:#ff3399;">(?:\"([^\"]*))</span><span style="color:#d41a01;">)</span>/
留意有顏色的地方就好了。我沒有加上群組命名,所以比較乾淨,這樣應該很容易就能看懂了。
祝各位在正規的地獄中得道昇天!