[英]how to parse a file with keyword-value pairs and {} and line breaks in Java?
在一个文件中,我有一些变量存储如下:
author = {Some Author},
link = {some link},
text = { bla bla bla bla bla bla bla bla bla bla bla
bla bla bla bla bla bla bla bla bla bla bla bla bla},
...
一些变量在多行上。
之后我需要将每个String条目吐入键和值,但这不是问题。我到目前为止:
\\S+\\s*[=][{]\\s*\\S*[},]
对我来说工作正常的解决方案是:
(\w+)\s*=\s*\{(.*?)\}
和
\\S+\\s*[=]\\s*[{].*[},]
你的文章并不明显,但这看起来像一个bibtex文件。 如果是,则大括号可以在大括号内出现,这意味着您的语言不是“常规”,并且不能通过正则表达式(例如您提供的语言)来描述。
如果没有,那么你想要的东西
(\w+)\s*=\s*\{(.*?)\}
但编写解析器可能是解决问题最可敬的方法。 如果它是bibtex你正在解析,一个开源Java书目管理器(如Jabref)可能会给你一些关于构建更健壮的东西的想法。
我建议您不要使用正则表达式,因为看起来您的格式有点过于自由形式。 编写一个简单的解析器,首先读取一个字符串直到=
作为一个键然后读取括号的内部直到分隔逗号或文件结尾而不关心换行符对我来说,似乎是一种更简单的方法。 如果你需要它,你可以随时用空格替换换行符。 它还有一个好处,如果您的值可以包含大括号,适当地转义,使用实际解析器处理它们比使用正则表达式更简单。
这种格式看起来很简单,并且不太可能扩展,因为手写的解析器非常适合。 但是对于更复杂的语言,或者即使您只是想要练习,您也可以使用解析器生成器来构建解析器,这样可以获得更易于理解的语言定义。 我知道ANTLR是一种在Java中使用的流行的。
您可以使用String类的split方法。
public String[] split(String regex)
将此字符串拆分为给定正则表达式的匹配项。
您可以先用逗号分割输入,然后在{}之间用空格分隔文本( \\s
)。
你考虑过Java属性文件吗? http://en.wikipedia.org/wiki/.properties
你应该使用属性 ,正则表达式不是你的情况下的好解决方案。
使用不同的文件格式可能会让您感到头痛,但您可以解析它:
Pattern p = Pattern.compile("\\s*(\\w+)\\s*=\\s*\\{(.*?)\\},?\\s*", Pattern.DOTALL);
while (true) {
Matcher m = p.matcher(input);
if (!m.find()) break;
String key = m.group(1);
String val = m.group(2);
System.out.println("OK: key=" + key + ", val=" + val);
input = m.replaceFirst("");
}
只需将println
插入Map中即可。
我不确定你问的是什么,你的正则表达式在提供额外信息方面没什么帮助。
但是,如果括号无法嵌套而您不想处理转义括号,则正则表达式非常简单。
注意:即使你最近的正则表达式(可能应该刚刚编辑你的帖子而不是回应你自己: \\\\S+\\\\s*[=]\\\\s*[{].*[},]
正在做一些事情它没有不需要这样做肯定会让你感到困惑。过度使用[]风格的角色类可能让你感到困惑。你的最后一个[},]真的是说“字符匹配'}'或','”这就是我我很肯定不是你的意思。
正则表达式似乎是每个人最喜欢的鞭打男孩,但我认为这是合适的。
Pattern p = Pattern.compile( "\\s*([^={}]+)\\s*=\\s*{([^}]+)},?" );
Matcher m = p.matcher( someString );
while( m.find() ) {
System.out.println( "name:" + m.group(1) + " value:" + m.group(2) );
}
正则表达式分解为:
这个正则表达式应该比。*版本更有效地执行,因为它更容易找出停止的位置。 我也认为它更清楚,但我会说话正则表达式。 :)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.