按模式将文本脚本划分为子字符串
-
30-09-2019 - |
题
考虑以下脚本(伪语言中的胡说八道):
if (Request.hostMatch("asfasfasf.com") && someString.existsIn(new String[] {"brr", "hrr"})) {
if (Requqest.clientIp("10.0.x.x")) {
somevar = "1";
}
somevar = "2";
}
else {
somevar = "first";
}
string foo = "foo";
// etc. etc.
您如何从中获取块的参数和内容? if-block的格式:
if<whitespace>(<parameters>)<whitespace>{<contents>}<anything>
我尝试使用 String.split()
带有正则方式 ^if\s*\(|\)\s*\{|\}\s*
但这惨败。即,问题是 ) {
也可以在内部IF和关闭中找到 }
也从许多地方找到。我认为这里既不懒惰或渴望扩张。
所以...为了用Regex实施它,我可能需要什么指针?
我还需要在没有if-block代码的情况下获取剩余的字符串(因此,代码从 else { ...
)。使用 String.split()
似乎很难,因为没有关于被解析的零件长度的信息。
我最初创建了一个基于循环的解决方案(使用 String.substring()
为此),但很乏味。我想拥有更奇特的东西。我是否应该使用Regex或创建一个自定义的通用功能(除此之外还有很多其他情况),以采用可简化的字符串和模式(考虑考虑 if<whitespace>(...
上面的模式)?
编辑: :更改为变量分配的返回,因为否则就没有意义。
解决方案
普通语言无法正常工作,因为 常规语法 无法匹配“任何数量的开放括号,然后是任何数量的近亲括号”。一种 无上下文的语法 为此需要。
除非您使用 Java的无上下文语法解析器 或正则表达式扩展 使正则表达式不再正常, ,您的基于循环的解决方案可能是最奇特的解决方案。
其他提示
与尝试使用Regex进行此操作相比,使用(或编写)解析器要好得多。
Regex非常适合某种内容,但是对于这样的复杂解析,它很糟糕。它很烂的另一个示例是在这里被问到很多的是解析HTML-您可以在有限的程度上进行,但是对于任何复杂的事物,DOM解析器是一个更好的解决方案。
对于[非常]简单的解析器,您需要的是递归功能,可以搜索牙套 {
和 }
, ,每次遇到一个开放式支架时,都会恢复一个水平,并在找到闭合支架时返回一个水平。然后,它需要在每个级别的两个括号之间存储字符串内容。
根据上述内容,您需要一个解析器。一种易于实现的类型(写有趣!)是 递归后裔解析器与回溯. 。尽管大多数都有学习曲线,但那里还有大量的解析器发电机。一个适合Java的解析器发电机是 Javacc.