正则表达式获取 C# 中模式的所有可能匹配项
Posted
技术标签:
【中文标题】正则表达式获取 C# 中模式的所有可能匹配项【英文标题】:Regex to get all possible matches for a pattern in C# 【发布时间】:2010-10-12 21:42:03 【问题描述】:我正在学习正则表达式,需要从字符串中获取模式的所有可能匹配项。
如果我的输入是:
case a
when cond1
then stmt1;
when cond2
then stmt2;
end case;
我需要获取具有以下组的匹配项
组 1:
"cond1"
"stmt1;"
和第 2 组:
"cond2"
"stmt2;"
是否可以使用任何正则表达式来获取此类组?
【问题讨论】:
我想我不明白。你的代码和正则表达式有什么关系? 我认为使用正则表达式而不是通过传统的编程方式处理它们会更容易获得所有这些循环/块。此外,我可以使用这样的正则表达式来解析许多不同的结构。 我觉得你应该写一个解析器,只用正则表达式解析源代码是行不通的。 我要解析多种语言,写很多解析器会很繁琐。 正如我所说:“仅使用正则表达式解析源代码是行不通的”。正则表达式不适合解析语言,它们只是错误的工具。 【参考方案1】:只要不嵌套语句,就可以使用正则表达式。例如,如果您的 stmt1 是另一个案例陈述,那么所有的赌注都将被取消(您不能使用正则表达式来处理类似的事情,您需要一个常规解析器)。
编辑:如果你真的想尝试一下,你可以用类似的东西来做(未经测试,但你明白了):
Regex t = new Regex(@"when\s+(.*?)\s+then\s+(.*?;)", RegexOptions.Singleline)
allMatches = t.Matches(input_string)
但正如我所说,这仅适用于非嵌套语句。
编辑 2:稍微更改了正则表达式以在最后一组中包含分号。这不会像你想要的那样工作 - 相反,它会给你多个匹配项,每个匹配项将代表一个 when 条件,第一组是条件,第二个 group 是语句.
我认为您无法构建一个完全符合您要求的正则表达式,但这应该足够接近(我希望)。
编辑 3:新的正则表达式 - 应该处理多个语句
Regex t = new Regex(@"when\s+(.*?)\s+then\s+(.*?)(?=(when|end))", RegexOptions.Singleline)
它包含一个肯定的前瞻,以便第二组从 then 匹配到下一个“何时”或“结束”。在我的测试中,它适用于:
case a
when cond1
then stmt1;
stm1;
stm2;stm3
when cond2
then stmt2;
aaa;
bbb;
end case;
现在是区分大小写的,所以如果你需要不区分大小写,你需要添加相应的正则表达式标志。
【讨论】:
是的,没错,但为此我可以检查下一个案例并取出它之前的字符串以对其应用模式并可以获得所有可能的匹配项。那么,您能帮忙形成正则表达式吗? 好吧,我试过这个正则表达式,但它不起作用。另外,根据pl/sql中的case表达式,之后可以有多个语句。 Edit 3 产生了两场比赛,每场比赛有三个分组(cond1 stmt1; when)。 是的,我需要为前瞻添加第三组,但可以放心地忽略它。每场比赛的前两组包含肉。【参考方案2】:我认为这是不可能的,主要是因为匹配 when...then... 的任何组都将匹配所有这些,从而在同一组中创建多个捕获。
我建议使用这个正则表达式:
(?:when(.*)\nthen(.*)\n)+?
导致:
第 1 场比赛: * 第一组:cond1 * 第 2 组:stmt1; 第 2 场比赛: * 第 1 组:cond2 * 组 2:stmt2;
【讨论】:
非常感谢。但是这个正则表达式只在换行时才有效。所以尝试将其修改为 (?:when(.*)\s+then(.*)\s*)+?但它仍然无法正常工作。 嗯,我复制了您的示例文本并对其进行了测试。也许您的实际数据不同?我没有设置任何正则表达式选项(没有 SingleLine,没有 MultiLine)。 'when' 不是从换行开始吗? 不一定。如果“when”没有从换行符开始,我认为它不会给出任何语法错误。【参考方案3】:如果这是用 java 编写的,我将为解析器编写两种模式,一种用于匹配情况,另一种用于匹配 when-then 情况。后者的写法如下:
CharSequence buffer = inputString.subSequence(0, inputString.length());
// inputString is the string you get after matching the case statements...
Pattern pattern = Pattern.compile(
"when (\\S+).*"
+ "then (\\S+).*");
Matcher matcher = pattern.matcher(buffer);
while (matcher.find())
DoWhenThen(matcher.group(1), matcher.group(2));
注意:我尚未测试此代码,因为我不能 100% 确定该模式...但我会对此进行修补。
【讨论】:
以上是关于正则表达式获取 C# 中模式的所有可能匹配项的主要内容,如果未能解决你的问题,请参考以下文章
C# 正则表达式 - 为括号内的单个模式查找一个或多个匹配项