Разделить строку на столбцы на основе расстояния между значениями
Я работаю с неструктурированными текстовыми данными, экспортированными из PDF. Исходные данные взяты из таблицы в формате PDF, которая была преобразована в текстовый формат, поэтому остается только общая структура. Отдельный раздел, на который я смотрю, раньше был таблицей.
Так, например, вот пример ввода
A B C D E
1 2 3
4 6 7
Первая строка указывает заголовки, а следующие строки - значения.
К счастью, интервал сохраняется (в некоторой степени): между каждым столбцом всегда будет как минимум два пробела. Однако фактическое количество пробелов будет варьироваться в зависимости от того, как синтаксический анализатор решил обработать его в зависимости от структуры таблицы.
Я хочу разобрать эти строки в следующих массивах. Сначала я бы проанализировал заголовок, чтобы получить столбцы, а затем использовал его в качестве шаблона, который мне нужен, при анализе остальных строк.
{"A", "B", "C", "D", "E"}
{"1", "2", "", "", "3"}
{"4", "", "6", "7", ""}
Можно ли это точно сделать, учитывая только эту информацию?
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
Я надеюсь, что это достаточно полезно, чтобы получить ожидаемый результат!