java - 用给定的对象或默认值替换标记化的字符串
问题描述
作为 java 和正则表达式的新手,我正在努力寻找解决以下问题的方法。
Object obj = new Object();
String FLTNUM = obj.getFlightNumber(); //1234
String REGNUM = obj.getRegistration(); //REG111
<TOKEN RW=J>%FLTNUM</TOKEN>_320_Y_<TOKEN RW=N12345>%REGNUM</TOKEN>B6
(一个 xml(ish)字符串。)
在上面的字符串中,我有如下要求:如果 FLTNUM 存在于对象中,则将其替换为航班号,否则使用 xml 属性值默认值,即 J 同样,如果对象中存在 REGNUM,则替换为对象值,否则 xml 属性值默认值即 N12345
所以最终输出将类似于:J_320_Y_N12345B6 OR 1234_320_Y_REG111B6
凌乱的解决方案我可以想出***
public static void main(String[] args) throws Exception {
String s = "<TOKEN RW=J>%FLTNUM</TOKEN>_320_Y_<TOKEN RW=N12345>%REGNUM</TOKEN>B6"; // An xml (ish) string.
String[] split = StringUtils.splitByWholeSeparator(s, "</TOKEN>");
boolean withDefaultValue = true; // Not passing object, just having a flag to check if value is present or not
List<String> asList = Arrays.asList(split);
StringBuilder builder = new StringBuilder();
for(String reg: asList) {
if(StringUtils.contains(reg, "TOKEN")) {
String[] split1 = StringUtils.splitByWholeSeparator(reg, "<TOKEN RW=");
List<String> asList2 = Arrays.asList(split1);
for(String reqInt: asList2) {
if(StringUtils.contains(reqInt, ">")) {
String[] split2 = reqInt.split(">");
String defaultValue = split2[0];
String token = getTokenValue(split2[1]);
if(!withDefaultValue && StringUtils.isNotBlank(token)) {
builder.append(token);
} else {
builder.append(defaultValue);
}
} else {
builder.append(reqInt);
}
}
} else {
builder.append(reg);
}
}
System.out.println(s);
System.out.println(builder.toString());
}
private static String getTokenValue(String token) {
if(StringUtils.equalsIgnoreCase("%FLTNUM", token)) {
return "1234";
} else if(StringUtils.equalsIgnoreCase("%REGNUM", token)) {
return "REG12345";
}
return "";
}
上面的程序确实给出了所需的输出,但是我发现它:
- 维护和单元测试太麻烦了
- 科技债务似乎有点高
- 不够通用,无法处理所有用例。
寻找更好的解决方案/指导。谢谢!
解决方案
尝试这样的事情:
public static void main(String[] args) throws IOException{
String s = "<TOKEN RW=J>%FLTNUM</TOKEN>_320_Y_<TOKEN RW=N12345>%REGNUM</TOKEN>B6";
System.out.println(process(s));
s = "<TOKEN RW=J>1234</TOKEN>_320_Y_<TOKEN RW=N12345>REG111</TOKEN>B6";
System.out.println(process(s));
}
public static String process(String s) {
Pattern p = Pattern.compile("(<TOKEN RW=)(.*?)(>)(.*?)(</TOKEN>)(.*?)(<TOKEN RW=)(.*?)(>)(.*?)(</TOKEN>)(.*)");
Matcher m = p.matcher(s);
String output = "";
if(m.find()) {
output += m.group(4).contains("FLTNUM") ? "J" : m.group(4);
output += m.group(6);
output += m.group(10).contains("REGNUM") ? "N12345" : m.group(10);
output += m.group(12);
}
return output;
}
输出:
J_320_Y_N12345B6
1234_320_Y_REG111B6
根据您的需要更改模式。参考https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html
推荐阅读
- c++ - 添加函数以使用重命名文件后,程序将不再找到文本字符串
- python - 如何在 Python 中进行一次热编码并以编程方式获取类的数量?对于人工神经网络
- android - android Firebase 查询 - 对 (pushid) 的引用?
- reactjs - 当我从 LAN 上的另一台 PC 浏览时,我的 ReactJS/Django(Rest API) 提示 Unhandled Promise 拒绝
- javascript - jQuery模式弹出后如何从JavaScript触发表单提交
- flutter - 如何更新另一个自定义 Flutter 小部件中存在的图像路径?
- vba - 检查工作簿或工作表范围中是否存在命名范围
- c++ - 如何实现 Dijkstra 算法以在 C 中的无向图中找到从 1 个节点到所有其他节点的最短路径并打印距离
- python - Flask API:更新数据库 ID
- javascript - Angular 9:检测空表单的输入键