2017-05-15 88 views
5

裏面我有以下的正則表達式,用於和工作原理:告訴正則表達式忽略括號時報價

/\[email protected](@?\w+(?:::\w+)?)([ \t]*)(\(((?>[^()]+) | (?3))* \))?/x

在此字符串@extends('template', 'test')正確組,給我我需要什麼。

的問題是,如果字符串中包含引號內未封閉的括號 - 它將會失敗:

@extends('template', 'te)st')@extends('template', 'te)作爲輸出

我怎樣才能知道這個表達式忽略括號是引號內(無論是'"

這是問題的一個RegExr演示:http://regexr.com/v1?396ci

而她e是一個字符串列表應該都能夠通過:

@extends('template', 'test')  // working 
@extends('template', $test)  // working 
@extends('template', 'te()st') // working 
@extends('template', 'te)st') // broken 
@extends('template', 'te())st') // broken 
@extends('template', 'te(st') // broken 
@extends('template', 'test)') // broken 
@extends('template', '(test') // broken 

我已經收窄 - 我想我需要能夠說

(
    \( <-- only if not inside quotes 
    ( 
     (?>[^()]+) | (?3) 
    )* 
    \) <-- only if not inside quotes 
)? 

但我似乎無法工作如何這條規則適用於這些特定的括號

回答

3

您可以使用前瞻用於此目的

這裏是我的正則表達式,將匹配到的所有第二個參數

| [\ W)(] +

擊穿(=(\ w +)\ w +()):

':開始字符串與報價搜索

?=XXX):積極向前看確保XXX存在提前

(\w+\)|\w+\():搜索無論是打開或關閉括號

現在,如果這個向前看是成功的,我們可以肯定的是,我們有一個報價,然後括號。現在,我們可以簡單地寫正則表達式,使括號

[\w\)\(]+:現在正在做的只是

,我們可以使用其內部括號定位的報價,我們可以使用if-else條件使用適當的每個案例的規則

(?(?=regex)then|else)

這裏的豪w我已經實現了它:

(?(?='(?=(\w+\)|\w+\())) <- condition, same as above 
'[\w\)\(]+' <- We have a match so we ignore parenthesis 
|'\w+' <- Here we don't 
) 

ps。我不明白你爲你的正則表達式中的其他部分寫了什麼,也許是爲了覆蓋其他一些情況,所以我沒有寫出修改你的原始正則表達式。您可以簡單地切換第二個參數的檢查與上面提到的那個

這是我的正則表達式匹配所有你的情況。

\[email protected]\w+\('[\w+\s]+',\s+(?(?='(?=(\w+\)|\w+\()))'[\w\)\(]+'|('\w+'|\$\w+))\)

你可以看到測試用例here

PS。只是爲了表明它的實際工作,我已經添加了一些失敗的測試用例

+0

感謝@Mayank - 這很接近 - 但它不包括測試用例的最終')'? – Laurence

+0

p.s.我添加了一個額外的測試用例,我忘了在原始問題中包含這些用例。 – Laurence

+0

@Laurence,按預期工作? –