2017-05-15 55 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,按预期工作? –