我使用专有语言进行经典if, else, endif
实现。
鉴于我有下面的字符串,我想找到[!--@Else--]
语句,但只找到[!--@If--]...[!--@EndIf--]
块中 NOT 的语句。因此,在匹配if
之前,我想要偶数个开头并关闭else
...
Lorem ipsum [!--@If(1=1)--] One it is [!--@If(2=1)--] 2 is not 1 [!--@Else--] so do this [!--@EndIf--] [!--@Else--] 1 is not 1 [!--@EndIf--] and something else
在这个例子中,我想找到第二个else
- 而不是第一个,因为它位于if/endif
块内。
我现在已经花费了无数个小时的消极和积极的观察,并且无法让它发挥作用!?
答案 0 :(得分:0)
您可以使用此正则表达式来检索每个if块的内容,作为匹配组VALUE
的一部分。最外面的匹配是数组中的最后一个:
(?<=\bif)(?>if(?<DEPTH>)|(?<VALUE-DEPTH>)endif|.?)*(?(DEPTH)(?!))(?=endif\b)
请注意,为清楚起见,我使用if
和endif
来表示您的开始和结束语法。
然后,您可以在组中的最后一个值上使用此正则表达式来提取else子句:
(?<=else)((?!else).)+$
答案 1 :(得分:0)
正如Abbondanza所说,如果你想用正则表达式做这个,你需要平衡组。我应该警告你,这不是一个好的解决方案。虽然.NET的正则表达式引擎是为数不多的,可以处理这样的情况,但它仍然不是真正推荐的方法。您可能最好手动解析语言,这样可以更轻松地计算嵌套级别。
无论如何,只是为了告诉你,为什么正则表达式不适合生产软件中的这个任务,这里有一个正则表达式(使用RegexOptions.IgnorePatternWhitespace
和RegexOptions.Singleline
)仍然做出一些简化的假设(我会到了以后):
(?<=\[!--@Else--\]) # Make sure that our match begins right after an else
# block.
[^\[]* # Match as many non-[ characters as possible (the actual
# statement)
(?= # This lookahead will assert that the previous statement
# was a top-level Else
(?<Depth>) # Push one capture onto the stack "Depth" (because, if
# this is one of the desired "Else"s we are exactly one
# level deep
(?> # Start a subpattern for anything that could follow and
# suppress backtracking (because the alternatives are
# mutually exclusive)
(?<Depth>\[!--@If\([^()]*\)--\])
# If we encounter an If block, push a new capture onto
# the stack (because the nesting level rises)
| # OR
(?<-Depth>)\[!--@EndIf--\]
# IF we can pop a capture from the stack, consume an
# EndIf. If we cannot, the named group will fail. Hence
# we can only consume one EndIf more than we already
# encountered Ifs.
| # OR
(?!\[!--@EndIf--\]). # If this character does not mark the beginning of an
# EndIf, consume an arbitrary character.
)* # Repeat as long as possible.
$ # Make sure we have reached the end of the string.
(?(Depth)(?!)) # If there is anything left on the stack, fail, too,
# because there are some Ifs that were not closed, so
# the syntax was invalid anyway.
# You can leave this out if you have convinced yourself
# beforehand that the overall nesting syntax is correct.
) # End of lookahead.
现在这已经是一头野兽,如果没有这篇评论小说,几乎没有人会理解。
但我提到简化假设。你走了。
If
条件下使用任何类型的括号。如果你想这样做,你也必须检查他们的正确的嵌套。它比我在这里做的稍微简单一些,但它仍然需要在一堆括号中构建和放下。[\[]]*
。由于我不允许使用任何类型的左括号,因此Else
块内不能包含条件语句。现在,如果您想允许这样做,您必须将几乎所有内容复制到实际匹配中,以便了解哪些If
和EndIf
在内Else
以及之后发生的事情。您可以看到,要获得覆盖100%所有案例的正则表达式解决方案,您需要使该代码完全无法维护。这就是你应该考虑的原因,手动分析字符串并构建某种语法树。通过这种方式,您可以获得嵌套结构的OOP表示,可以轻松遍历您想要查找的特定Else
。