这几天公司有个特殊的需求,需要进行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("\n ");
value = value.replaceAll("\n","\n ");
str.append(value).append("\n");
}else if(value.startsWith("|\n")){
str.append(key).append(": ");
value = value.replaceAll("\n","\n ");
str.append(value).append("\n");
} else {
str.append(key).append(": ").append(value).append("\n");
}
}
return str.toString();
}
public static Map<String, String> yamlToMap(String yamlString) {
Map<String, String> resultMap = new LinkedHashMap<>();
String[] lines = yamlString.split("\n");
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("|\n");
continue;
}
//说明是value形式
if(currentKey != null){
if(line.startsWith(" ")){
line = line.substring(2);
}else if(line.startsWith("\t")){
line = line.substring(1);
}
currentValue.append(line).append("\n");
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: \n" + entry.getValue() + "\n");
// }
String resultStr = mapToYaml(resultMap);
System.out.println("----------");
//反解析回来的结果
System.out.println(resultStr);
}
}