sed替换最后一个匹配_ppt占位符设置

sed替换最后一个匹配_ppt占位符设置json字符串处理


Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

需求说明

最近在公司项目中遇到一个需要,需要在用户输入的入参数据中,将数据里面${}占位符的数据替换为真实的数据方式,以下提供两种方式

使用Api

  • JsonUtils:自己封装的工具类,其中对Jackson的api进行封装,可以自行替换

方式一

https://blog.csdn.net/weixin_43915643/article/details/123231563

缺点:
  • 正则表达式匹配,转换后会出现多余的引号,导致替换后的数据在转换为json格式就会出现转换不了的问题
  • 正则表达式过于复杂,后期修改就不好维护

方式二

方式二的好处在于使用了 Map的方式处理了json格式的数据,也不会出现多余的双引号的问题。缺点就是可能会出来无限深度的递归

public static String processMap(Map<String, Object> model, Object data) throws InvocationTargetException,
                                                                                   IllegalAccessException,
                                                                                   NoSuchMethodException { 
   
        //获取到所有map的key value
        Map<String, Object> valueMap = new HashMap<>(model);
        for (Map.Entry<String, Object> next : model.entrySet()) { 
   
            String modelKey = next.getKey();
            //获取到value的数据
            Object modelValue = next.getValue();
            String modelValueStr = JsonUtils.toJson(modelValue);
            boolean isJson = JsonUtils.isJson(modelValueStr);
            //处理占位符,判断是否时标准的json结构
            if (!isJson) { 
   
                //截取出占位符的key
                String process = doProcess(modelValueStr, data);
                valueMap.put(modelKey, process);
            } else { 
   
                Object parse = JsonUtils.parse(modelValueStr, Object.class);
                if (parse instanceof Map) { 
   
                //将数据为Map的进行递归处理
                    String processMap = processMap(JsonUtils.toMap(modelValueStr, String.class, Object.class), data);
                    valueMap.put(modelKey, JsonUtils.toMap(processMap, String.class, Object.class));
                }
            }
        }
        return JsonUtils.toJson(valueMap);
    }

	/** * 进行字符串的处理 */
private static String doProcess(String str, Object data) throws IllegalAccessException,
                                                                         InvocationTargetException,
                                                                         NoSuchMethodException { 
   
        Matcher matcher = PLACEHOLDER_PATTERN.matcher(str);
        StringBuffer values = new StringBuffer();
        while (matcher.find()) { 
   
            String key = matcher.group(1);
            Object value = PropertyUtils.getProperty(data, key);
            Assertions.notNull(value, String.format("占位符未匹配到数据:%s", key));
            //解决:Illegal group reference 对字符串value进行 encode 防止value中有 $ 符号导致的替换异常
            matcher.appendReplacement(values, JsonUtils.toJson(value).replaceAll("\\$", "RDS_CHAR_DOLLAR"));
        }
        matcher.appendTail(values);
        return values.toString();
    }

注意

这里在使用jackson过程中遇到过一个坑,就是使用jackson api,用toJson() 方法转换下面这种格式的数据:

"{\"name\": \"zhangfei\"}___xxxx"

“{“test”:“name”}___xxxxx” 使用Jackson时会将 ___xxxxx字符截取掉(Jackson默认会使用 } 结尾作为结尾的符号,然后丢弃掉后面的数据),就会导致这个字符串也是一个合法的json,包括后续使用parse() 进行转换

解决方案
public static boolean isJson(@NotNull ObjectMapper mapper, String jsonInString) { 
   
       if (StringUtils.isEmpty(jsonInString)) { 
   
           return false;
       }
       try { 
   
       	//jackson在读取到不是标准的json时会抛出错误,则不是json格式
           JsonNode jsonNode = mapper.readTree(jsonInString);
           //在读取json完之后,判断读取完的字符串是否跟原来字符串相同,如果不相同就判断为false
           String jStr = jsonNode.toString();
           // trimAllWhitespace() 去掉所有的空格符号
           return StringUtils.trimAllWhitespace(jStr).equals(StringUtils.trimAllWhitespace(jsonInString));
       } catch (IOException e) { 
   
           return false;
       }
   }


