正则表达式-零宽断言实践

前端之家收集整理的这篇文章主要介绍了正则表达式-零宽断言实践前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

业务背景

处理JSON字符串KEY值中的特殊字符,VALUE中的字符不受影响。
如下所示,替换KEY中的_DOT_为点._SUB__

@H_301_17@"L_DOT_BUILD_SUB_DATE": @H_301_17@"DOT_SUB"

处理字符串替换一般都是用String的replace系列方法。在这里用replaceAll(),这个方法可以使用正则表达式。

基本概念

维基百科
正则表达式,又称正规表示式、正規表示法、正規運算式、規則運算式、常規表示法(英语:Regular Expression,在代码中常简写为regex、regexp或RE),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器裡,正則表达式通常被用来检索、替换那些符合某个模式的文本。

解决方

一般的是正则是不行的,可能是功底不够。求助大神之后,要用零宽断言(这名字很拗口,不知道谁起的),详细的概念可以谷歌。简单的说零宽断言表示匹配字符的时候再添加一些定位条件,使匹配更精准。我这里贴出一些关键的用法

喜欢正则的同学可以参考正则表达式简明参考,可以用正则表达式测试器玩玩。

详细过程

需要说明的是零宽断言不支持换行,这个实际测试过,所以在用之前需要把JSON字符串格式化,这里推荐工具Gson,详细代码如下。

public static String JSONFormatter(String uglyJSONString) {
        Gson gson3 = new GsonBuilder()@H_301_17@.setPrettyPrinting()@H_301_17@.create()@H_301_17@;
        @H_301_17@com@H_301_17@.google@H_301_17@.gson@H_301_17@.JsonParser jp = new @H_301_17@com@H_301_17@.google@H_301_17@.gson@H_301_17@.JsonParser()@H_301_17@;
        JsonElement je = jp@H_301_17@.parse(uglyJSONString)@H_301_17@;
        String prettyJsonStr2 = gson3@H_301_17@.toJson(je)@H_301_17@;
        return prettyJsonStr2@H_301_17@;
    }

直接贴出解决代码

@H_301_17@public static @H_301_17@String parseDotSub(@H_301_17@String jsonStr) {
        @H_301_17@//格式化JSON,使JSON中的键值对换行
        jsonStr @H_301_17@= JSONFormatter(jsonStr);
        @H_301_17@//解析键值对,不替换值中的字符,只替换冒号之前KEY中的字符
        @H_301_17@String regexDot @H_301_17@= @H_301_17@"_DOT_(?=.*:)";
        @H_301_17@String regexSub @H_301_17@= @H_301_17@"_SUB_(?=.*:)";
        jsonStr @H_301_17@= jsonStr@H_301_17@.replaceAll(regexDot,CONSTANT_DOT);
        jsonStr @H_301_17@= jsonStr@H_301_17@.replaceAll(regexSub,CONSTANT_SUB);
        @H_301_17@return jsonStr;
    }

测试

扩展

问题

利用零宽断言还解决了另外一个问题。字母和数字之间的减号,数字中间的点(不包括字母和数字之间的点)都替换为冒号。

@H_301_17@public static @H_301_17@String parseToColon(@H_301_17@String jsonStr) {
        @H_301_17@//以数字结尾的前面带-的字符
        @H_301_17@String regexSub @H_301_17@= @H_301_17@"-(?=\\d+)";
        jsonStr @H_301_17@= jsonStr@H_301_17@.replaceAll(regexSub,CONSTANT_COLON);
        @H_301_17@//以数字开始后面带点的字符
        @H_301_17@String regexDot @H_301_17@= @H_301_17@"(?<=\\d+)\\.";
        jsonStr @H_301_17@= jsonStr@H_301_17@.replaceAll(regexDot,CONSTANT_COLON);
        @H_301_17@return jsonStr;
    }

测试

第一次接触到零宽断言,正则是太强大了,可以灵活的解决问题,这里做个笔记留着以后查看。

猜你在找的正则表达式相关文章