2010-01-11 35 views
2

在一个文件中我存储一些像这样的变量:如何使用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}, 
... 

有些变量是在多。

之后,我需要吐每个字符串进入关键和价值,但那不是一个problem.I'm至今:

\\S+\\s*[=][{]\\s*\\S*[},] 

的解决方案,这是对我工作的罚款是:

(\w+)\s*=\s*\{(.*?)\} 

\\S+\\s*[=]\\s*[{].*[},] 
+0

那么问题是什么?如何处理多线? – Dmitry 2010-01-11 23:51:40

+1

我想现在是时候问问自己你在做什么了。看起来好像你问这样做是为了为你的正则表达式创建一个解析器,而不是用正确的方式来使用正确的解析器生成器。 – 2010-01-11 23:52:22

+0

请发送编码?闻起来像功课。 – 2010-01-12 02:23:34

回答

5

从您的帖子中不明显,但这看起来像一个bibtex文件。如果是大括号,则大括号内可能会出现括号,这意味着您的语言不是“常规”的,并且不能用您提供的正则表达式来描述。

如果没有,那么你想要的东西像

(\w+)\s*=\s*\{(.*?)\} 

但是写一个解析器可能是解决你的问题最值得尊敬的方式。如果你正在解析,一个开源的Java书目管理器(如Jabref)可能会给你一些建设更强大的想法。

+1

+1关于嵌套花括号的注释 – Thilo 2010-01-12 01:28:21

+0

是的,它是bibtex文件,但它只是转换一个文件,其中没有大括号内的文件。感谢您的解释 – aphex 2010-01-12 19:31:51

4

我会建议你不要使用regexes这个,因为它看起来你的格式有点过于自由。对于我来说,编写一个简单的解析器,首先将字符串读取到=作为关键字,然后将大括号内的内容读取到分隔逗号或文件结束而不关注换行符,对我而言似乎是一种更简单的方法。如果你需要它,你可以用空格替换换行符。它还有一个好处,如果你的值可以包含花括号,适当地逃脱,用真正的解析器处理它们比用正则表达式更简单。

这种格式看起来很简单,不太可能被延伸到手写解析器非常适合的地方。但是对于更复杂的语言,或者即使您只是想要练习,也可以使用解析器生成器来构建解析器,这具有更易于理解的语言定义。据我所知,ANTLR是一种在Java中使用的流行语言。

+0

是的,我想用正则表达式。 – aphex 2010-01-11 23:57:08

0

你应该使用Properties,正则表达式不是你的情况的好解决方案。

+0

他可能必须使用他给出的文件格式。属性文件处理换行符的方式不同。 – Thilo 2010-01-12 01:27:04

1

您可以使用String类的split方法。

public String[] split(String regex)

拆分这串绕定正则表达式的匹配。

你可以先以逗号分割的输入,然后平分文本{}用空格(\s)。

0

使用不同的文件格式可能会节省你有些头疼,但你可以分析它想:

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与插入到你的地图。

0

我不确定你在问什么,你的正则表达式在提供额外信息方面没有多大帮助。

但是,如果括号不能嵌套,你不想处理转义的括号,那么正则表达式非常简单。

请注意:即使您最近使用的正则表达式(可能应该只是编辑了您的帖子,而不是回应自己:\\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)); 
} 

正则表达式分解为:

  • 任何前面的空格。
  • 第一个捕获组是一个非零长度的字符串,只包含不是'=','{'或'}'的字符
  • 任何中间空格。
  • '='
  • 任何中间空格。
  • '{'
  • 第二捕获基团是仅含有不属于闭合字符的非零长度字符串 '}'
  • '}'
  • 可选 ''

这正则表达式应该比。*版更有效率,因为它更容易找出停止的地方。我也认为它更清晰,但我会说话的正则表达式。 :)

相关问题