public static String toJson(ObjectMapper mapper, Object object, boolean pretty) { 
   
       if (object == null) { 
   
           return StringPool.EMPTY_JSON;
       }
       // 如果是 string, 先转为 object 再转为 json, 避免转义字符
       if (object instanceof String) { 
   
           String str = StringUtils.trimWhitespace((String) object);
           //在执行toJson的时候会先判断是否是标准的json格式,如果不是就按照字符串的方式返回
           if (isJson(mapper, str)) { 
   
               object = parse(str, Object.class);
           } else { 
   
               // 非 json 字符串, 直接返回原始字符串
               return str;
           }
       }

       try { 
   
           String json;
           if (pretty) { 
   
               json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
           } else { 
   
               json = mapper.writeValueAsString(object);
           }
           return json;
       } catch (JsonProcessingException e) { 
   
           throw Exceptions.unchecked(e);
       }
   }
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/196097.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • linux之lvm分区扩容[通俗易懂]

    linux之lvm分区扩容[通俗易懂]以下步骤的前提为磁盘lvm分区1、加入新硬盘2、分区PV(physicalvolume)即物理卷,就是物理磁盘,可以通过fdisk-l查看操作系统有几块硬盘VG(volumegroup)即卷组,就是一组物理磁盘的组合,里面可以有一块硬盘也可以有多块硬盘LV(logicalvolume)及逻辑卷,就是在VG(指定的物理磁盘组)里面划分出来的可以说成是PV就是硬盘…

    2022年6月20日
  • Linux 查看环境变量_Linux怎么设置环境变量

    Linux 查看环境变量_Linux怎么设置环境变量各位客官好啊,最近新冠病毒疫情比较严重,还望各位出门时多多防范,一定要带口罩!!!接下来,讲一讲环境变量的相关知识点,既然提到了环境变量,那么我当前的环境里有多少默认的环境变量呢?关于这个问题,我教你两个命令就可以了,并且这两个命令一个比一个牛?先说一说【env】一、用env命令来查看环境变量上图就是我的系统输出的结果,简单给大家介绍几个重点的变量1)HOME:代表用户的家目录,通过cd…

    2022年9月1日
  • IT界最伟大的十位人物「建议收藏」

    IT界最伟大的十位人物「建议收藏」美国《电脑周刊》最近评出了“IT界最伟大十位人物”,苹果公司创办人史蒂夫·乔布斯(SteveJobs)凭借着创新精神和在苹果的二次创业排名榜首。    世界首富的微软董事会主席比尔·盖茨仅排名第三位,不敌万维网(Web)发明人蒂姆·伯纳斯·李。巧合的是,三甲排名人物都是在同一年出生。    上榜的十位人物大多世界闻名,而且富可敌国。例如,盖茨已经

    2022年10月9日
  • ip2long之后有什么好处?

    ip2long之后有什么好处?

    2021年10月18日
  • 滑动窗口 leetcode_滑动窗口leetcode

    滑动窗口 leetcode_滑动窗口leetcode原题链接给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。返回滑动窗口中的最大值。示例 1:输入:nums = [1,3,-1,-3,5,3,6,7], k = 3输出:[3,3,5,5,6,7]解释:滑动窗口的位置 最大值————— —–[1 3 -1] -3 5 3 6 7

    2022年8月8日
  • origin如何绘制双y轴柱状图_Graphpad柱状图双Y轴

    origin如何绘制双y轴柱状图_Graphpad柱状图双Y轴origin横坐标的标注如何修改成双行显示呢?shift+enter,可以换行思路:在两个图层上分别绘制两个柱状图,然后将两个图层合并。第一步:建立一个X列,四个Y列。其中,两列数据中间加上两个空列第二步:绘制第一个柱状图第三步:绘制第二个柱状图第四步:两图层合并点击合并按钮第五步:接下来就是坐标轴的显示基本上就完成了…

    2022年9月30日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号