【问题标题】:Split string into columns based on distance between values根据值之间的距离将字符串拆分为列
【发布时间】:2014-05-22 21:32:49
【问题描述】:

我正在处理从 PDF 导出的非结构化文本数据。原始数据来自转换为文本格式的 PDF 中的表格,因此剩下的就是它的一般结构。我正在查看的特定部分曾经是一个表格。

例如,这里有一些示例输入

  A        B     C     D         E
 1        2                     3
 4              6     7    

第一行表示标题,后面几行是值。

幸运的是,保留了间距(有点):每列之间总是至少有两个空格。但是,实际的空格数会有所不同,具体取决于解析器根据表的结构决定如何处理它。

我想将这些行解析为以下数组。我将首先解析标题以获取列,然后在解析其余行时将其用作我需要的模板。

{"A", "B", "C", "D", "E"}
{"1", "2",  "",  "", "3"}
{"4",  "", "6", "7",  ""}

仅给出这些信息,是否可以准确地做到这一点?

【问题讨论】:

  • 要获取标题,您可以使用split("\\s+")。但是你怎么知道第二行是{"1", "2", "", "", "3"} 而不是{"1", "", "2", "", "3"}
  • 是的。但你需要展示你的努力才能在这里得到更多的东西..
  • @GirlyGirl 基于空格数和(大部分)原始数据。

标签: java pdf split string-parsing


【解决方案1】:

我猜你可以得到字符串中标题(A,B,...)的索引,并将其与每行中值的索引进行比较以获得最接近的...我快速尝试并得到这个结果:

public static void main(String[] args) {
    String headerColumn = "  A        B     C     D         E";
    String firstLine = " 1        2                     3";
    String secondLine = " 4              6     7    ";

    Map<Integer, String> indexHeaderMap = new HashMap<Integer, String>();
    // Get header indexes
    for (int i = 0; i < headerColumn.length(); i++) {
        String currChar = String.valueOf(headerColumn.charAt(i));
        if (!currChar.equals(" ")) {
            indexHeaderMap.put(i, currChar);
        }
    }

    // Parse first line
    parseLine(firstLine, indexHeaderMap);
    // Parse second line
    parseLine(secondLine, indexHeaderMap);
}

以及功能:

private static void parseLine(String pLine, Map<Integer, String> pHeaderMap) {
    for (int i = 0; i < pLine.length(); i++) {
        String currChar = String.valueOf(pLine.charAt(i));
        if (!currChar.equals(" ")) {
            int valueColumnIndex = getNearestColumnIndex(i, pHeaderMap);
            System.out.println("Value " + currChar + " is on column " + pHeaderMap.get(valueColumnIndex));
        }
    }
}

private static int getNearestColumnIndex(int pIndex,
        Map<Integer, String> pHeaderMap) {
    int minDiff = 500;
    int nearestColumnIndex = -1;
    for(Map.Entry<Integer, String> mapEntry : pHeaderMap.entrySet()) {
        int diff = Math.abs(mapEntry.getKey() - pIndex);
        if (diff < minDiff) {
            minDiff = diff;
            nearestColumnIndex = mapEntry.getKey();
        }
    }

    return nearestColumnIndex;
}

这是输出:

Value 1 is on column A
Value 2 is on column B
Value 3 is on column E
Value 4 is on column A
Value 6 is on column C
Value 7 is on column D

我希望这对获得您期望的结果有足够的帮助!

【讨论】:

    猜你喜欢
    • 2018-10-24
    • 2018-10-06
    • 2022-11-15
    • 1970-01-01
    • 2021-03-06
    • 1970-01-01
    • 1970-01-01
    • 2021-06-14
    • 1970-01-01
    相关资源
    最近更新 更多