• java 正则表达式解析数据


    1 背景

    在写代码过程中,会遇到一些解析需求,需要把字符串里面的某些东西提取出来。和作者信息,生日,地址,年龄之类的。虽然用java 自带String.split()方法能够处理大部分需求了,但显得比较笨拙,因为需要去遍历数组。

    2 实战

    String dataId = “hello world my name is: DayDayUp. and my birthday is 8.9. unmappedReason,version”;

    对于上面这个字符串,现在需要我们把DayDayUp获取出来。则需要先写提取的表达式,
    String REGEX = “name is:(.*?)\. and”;
    整体逻辑如下:

    
        @Test
        public void spliteAppNameTest2() {
            String dataId = "hello world my name is: DayDayUp. and my birthday is 8.9. unmappedReason,version";
            String REGEX = "name is:(.*?)\\. and";
    
            System.out.println(getPatternCode(dataId,REGEX));
        }
    
        public static String getPatternCode(String dataId, String rgex) {
            if (StringUtils.isEmpty(dataId)) {
                return null;
            }
    
            // 匹配的模式
            Pattern pattern = Pattern.compile(rgex);
            Matcher m = pattern.matcher(dataId);
            while (m.find()) {
                return m.group(1);
            }
            return null;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    输出: DayDayUp
    getPatternCode()封装了具体的逻辑。如果找到,即满足正则表达式规则,则返回第一个分分组。
    ps: 需要用(.?)来提取-补获组,.?表示非贪婪式匹配。.*表示贪婪式匹配。

    3 思考

    获取生日如何写呢?

     @Test
        public void spliteAppNameTest2() {
            String dataId = "hello world my name is: DayDayUp. and my birthday is 8.9. unmappedReason,version";
            String REGEX = "birthday is (.*?)\\. unmappedReason";
    
            System.out.println(getPatternCode(dataId,REGEX));
        }
    
        public static String getPatternCode(String dataId, String rgex) {
            if (StringUtils.isEmpty(dataId)) {
                return null;
            }
    
            // 匹配的模式
            Pattern pattern = Pattern.compile(rgex);
            Matcher m = pattern.matcher(dataId);
            while (m.find()) {
                return m.group(1);
            }
            return null;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    输出:8.9

    4 进阶

    思考:如何捕获多条数据呢?
    这个场景在爬虫场景比较多,如提取列表页中图片url地址或者图片名字时候。下面是一个简化例子,大家可以自己改造一下,就能在很多场景中使用了。
    目标: 把字符串中2个生日日期提取出来,即8.9 和1.1

     @Test
        public void spliteAppNameTest2() {
            String dataId =  "hello world my name is: DayDayUp. and Zhang's birthday is 8-9. besides, Yang's birthday is 1-1. besides";
            String REGEX = "birthday is (.*)\\.";
    
            System.out.println(getPatternCode(dataId,REGEX));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    输出:

    8-9. besides, Yang's birthday is 1-1
    
    • 1

    这里使用(.*)贪婪匹配,直接匹配了全部字符串。所以输出比较长。

      @Test
        public void spliteAppNameTest2() {
            String dataId = "hello world my name is: DayDayUp. and Zhang's birthday is 8-9. besides, Yang's birthday is 1-1. besides";
            String REGEX = "birthday is (.*?)\\.";
    
            System.out.println(getPatternCode(dataId,REGEX));
        }
    
        public static StrBuilder getPatternCode(String dataId, String rgex) {
            if (StringUtils.isEmpty(dataId)) {
                return null;
            }
            if (StringUtils.isEmpty(rgex)) {
                rgex = REGEX;
            }
            // 匹配的模式
            Pattern pattern = Pattern.compile(rgex);
            Matcher m = pattern.matcher(dataId);
            StrBuilder sb = new StrBuilder();
            while (m.find()) {
                sb.append(m.group(1)+"\n");
               // m.appendReplacement(sb,);
               // return m.group();
            }
            return sb;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    输出:

    8-9
    1-1
    
    • 1
    • 2

    改动点,
    1 使用了 StrBuilder sb = new StrBuilder(); 来保存补获组 sb.append(m.group(1)+“\n”);
    2 String REGEX = “birthday is (.*?)\.”;

    5 总结

    还是python写正则表达式要简单一点,java写起来代码量比较多,也比较复杂。特别是里面\,需要用2个\来表示一个\。刚开始还不能很好适应。

  • 相关阅读:
    一篇博客彻底掌握:粒子滤波 particle filter (PF) 的理论及实践(matlab版)
    【无标题】
    Python 正则表达式匹配特殊字符串
    5.zigbee的开发,串口putchar重定向(使用print),单播实验,usb抓包实验
    Centos8搭建npm和maven的nexus私服
    06_SpingBoot 下的 Spring MVC
    [代码已开源]集群聊天服务器与客户端开发
    Python函数
    Python(黄金时代)—— 让文字来说话
    Vue3 中的 v-bind 指令:你不知道的那些工作原理
  • 原文地址:https://blog.csdn.net/qq_39463175/article/details/127585568