yaml文件只解析第一层,解析为Map<String,String>,并且支持反解析,工具类

yaml文件只解析第一层,解析为Map<String,String>,并且支持反解析,工具类

这几天公司有个特殊的需求,需要进行yml解析成map,支持页面上的修改,然后在保存为yml文件和key value,存到两张表中,网上没找到合适的工具类,于是自己写了一个,下面是代码分享,支持所有的yml格式,但是由于要做互转,所以注释会被去掉

package com.bilibili.bmr.cluster.config.utils;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.util.StrUtil;
import jodd.util.StringUtil;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class YmlUtils {

    public static String mapToYaml(Map<String, String> map) {
        StringBuilder str = new StringBuilder();
        Set<String> keySet = map.keySet();
        for (String key : keySet) {
            String value = map.get(key);
            if(value.contains(":") || value.contains("-")){
                str.append(key).append(":").append("
  ");
                value = value.replaceAll("
","
  ");
                str.append(value).append("
");
            }else if(value.startsWith("|
")){
                str.append(key).append(": ");
                value = value.replaceAll("
","
  ");
                str.append(value).append("
");
            } else {
                str.append(key).append(": ").append(value).append("
");
            }
        }
        return str.toString();
    }


    public static Map<String, String> yamlToMap(String yamlString) {
        Map<String, String> resultMap = new LinkedHashMap<>();

        String[] lines = yamlString.split("
");
        String currentKey = null;
        StringBuilder currentValue = new StringBuilder();
        for (String line : lines) {
            line = StringUtil.trimRight(line);
            if(StrUtil.isBlank(line)){
                continue;
            }
            if(line.trim().startsWith("#")){
                continue;
            }
            Pattern pattern = Pattern.compile("^\w+:\s\w+.*", Pattern.DOTALL);
            Pattern pattern02 = Pattern.compile("^\w+:$", Pattern.DOTALL);
            Pattern pattern03 = Pattern.compile("^\w+:\s\|$", Pattern.DOTALL);
            Matcher matcher = pattern.matcher(line);
            Matcher matcher02 = pattern02.matcher(line);
            Matcher matcher03 = pattern03.matcher(line);
            //说明是key-value 形式
            if (matcher.find()) {
                String keyValues = matcher.group(0);
                String[] split = keyValues.split(":");
                if(split.length == 2) {
                    resultMap.put(split[0].trim(), split[1].trim());
                }
                //碰到一个key 之后重置 key value
                currentKey = null;
                currentValue = new StringBuilder();
                continue;
            }
            //说明是 key 形式
            if(matcher02.find()) {
                currentKey = matcher02.group(0).replace(":","").trim();
                //重置value
                currentValue = new StringBuilder();
                continue;
            }
            //说明是 key加value  形式
            if(matcher03.find()) {
                currentKey = matcher03.group(0).split(":")[0];
                //重置value
                currentValue = new StringBuilder();
                currentValue.append("|
");
                continue;
            }
            //说明是value形式
            if(currentKey != null){
                if(line.startsWith("  ")){
                    line = line.substring(2);
                }else if(line.startsWith("	")){
                    line = line.substring(1);
                }
                currentValue.append(line).append("
");
                resultMap.put(currentKey,currentValue.toString());
                continue;
            }

        }
        return resultMap;
    }

    public static void main(String[] args) {
		//这里写你的测试文件路径
        FileReader fileReader = new FileReader("src/main/resources/test.yml");
        String result = fileReader.readString();
        Map<String, String> resultMap = yamlToMap(result);

//        // 输出结果
//        for (Map.Entry<String, String> entry : resultMap.entrySet()) {
//            System.out.println("Key: " + entry.getKey());
//            System.out.println("Value: 
" + entry.getValue() + "
");
//        }
        String resultStr = mapToYaml(resultMap);
        System.out.println("----------");
        //反解析回来的结果
        System.out.println(resultStr);
    }

}