2014-09-21 122 views
1

我寫了一個正則表達式模式,當我在Regexr中測試它時,它完美地工作,但是當我在我的PHP代碼中使用它時,它並不總是匹配。PHP的正則表達式反向引用不起作用

The regular expression,包括一些應該和不應該匹配的示例。

示例PHP代碼應該匹配,但不會:

preg_match('/^([~]{3,})\s*([\w-]+)?\s*(?:\{([\w-\s]+)\})?\s*(\2[\w-]+)?\s*$/', "~~~ {class} lang", $matches); 
echo var_dump($matches); 

我相信這個問題是由最後捕獲組(\2[\w-]+)在逆向引用造成的,但是,我不能一刀弄清楚如何解決這個。

回答

2

因爲您指的是一個不存在的組(組2)。所以從正則表達式中刪除\2

^([~]{3,})\s*([\w-]+)?\s*(?:\{([-\w\s]+)\})?\s*([\w-]+)?\s*$ 

DEMO

~~~ {class} lang 
    | | |  | 
    Group1| Group3 Group4 
     | 
Missing group 2 
+1

我喜歡,你怎麼說明吧:) – 2014-09-21 16:30:00

+0

謝謝,你和@hwnd幫我弄明白了。 – CupOfTea696 2014-09-21 21:26:06

2

問題是通過捕獲組#2造成的,你做這組可選。因此,因爲它可能存在也可能不存在,所以您需要使反向引用可選,否則它總是查找所需的組。

但是,由於所有的組都是可選的,我只是遞歸第二組的子模式。

^(~{3,})\s*([\w-]+)?\s*(?:{([^}]+)})?\s*((?2))?\s*$ 

示例:以下

$str = '~~~ {class} lang'; 
preg_match('/^(~{3,})\s*([\w-]+)?\s*(?:{([^}]+)})?\s*((?2))?\s*$/', $str, $matches); 
var_dump($matches); 

輸出

array(5) { 
    [0]=> string(16) "~~~ {class} lang" 
    [1]=> string(3) "~~~" 
    [2]=> string(0) ""     # Returns "" for optional groups that dont exist 
    [3]=> string(5) "class" 
    [4]=> string(4) "lang" 
} 
+0

問題是這樣'~~~ lang {class} lang'也給出了一個匹配,它不應該。 – CupOfTea696 2014-09-21 21:15:22

+0

我剛剛解決了它,我把第二個捕獲組更改爲'([\ w - ] *)',當它不在那裏而不是不存在時,它是一個空字符串。 – CupOfTea696 2014-09-21 21:25:27

+0

告訴我它應該完全匹配,當我回家時我會看一下 – hwnd 2014-09-21 21:35:21

0

的答案幫助我弄清楚,爲什麼它不工作。然而,兩個答案都會給我不想要的$str = '~~~ lang {class} lang';做出正面匹配。 我將它修改爲我更改的捕獲組2至([\w-]*),這樣即使在那個地方沒有字符串,捕獲組仍然存在,但仍然是空的。這樣,所有下列字符串匹配:

$str = '~~~ lang  {no-lines float left} '; 
$str = '~~~  {class} '; 
$str = '~~~ lang'; 
$str = '~~~ {class } lang '; 
$str = '~~~'; 
$str = '~~~lang{class}'; 

但是這一次不會:

$str = '~~~ css {class} php'; 

完整的解決方案:

$str = '~~~ {class} lang'; 
preg_match('/^([~]{3,})\s*([\w-]*)?\s*(?:\{([\w-\s]+)\})?\s*(\2[\w-]+)?\s*$/', $str, $matches); 
var_dump($matches);