2014-05-15 71 views
1

嗯,我不認爲標題是正確的,但這裏是問題所在。優化正則表達式來區分captchure組引號

我在標籤簡碼工作,有這樣的正則表達式的正常工作

http://regex101.com/r/fR0iV7

[tabs id="myid" type="tabnav"] 
    [tabsgroup title="Tab title" active="1"]Tab content goes here...[/tabsgroup] 
    [tabsgroup title="Tab title" active="0"]Tab content goes here...[/tabsgroup] 
    [tabsgroup title="Tab title" active="0"]Tab content goes here...[/tabsgroup] 
    [/tabs] 

$re = '/\[tabsgroup .*?title\=\"(.*?)\".*?active\=\"(.*?)\"](.*?)\[\/tabsgroup \]/s'; 


// print 

MATCH 1 
1. [49-58] `Tab title` 
2. [68-69] `1` 
3. [71-95] `Tab content goes here...` 
MATCH 2 
1. [126-135] `Tab title` 
2. [145-146] `0` 
3. [148-172] `Tab content goes here...` 
MATCH 3 
1. [203-212] `Tab title` 
2. [222-223] `0` 
3. [225-249] `Tab content goes here...` 

,直到我嘗試使用標題中的圖標。

[tabsgroup title="Tab title <span class="fa fa-star"></span>" active="1"]Tab content goes here...[/tabsgroup] 

比賽部分出來爲http://regex101.com/r/xM8cW8

MATCH 1 
1. [49-72] `Tab title <span class=` 
2. [102-103] `1` 
3. [105-129] `Tab content goes here...` 

我知道這是因爲我拍攝這個title\=\"(.*?)\"但我不知道如何改進它,使它能夠在自己的引號之間的區別和引號內的引號。 任何幫助表示讚賞。

+1

甲快速修復由做到這一點:'$圖案=「〜\ [ 「(+> | [^(><[^>?])*?)」 tabsgroup *標題=?]」。 *?active =「(。*?)」](。*?)\ [/ tabsgroup]〜';'(想法是跳過尖括號之間的部分)但請記住,因爲它包含幾個'。* ?',它不是一種防水圖案 –

+0

@Cimimir發佈它回答請添加可能的問題的解釋,如果你可以看起來像一場比賽!:) http://regex101.com/r/rQ9xE3 – Benn

+0

我添加了一個如果用regex101測試它,請不要忘記將分隔符更改爲'〜'(我使用這個命令避免每個斜槓轉義) –

回答

1

,可以快速跳過所有尖括號之間的屬性值的所有部分解決這個問題:

$pattern = '~ 
    \[tabsgroup .*? 
     title="((?> <[^>]+> | [^"])*)" .*? 
     active="(.*?)" 
    ] 
    (.*?) 
    \[/tabsgroup]‌​ ~xs'; 

但是,請記住,使用.*.*?是危險的,可以給你意想不到的結果,因爲這些子模式絕對可以匹配所有。我不知道你的短代碼的所有可能屬性是什麼,但我建議通過更明確的內容更改.*?。例如:

$pattern = <<<'EOD' 
~ 
    \[tabsgroup 
     \s+ # if you know that it can only be white characters 
      # otherwise use \s[^]]*? 
     title="((?> <[^>]+> | [^"])*)" 
     \s+ # the same here 
     active="([^"]*)" # no quotes allowed here 
     # or you can reuse the title subpattern: active="((?1))" 
     # however, if only possible values are 0 and 1: active="([01])" 
    ] 
    (.*?) # This can be change to ([^[]+) if you are sure to not have 
      # other tags inside. 
      # If it is not the case: ((?>[^[]+|\[(?!/tabsgroup]))*) 
      # will match all except [/tabsgroup] 
    \[/tabsgroup]‌ 
~xs 
EOD; 
// Once there is no more dot, don't forget to remove the s modifier