2011-10-09 76 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 
相关问题