首页 > 解决方案 > 用给定的对象或默认值替换标记化的字符串

问题描述

作为 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 "";
    }

上面的程序确实给出了所需的输出,但是我发现它:

寻找更好的解决方案/指导。谢谢!

标签: javastringparsingsplit

解决方案


尝试这样的事情:

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


推荐阅读