首页 > 解决方案 > 如何将文件字符串格式化为点路径

问题描述

我想进行配置以存储项目,但是,当我创建获取值的路径时,发生了错误。

HashMap<String, Text> sections;

private void loadKeys() {
    List<String> list = new ArrayList<>();
    for (String s : sections.keySet()) {
        Text te = sections.get(s);
        String changeable = s.substring(0, s.length() - 1);
        for (int i = 0; i < te.lines(); i++) {
            String line = te.getLine(i);
            while (line.startsWith("  ")) {
                line = line.substring(2);
            }
            if (!line.startsWith("-")) {
                if (line.endsWith(":")) {
                    changeable = changeable + "." + line.substring(0, line.length() - 1);
                } else {
                    list.add(changeable + "." + line);
                }
            }
        }
    }
    for (String s : list) {
        System.out.println(s);
    }
}

文本.java

public class Text {
private List<String> lines = new ArrayList<>();

public Text(String txt) {
    if (txt.contains("\n")) {
        for (String s : txt.split("\n")) {
            lines.add(s);
        }
    } else {
        lines.add(txt);
    }
}

public int lines() {
    return lines.size();
}

public String getLine(int line) {
    return lines.get(line);
}

@Override
public String toString() {
    String string = "";
    for (String s : lines) {
        if (string.equals("")) {
            string = s;
        } else {
            string = string + "\n" + s;
        }
    }
    return string;
}
}

文件:

Test11:
  Test12:
    Test13: 'test'
    Test14: 'test2'
  Test15: teste
  Test16:
    Test17: "test test"

我想要的输出:

我用上面的代码得到了什么:

Test12 正在重复。你能帮我得到我想要的吗?提前致谢

标签: java

解决方案


这很容易。您只需要保留当前关卡深度关卡名称即可。您可以通过递归或使用queue来实现。

public static Map<String, String> readProperties(Path path) throws IOException {
    final class Level {

        private final String name;
        private final int offs;

        public Level(String name, int offs) {
            this.name = name;
            this.offs = offs;
        }
    }

    Map<String, String> map = new LinkedHashMap<>();
    // contains all root items for current one with it's offset, to detecl that current level is sub level or parent
    Deque<Level> levels = new LinkedList<>();
    Pattern pattern = Pattern.compile("(?<offs>\\s*)(?<key>[^:]+)\\s*:\\s*(?<value>.*)\\s*");

    Files.lines(path)
         .map(pattern::matcher)
         .filter(Matcher::matches)
         .forEach(matcher -> {
             int offs = matcher.group("offs").length();

             // remove parent levels until reach the parent of current level
             while (!levels.isEmpty() && levels.peekLast().offs >= offs) {
                 levels.removeLast();
             }

             String key = matcher.group("key");
             String value = matcher.group("value");

             if (value.isEmpty())
                 levels.add(new Level(key, offs));
             else
                 map.put(levels.stream().map(level -> level.name).collect(Collectors.joining(".")) + '.' + key, value);
         });

    return map;
}

推荐阅读