我正在解析纯文本并将其转换为键值对。 例如,纯文本:
some_uninteresting_thing
key1 valueA, some_uninteresting_thing valueB
key2 valueD
key3 some_uninteresting_thing valueE
key4 valueG(valueH, valueI)
key5 some_uninteresting_thing
可能的映射:
Map(
key1 ->(valueA, valueB,valueC),
key2 ->(valueD, valueE),
key3 ->(valueF)
key4 ->(valueH, valueI)
...
)
Amd结果将是:
key1 ->(valueA, valueB)
key2 ->(valueD)
key4 ->(valueH, valueI)
(key5不应该映射,因为没有适当的值。正如你所看到的那样,纯文本是宽松的。什么java库有助于处理这个?
答案 0 :(得分:3)
如果您熟悉正式语言,标记化/语法等,则可以使用像JavaCC这样的解析器生成器。 JavaCC获取您编写的语法文件,并生成将文本文件解析为一系列标记或sytax树的Java代码。有一些Maven和Ant插件可以帮助将这个额外的源集成到你的构建中。
对于仅限运行时的解决方案,有RunCC,我已经使用了很好的结果。 (我怀疑它没有JavaCC那么快,但对于我的情况,性能很好。)
还有Chaperon,它使用语法文件将纯文本转换为XML。
替代方法是使用正则表达式和StringTokenizer
的临时混合。
在解析器项目或正则表达式准备就绪的情况下,您的一般方法就是这样:
BufferedReader.readLine()
来读取文件的行,并StringTokenizer
将行拆分为空格和逗号的子串。< / LI>
您从解析器获得的字符串,您用作键的第一个字符串,以及后续字符串是您添加到Map的值。例如。在伪代码中
地图&GT; map = new HashMap&gt;(); 每行{ 列表标记= ...; //分割线的结果 String key = tokens.get(0); map.add(key,tokens.sublist(1,tokens.size()); }
即使解析器没有过滤不感兴趣的文本,它也会在稍后过滤。
使用上述项目构建解析器以解析地图文件格式。同样,您可以使用正则表达式和StringTokenizer构建一个简单的解析器。使用解析器构建地图。地图与上面的签名相同,即Map<String,List<String>>.
最后,根据允许值映射过滤输入映射。
像这样。
Map<String,List<String>> input = ...; // from step 1.
Map<String,List<String>> allowed = ...; // from step 3.
Map<String,List<String>> result = new HashMap<String<list<String>>(); // the final map
for (String key : input.keySet()) {
if (allowd.contains(key)) {
List<String> outputValues = new ArrayList();
List<String> allowedValues = allowed.get(key);
List<String> inputValues = input.get(key);
for (String value: inputValues) {
if (allowedValues.contains(value))
outputValues.add(value);
}
if (!outputValues.isEmpty())
output.put(key, outputValues);
}
}
// final result in filter
答案 1 :(得分:0)
您可以使用口译员和构建器。
解释器解析源并识别传递给构建器的键和值,构建所需的任何数据结构。