乐趣区

关于java:刘亦菲生日当天引发了我对正则的思考

前两天从网上采集到一条短视频数据(刷短视频),发现六公主连排 5 部刘亦菲主演的电影!甚是震惊,太有牌面了,看了一下日子是 8 月 25 号,嗷,原来当天是刘亦菲的生日。巧了,正好也是我家柴犬旺财的 3 岁生日😀。
<!– more –>

言归正传,咱们看到这条数据的

题目:# 刘亦菲 35 岁生日获央视独宠# 神仙姐姐生日快乐!

为了剖析数据,咱们须要获取数据中所提到的话题# 刘亦菲 35 岁生日获央视独宠 #。发问:你能想到几种实现形式呢?欢送评论区留言。

正则

想必仔细看题目的敌人肯定会猜到本文的主人公——正则,这玩意长处是写起来快,但毛病也不言而喻,性能差,跟批处理一个德性,反人类的难记,长时间不必,每次都要重新学习,日常开发中也就偶然写工具用一下。因而,咱们只须要把罕用的正则了解透就能够了,不要有心理包袱,看完本文,大部分的正则应用场景就能够活学活用。

场景一:匹配两个 # 之间的字符串

当初咱们把需要转换成实现思路,想要获取上述数据中的话题,其实就是匹配两个 # 之间的文本内容,show code:

正则表达式#.*?#

    public static void main(String[] args) {
        String title = "# 刘亦菲 35 岁生日获央视独宠# 神仙姐姐生日快乐!";
        Pattern p = Pattern.compile("(#.*?#)");
        Matcher m = p.matcher(title);
        while (m.find()) {String group = m.group(0);
            System.out.println("话题:" + group);
        }
    }

输入

话题:# 刘亦菲 35 岁生日获央视独宠 #

能够看出,输入的后果就是该条数据的话题,给大家剖析一下这个正则表达式:
.示意任意字符,?平时示意匹配 0 个或者多个,此时它示意 不贪心 ,那什么是 贪心 呢?

说到 贪心 ,那就不得不提这两个限定符:*+,它们两个就是 贪心 的!*示意匹配 0 个或者多个,+示意匹配至多一个,能够发现它们的共性:都会尽可能匹配更多。但,只有紧跟在它们的前面加上一个 ?,让他们扪心自问,就能够实现 非贪心,即最小匹配。比方,咱们在题目上再加一个#,此时题目变为# 刘亦菲 35 岁生日获央视独宠 ## 神仙姐姐生日快乐!,而后正则表达式咱们不应用?,此时,运行代码后输入后果为:

话题:# 刘亦菲 35 岁生日获央视独宠 ##

比拟两次的执行后果,咱们会发现输入后果多了一 #,这样就很贪心,违反了咱们的初衷,这就是? 的妙用。

场景二:只匹配 # 结尾的字符串

咱们晓得不同平台的话题格局是不一样的,比方抖音,它的话题模式就与微博不同,只是 # 结尾,并没有成对的 # 与其响应:

题目:# 刘亦菲 35 岁生日获央视独宠 神仙姐姐生日快乐!

如果是这种模式的话题,爱动脑筋的敌人就会发现无非就是将前面的 # 变为一个空格或者多个空格呗。没错,咱们能够应用

正则表达式#.*?\\s+

    public static void main(String[] args) {
        String title = "# 刘亦菲 35 岁生日获央视独宠  神仙姐姐生日快乐!";
        Pattern p = Pattern.compile("(#.*?\\s+)");
        Matcher m = p.matcher(title);
        while (m.find()) {String group = m.group(0);
            System.out.println("话题:" + group);
        }
    }

输入

话题:# 刘亦菲 35 岁生日获央视独宠 

Tips\s 示意匹配所有空白符,它不仅仅能够匹配空格,还能够匹配换行等空白字符,如果再加上+,组合起来就示意甭管几个空白字符,通通 all in。

不过,不要快乐得太早,心细的小明还发现话题可能会存在文末的状况:

题目:神仙姐姐生日快乐!# 刘亦菲 35 岁生日获央视独宠

此时是没有空白字符完结的,下面的正则就不满足这种状况。那如何是好?小明过后就想到了两个计划:

  • 计划一:不论话题在不在文末,咱们在匹配之前全副给题目追加一个空白字符,这样就能够人为干涉,奇妙地避开了这种状况,曲线救国,便于正则匹配
  • 计划二:应用正则表达式#.*?$

Tips:计划二中的 $ 是用来匹配输出字符串的结尾地位,组合起来就示意匹配# 结尾,始终到句末的话题。

进阶

后面两种场景咱们尽管获取到了两个 # 之间或者 # 结尾的内容,实现了需要,然而匹配的后果还是会带上 #,贪心的小明不满足现状(产品强制要求),可不可以不带呢?
当然能够了!小明又想到了两个计划:

  • 计划一:失去匹配的话题后,再二次文本处理去掉#
  • 计划二:应用正则表达式 ?<=?=一步到位,间接去除#

应用办法

  • (?<=exp2)exp1:示意匹配 exp2 前面的 exp1
  • exp1(?=exp2):示意匹配 exp2 后面的 exp1
    那联合以上咱们理论应用的所有场景,最终这个现实的正则表达式就正式出炉(好热):((?<=#).*?(?=#|\s+))

    反馈慢的敌人,能够慢点了解,咱们先运行试一下(不自信):

    public static void main(String[] args) {
        String title = "# 刘亦菲# #神仙姐姐 #生日快乐# #刘亦菲 35 岁生日获央视独宠";
        Pattern p = Pattern.compile("((?<=#).*?(?=#|\\s+|$))");
        Matcher m = p.matcher(title);
        while (m.find()) {String group = m.group(0);
            System.out.println("话题:" + group);
        }
    }

输入

话题: 刘亦菲
话题:
话题: 神仙姐姐
话题: 生日快乐
话题:
话题: 刘亦菲 35 岁生日获央视独宠

Tips:正则表达式中的 | 示意或,即多项之间的一个抉择,就像明天你看完本文,感觉不错的话,
必须做出 ( 关注 | 点赞 | 星标 ) 其中的一个抉择!
从代码的输入后果咱们能够看出,目前的正则是经得住理论考验的。然而惟一美中不足的是,会有空字符串的状况呈现(产品不批准)。
这该如何是好?
目前小明的解决方案是,拿到匹配后果时,过滤掉空字符串。能解决问题的方法就是好方法。不过,必定有更完满的表达式能够实现这个需要,此处抛砖引玉,期待你在评论区分享!

罕用的正则表达式分享

  • 微信号(并不能帮你要到男神 | 女神的微信号)
^[a-zA-Z][a-zA-Z\d_-]{5,19}$

未完待续……

本文可转载,但需申明原文出处。程序员小明,一个很少加班的程序员。欢送关注微信公众号“程序员小明”,获取更多优质文章。

退出移动版