如何解析变量空格分隔的文本

时间:2013-12-20 22:58:28

标签: java regex parsing

我需要解析日志文件并将其转换为XML / Excel文件。日志文件具有以下格式的记录数据:

Key_ID    Property1  Property2 Property3
Row1      value1iiii           value3
Property4
value4
Key_ID    Property1  Property2 Property3
Row2         value1             value3
Property4
value4

目前我正在尝试用Java做这个,我需要XML转换进行比较,而Excel用于导出(我将使用Apache POI库)。问题是元素之间的可变间距,有时值可能是空白的。目前我正在阅读两行并将它们存储到一个字符串并尝试扫描,但这将错过空白值,从而解析相应属性的错误值。即使使用正则表达式,也会出现同样的问题。

感谢宝贵的建议。我保留的数据仅供参考,我的意思是列数不同,有时空白值可以存在。我已经浏览了近50个这样的日志文件,我可以找到的常见的事情就是打印日志文件,好像我们从数据库/ Excel表中复制和粘贴数据一样。我能想到的唯一解决方案是逐行分析字符。 对不起伙计们,我无法立即回复,我的宽带连接已关闭。再次感谢您节省时间。

2 个答案:

答案 0 :(得分:0)

如果中间有空白字段,则无法使用REGEX执行此操作。

但是,如果您的列具有固定宽度,那么我的建议是逐行读取文件。然后使用字符位置解析列。例如,1-9是Key_ID,10-20是Property1,依此类推。

答案 1 :(得分:0)

这是一种奇怪的格式。 但是,我会假设就是这样。 所以这就是我要做的。 代码不是Java正确的。 这更能说明这个想法。

while (hasNext()) { // using some reader Scanner can probably work
    String s = nextLine();
    if (s.startsWith("Key_ID")) {
        String s1 = nextLine();
        // requires some complex parsing
        // step 1 - split string into values
        String s11 = s1.split("[ ]+");
        String property1 = null;
        String property2 = null;
        String property3 = null;
        if (s11.length == 1) { // only key is present
        } else if (s11.length == 2) { // two properties have blank values
            // look in the next if block to see how that can expand to 2 blank values
        } else if (s11.length == 3) { // one property have blank values
            if (isBlank(10,20)) { // the text "Property1"
                property2 = s11[1];
                property3 = s11[2];
            } else if (isBlank(20,30) { // the text "Property2"
                property1 = s11[1];
                property3 = s11[2];
            } else {
                property1 = s11[1];
                property2 = s11[2];
            }
        } else {
            property1 = s11[1];
            property2 = s11[2];
            property3 = s11[3];
        }
        nextLine(); // skips the Property4
        String property4 = nextLine();
    }
}

boolean isBlank(String s, int start, int end) {
    // assumes that if there is a value it will be between the header text (e.g., Property1)
    boolean result = true;
    for (int i = start; i < end; i++) {
        result &= s.charAt(i).equals(' ');
    }
    return result;
}

注意:可能有一种方法可以进一步优化代码,但我不想进入它,因为代码已经非常难看了。我想要注意的是,因为格式是人类可读但不是计算机可读的,所以代码必须有点智能。