2011-10-09 71 views
2

我想用下面的模式匹配正則表達式的字符串。使用正則表達式來匹配帶引號的字符串與嵌入的非轉義引號

string text = "'Emma','The Last Leaf','Gulliver's travels'"; 
string pattern = @"'(.*?)',?"; 

foreach (Match match in Regex.Matches(text,pattern,RegexOptions.IgnoreCase)) 
{ 
    Console.WriteLine(match + " " + match.Index); 
    Console.WriteLine(match.Groups[1].Captures[0]); 
} 

這符合「愛瑪」和「最後一片葉子」正確,但第三場比賽是「格列佛」。但希望的搭配是「格列佛遊記」。我怎樣才能爲這樣的模式建立一個正則表達式?

+0

如果添加逗號你的輸入更語言學問題:) – madhead

+4

字符串,你可以去掉',?'中的'?',這會導致錯誤的匹配。有沒有辦法可以得到正確的轉義輸入字符串?如果這本書實際上被命名爲「Gulliver'的旅行」,你會怎麼做? – bzlm

+1

您可以使用平衡分組處理嵌套字符(http://blogs.msdn.com/b/bclteam/archive/2005/03/15/396452.aspx)。但是,嵌套字符並不是你的問題中最糟糕的。真正的問題是'格列佛'中的撇號不會逃脫。這確實使解析器的規則很難定義。 –

回答

4

由於,是你的分隔符,你可以嘗試改變你的模式。它應該工作。

string pattern = @"'(.*?)'(?:,|$)"; 

這種方式的工作方式是,它尋找一個單引號,後面跟着逗號或行尾。

+0

+1因爲它「在這裏工作」,但請參閱bzlm的(也許是愚蠢的;-)反例:「艾瑪」,「最後一片葉子」,「格列佛」,旅行' - 只要記住正則表達式相對*脆弱*獸。 – 2011-10-09 19:32:11

+0

@pst OP的要求是匹配兩個單引號之間的字符串部分,並且每個字符只能用逗號分隔。據我瞭解''是這裏唯一的救援。否則,正如你所說這個任務需要一個複雜的(或不可能的)正則表達式。將上面的正則表達式應用到您給出的文本上,可以得到預期的輸出結果:Emma,Last Leaf,Gulliver以及無意義的行程 –

+0

+1。只要你解析的字符串不包含逗號和撇號的奇怪組合,超出了我們已經看到的,那麼這應該就足夠了。 –

0

如果您有單引號分隔字符串,並且Gulliver's包含單個未轉義引號,則無法將其與字符串末尾區分開。你總是可以只用逗號分開,並從兩邊修剪'秒,但我不知道這是你想要的東西:

string text = "'Emma','The Last Leaf','Gulliver's travels'"; 

foreach(string s in text.split(new char[] {','})) { 
    Console.WriteLine(s.Trim('\'')); 
} 
+0

從技術上講,它可以與字符串的末尾區分開來,因爲引號後面沒有逗號或者是輸入中的最後一個字符。 :) – bzlm

+0

@bzlm:我認爲你有自己的答案:) – Ryan

2

我認爲這是可以正常工作'(.*?)',|'(.*)'爲正則表達式。

+0

嘗試與LINQPad(http://linqpad.org) - *不*它的工作?如果格列佛遊記是第一次呢? – 2011-10-09 19:28:08

+0

我檢查過expresso(http://www.ultrapico.com/)兩個版本(格列佛在結束時/在開始時)似乎工作 – esunar

+0

它的工作原理是因爲交替是有序的。它始終嘗試''(。*?)','首先,除了最後一個項目外,其他所有項目都匹配,無論嵌入的撇號如何。相當優雅,真的。 –

1

你可以考慮使用向後看/向前看:

"(?<=^'|',').*?(?='$|',')" 

測試使用grep

kent$ echo "'Emma','The Last Leaf','Gulliver's travels'"|grep -Po "(?<=^'|',').*?(?='$|',')" 
Emma 
The Last Leaf 
Gulliver's travels 
相關問題