2016-10-12 51 views
4

我试图在单引号内搜索单词的字符串,但前提是这些单引号不在括号内。排除特定上下文的正则表达式匹配

例字符串: something, 'foo', something ('bar')

因此,对于给定的例子,我想匹配foo,但不bar

在搜索正则表达式示例后,我可以在单引号内匹配(请参阅下面的代码片段),但不确定如何在上述上下文中排除匹配。

string line = "something, 'foo', something ('bar')"; 
Match name = Regex.Match(line, @"'([^']*)"); 
if (name.Success) 
{ 
    string matchedName = name.Groups[1].Value; 
    Console.WriteLine(matchedName); 
} 
+0

圆括号是否围绕单引号? IE浏览器。 '(文本'foo'文本)'匹配“foo”? – Richard

+0

Regex101.com是一个很好的网站,用于测试正则表达式以查找它是否按照您期望的方式运行。 – Woot

+2

@Woot:Regex101不支持.NET正则表达式。为了测试.NET正则表达式,Ultrapico Expresso工具非常好。 –

回答

3

我会建议使用向前看,而不是使用(见它live):

(?<!\()'([^']*)'(?!\)) 

或用C#:

string line = "something, 'foo', something ('bar')"; 
Match name = Regex.Match(line, @"(?<!\()'([^']*)'(?!\))"); 
if (name.Success) 
{ 
    Console.WriteLine(name.Groups[1].Value); 
} 
2

最简单的方式来获得你所需要的是使用交替组和匹配并捕获你所需要的东西,只匹配你不需要的东西:

\([^()]*\)|'([^']*)' 

regex demo

详细

  • \( - 一个(
  • [^()]* - 比()其他0+字符
  • \) - 一个)
  • | - 或
  • ' - 单引号 - 一个'
  • ([^']*) - 比'
  • '其他组1个捕获0+字符。

在C#中,使用.Groups[1].Value来获取所需的值。见online demo

var str = "something, 'foo', something ('bar')"; 
var result = Regex.Matches(str, @"\([^()]*\)|'([^']*)'") 
    .Cast<Match>() 
    .Select(m => m.Groups[1].Value) 
    .ToList(); 

另一种方法是由托马斯提到的,但因为它是.NET,您可以使用无限宽度的回顾后

(?<!\([^()]*)'([^']*)'(?![^()]*\)) 

this regex demo

详细

  • (?<!\([^()]*) - 负回顾后失败的比赛,如果有(随后与比(其他0+字符和)高达
  • '([^']*)' - 报价,0+其他字符比单引号捕获到组1中,而另一个单引号
  • (?![^()]*\)) - 如果除了01以外的0+字符,则匹配失败的负向前瞻和)跟在)后面的'之前的子模式。

由于您想要排除',因此应用上述相同的代码。

+0

我欣赏深入的解释,帮助我理解你的方法。我试图理解两种解决方案之间的差异:无限宽度lookbehind提供了什么优势? –

+0

无限宽度lookbehind允许用'*'和'+'量化子模式。您可能会失败或要求子模式出现在您需要的模式之前,而不是紧接在它之前。 –