告诉 RegEx 在引号内忽略括号
Tell RegEx to ignore parenthesis when inside a quote
我使用并运行了以下正则表达式:
/\B@(@?\w+(?:::\w+)?)([ \t]*)(\( ( (?>[^()]+) | (?3) )* \))?/x
这个字符串 @extends('template', 'test')
正确分组并提供我需要的东西。
问题是如果字符串在引号内包含未闭合的括号 - 它会失败:
@extends('template', 'te)st')
给出 @extends('template', 'te)
作为输出
如何告诉此 RegEx 忽略引号内的括号('
或 "
)
这是问题的 RegExr 演示:http://regexr.com/v1?396ci
下面是应该都可以通过的字符串列表:
@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
)?
但我似乎无法弄清楚如何将该规则应用于这些特定的括号
您可以为此目的使用前瞻
这是我的正则表达式,它将匹配所有 extends
的第二个参数
(?=(\w+)|\w+())[\w)(]+
细分:
'
: Start the search for string with quote
?=XXX)
: Positive look ahead which ensures XXX is present ahead
(\w+\)|\w+\()
: Search for either opening or closing braces
现在,如果这种前瞻性成功,我们可以确定我们有一个引号后跟一个括号。现在我们可以简单地编写正则表达式来制作括号
[\w\)\(]+
: Doing just that
现在我们可以找到其中带有括号的引号,我们可以使用 if-else 条件为每种情况使用适当的规则
(?(?=regex)then|else)
以下是我的实现方式:
(?(?='(?=(\w+\)|\w+\())) <- condition, same as above
'[\w\)\(]+' <- We have a match so we ignore parenthesis
|'\w+' <- Here we don't
)
ps。我不明白你在正则表达式中为其他部分写的很多东西,也许是为了涵盖其他一些情况,所以我不会写来修改你原来的正则表达式。您可以简单地将第二个参数的检查切换为上面提到的
这是我的正则表达式,它与您的所有情况都匹配。
\B@\w+\('[\w+\s]+',\s+(?(?='(?=(\w+\)|\w+\()))'[\w\)\(]+'|('\w+'|$\w+))\)
可以看到测试用例here
PS。为了证明它确实有效,我添加了一些失败的测试用例
我使用并运行了以下正则表达式:
/\B@(@?\w+(?:::\w+)?)([ \t]*)(\( ( (?>[^()]+) | (?3) )* \))?/x
这个字符串 @extends('template', 'test')
正确分组并提供我需要的东西。
问题是如果字符串在引号内包含未闭合的括号 - 它会失败:
@extends('template', 'te)st')
给出 @extends('template', 'te)
作为输出
如何告诉此 RegEx 忽略引号内的括号('
或 "
)
这是问题的 RegExr 演示:http://regexr.com/v1?396ci
下面是应该都可以通过的字符串列表:
@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
)?
但我似乎无法弄清楚如何将该规则应用于这些特定的括号
您可以为此目的使用前瞻
这是我的正则表达式,它将匹配所有 extends
(?=(\w+)|\w+())[\w)(]+
细分:
'
: Start the search for string with quote
?=XXX)
: Positive look ahead which ensures XXX is present ahead
(\w+\)|\w+\()
: Search for either opening or closing braces
现在,如果这种前瞻性成功,我们可以确定我们有一个引号后跟一个括号。现在我们可以简单地编写正则表达式来制作括号
[\w\)\(]+
: Doing just that
现在我们可以找到其中带有括号的引号,我们可以使用 if-else 条件为每种情况使用适当的规则
(?(?=regex)then|else)
以下是我的实现方式:
(?(?='(?=(\w+\)|\w+\())) <- condition, same as above
'[\w\)\(]+' <- We have a match so we ignore parenthesis
|'\w+' <- Here we don't
)
ps。我不明白你在正则表达式中为其他部分写的很多东西,也许是为了涵盖其他一些情况,所以我不会写来修改你原来的正则表达式。您可以简单地将第二个参数的检查切换为上面提到的
这是我的正则表达式,它与您的所有情况都匹配。
\B@\w+\('[\w+\s]+',\s+(?(?='(?=(\w+\)|\w+\()))'[\w\)\(]+'|('\w+'|$\w+))\)
可以看到测试用例here
PS。为了证明它确实有效,我添加了一些失败的测试用例