2016-10-12 47 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允許用'*'和'+'量化子模式。您可能會失敗或要求子模式出現在您需要的模式之前,而不是緊接在它之前。 –