如何解决将嵌套的配对组与通配符配对
我需要解析一堆看起来像这样的基于文件的旧数据:
(or
(if (eq ?SSD-enart_Cl:sName rueck1)
then
(or (eq ?SSD_Cl:sName sb405)
(eq ?SSD_Cl:sName sb455)
(eq ?SSD_Cl:sName sb52)
)
)
(if (eq ?SSD-enart_Cl:sName rueck3)
then
(or (eq ?SSD_Cl:sName sb38)
(eq ?SSD_Cl:sName sb405)
(eq ?SSD_Cl:sName sb43)
(eq ?SSD_Cl:sName sb455)
(eq ?SSD_Cl:sName sb48)
)
)
(if
(eq ?SSD-enart_Cl:sName r-SSD-ck4)
then
(<> ?SSD_Cl:qty -1)
)
)
我需要一个通配符正则表达式,它将匹配并返回以<whitespace>(xxx<whitespace>....)<whitespace>
开头的分组括号的集合,其中xxx
是通配符字符串,而<whitespace>
不是文字字符串,而是任何空格,最常见的是制表符,空格或换行符。而且我需要在匹配项中嵌套嵌套的paren-group,以便根据匹配项将其忽略,但将其作为外部匹配项的一部分包含在内。一些场景/示例将使这一点很清楚,并且所有示例都与上面显示的数据有关。
-
xxx
=or
,因此正则表达式将查找<whitespace>(or<whitespace>....)<whitespace>
这应该返回一个匹配项:(or ... )
中数据的全部内容,具体是:
(if (eq ?SSD-enart_Cl:sName rueck1)
then
(or (eq ?SSD_Cl:sName sb405)
(eq ?SSD_Cl:sName sb455)
(eq ?SSD_Cl:sName sb52)
)
)
(if (eq ?SSD-enart_Cl:sName rueck3)
then
(or (eq ?SSD_Cl:sName sb38)
(eq ?SSD_Cl:sName sb405)
(eq ?SSD_Cl:sName sb43)
(eq ?SSD_Cl:sName sb455)
(eq ?SSD_Cl:sName sb48)
)
)
(if
(eq ?SSD-enart_Cl:sName r-SSD-ck4)
then
(<> ?SSD_Cl:qty -1)
)
-
xxx
=if
,因此正则表达式将查找<whitespace>(if<whitespace>....)<whitespace>
这应该准确返回3个匹配项:
第1场比赛:
(if (eq ?SSD-enart_Cl:sName rueck1)
then
(or (eq ?SSD_Cl:sName sb405)
(eq ?SSD_Cl:sName sb455)
(eq ?SSD_Cl:sName sb52)
)
)
第2场比赛:
(if (eq ?SSD-enart_Cl:sName rueck3)
then
(or (eq ?SSD_Cl:sName sb38)
(eq ?SSD_Cl:sName sb405)
(eq ?SSD_Cl:sName sb43)
(eq ?SSD_Cl:sName sb455)
(eq ?SSD_Cl:sName sb48)
)
)
第3场比赛:
(if
(eq ?SSD-enart_Cl:sName r-SSD-ck4)
then
(<> ?SSD_Cl:qty -1)
)
注意:我严格不需要比赛中返回的字符串中包含(if
和结尾)
;只是其中的内容。但这两种方法都很好-无论哪种方法都更容易。
-
xxx
=or
,因此正则表达式将查找<whitespace>(or<whitespace>....)<whitespace>
在此示例中,我们只需要查看or
中的一个,因为我将始终评估给定if
的字符串,而不是整个字符串。因此,我们可以仅查看第二个or
中的if
,例如:
(if (eq ?SSD-enart_Cl:sName rueck3)
then
(or (eq ?SSD_Cl:sName sb38)
(eq ?SSD_Cl:sName sb405)
(eq ?SSD_Cl:sName sb43)
(eq ?SSD_Cl:sName sb455)
(eq ?SSD_Cl:sName sb48)
)
)
这应返回恰好1个匹配项:
(or (eq ?SSD_Cl:sName sb38)
(eq ?SSD_Cl:sName sb405)
(eq ?SSD_Cl:sName sb43)
(eq ?SSD_Cl:sName sb455)
(eq ?SSD_Cl:sName sb48)
)
-
xxx
=eq
,因此正则表达式将查找<whitespace>(eq<whitespace>....)<whitespace>
同样,我将始终(通过c#而不是regex)深入嵌套,例如,在第二个or
中包含以下if
块,而不是整个字符串。因此,我们只看第二个eq
的{{1}}中的or
,例如:
if
我希望正好有5个匹配项,每个匹配项(or (eq ?SSD_Cl:sName sb38)
(eq ?SSD_Cl:sName sb405)
(eq ?SSD_Cl:sName sb43)
(eq ?SSD_Cl:sName sb455)
(eq ?SSD_Cl:sName sb48)
)
。
现在我已经给出了示例,以下是可以视为绝对原则:
- 在所有情况下都会有paren-grouping,我需要正则表达式不尝试匹配内部匹配的嵌套paren-grouping,但仅匹配外部匹配。但是内部分组应作为外部匹配的一部分返回。正则表达式应将任何内部嵌套的括号都视为普通字符串,并仅与匹配项一起返回,而不要尝试将其视为匹配项。总之,例如,当正则表达式找到
(eq...)
...时,它需要去寻找(if
的结尾)
,而忽略其中的任何括号。 - 我需要能够以编程方式向正则表达式提供自己的通配符,它们可以是
(if
,if
,and
等。通配符文本永远不会是特殊的字符,只是常规的小写字母,并且在所有情况下都将以一个开头括号,该空格本身将以空格开头,然后将始终有一个结尾括号。在这些匹配的外部括号之间,通常会有更多的括号,出于匹配目的,应将其忽略,但将其作为普通字符串作为匹配内容返回。 - 内部和外部匹配集总是正确的。开头没有比结尾更多的了,反之亦然,这当然会使正则表达式感到困惑。
- (我相信)单个正则表达式表达式应该能够容纳所有内容,并且我将在运行时提供通配符文本。
我目前在我的应用程序中有一个正则表达式,几乎可以执行我在这里要执行的操作,除了它匹配双引号而不是打开/关闭括号的
or
即使在匹配的字符串中经常有更多的双引号,上述函数也可以很好地找到双引号的“ endcap集”。我需要的是类似的方法:打开/关闭成组的括号,但始终在开头的括号旁带有通配符字符串。不幸的是,我是一名正则表达式初学者,无法弄清楚如何以一种可行的方式修改上述正则表达式。
编辑
我担心我上面的超详细文章会吓跑人。这比看起来要简单得多,所以让我简化一下。我需要一个与public static MatchCollection GetQuotedStrings(string str) {
Regex regex = new Regex("(\"([^\"]|\"\")*\")");
return regex.Matches(str);
}
的所有实例匹配的正则表达式,其中(if...)
始终以空格开头,总是有一个闭合的(if
,而)
代表很多杂项内容。
唯一棘手的部分是,外部...
分组内部经常会有其他(..)
分组,并且这些内部分组需要像普通字符串一样对待,并且不能与正则表达式匹配。就是这样。
解决方法
原来是答案:
$@"\({wildcard}(?>\((?<c>)|[^()]+|\)(?<-c>))*(?(c)(?!))\)"
我在运行时将wildcard
传递给函数,并且效果很好。
我从这里收集了解决方案:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。