刘亦菲生日当天,引发了我对正则的思考

刘亦菲生日当天,引发了我对正则的思考

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

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

标题:#刘亦菲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:方案二中的 $ 是用来匹配输入字符串的结尾位置,组合起来就表示匹配 #开头,一直到句末的话题。

进阶

前面两种场景我们虽然获取到了两个 #之间或者 #开头的内容,实现了需求,但是匹配的结果还是会带上 #,贪婪的小明不满足现状(产品强制要求),可不可以不带呢?
当然可以了!小明又想到了两个方案:

  • 方案一:得到匹配的话题后,再二次文本处理去掉 #
  • 方案二:使用正则表达式 ?<=< code>&#x548C;<code>?=</code>&#x4E00;&#x6B65;&#x5230;&#x4F4D;&#xFF0C;&#x76F4;&#x63A5;&#x53BB;&#x9664;<code>#</code><!--=<-->

使用方法

  • (?<=exp2)exp1< code>&#xFF1A;&#x8868;&#x793A;&#x5339;&#x914D; <code>exp2</code> &#x540E;&#x9762;&#x7684; <code>exp1</code><!--=exp2)exp1<-->
  • exp1(?=exp2):表示匹配 exp2 前面的 exp1
    那结合以上我们实际使用的所有场景,最终这个理想的正则表达式就正式出炉(好热): ((?<=#).*?(?=#|\s+))< code><br><img src="https://img.mynamecoder.com/lyf.gif"><br>&#x53CD;&#x5E94;&#x6162;&#x7684;&#x670B;&#x53CB;&#xFF0C;&#x53EF;&#x4EE5;&#x6162;&#x70B9;&#x7406;&#x89E3;&#xFF0C;&#x6211;&#x4EEC;&#x5148;&#x8FD0;&#x884C;&#x8BD5;&#x4E00;&#x4E0B;&#xFF08;&#x4E0D;&#x81EA;&#x4FE1;&#xFF09;&#xFF1A;<!--=#).*?(?=#|\s+))<-->
    public static void main(String[] args) {
        String title = "#&#x5218;&#x4EA6;&#x83F2;# #&#x795E;&#x4ED9;&#x59D0;&#x59D0; #&#x751F;&#x65E5;&#x5FEB;&#x4E50;# #&#x5218;&#x4EA6;&#x83F2;35&#x5C81;&#x751F;&#x65E5;&#x83B7;&#x592E;&#x89C6;&#x72EC;&#x5BA0;";
        Pattern p = Pattern.compile("((?<=#).*?(?=#|\\s+|$))"); matcher m="p.matcher(title);" while (m.find()) { string group="m.group(0);" system.out.println("话题:" + group); } < code></=#).*?(?=#|\\s+|$))");>

输出

&#x8BDD;&#x9898;:&#x5218;&#x4EA6;&#x83F2;
&#x8BDD;&#x9898;:
&#x8BDD;&#x9898;:&#x795E;&#x4ED9;&#x59D0;&#x59D0;
&#x8BDD;&#x9898;:&#x751F;&#x65E5;&#x5FEB;&#x4E50;
&#x8BDD;&#x9898;:
&#x8BDD;&#x9898;:&#x5218;&#x4EA6;&#x83F2;35&#x5C81;&#x751F;&#x65E5;&#x83B7;&#x592E;&#x89C6;&#x72EC;&#x5BA0;

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

常用的正则表达式分享

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

未完待续……

对了,记得关注一下微信公众号,我在那里等大家。

欢迎关注微信公众号,获取更多资源

刘亦菲生日当天,引发了我对正则的思考

Original: https://www.cnblogs.com/coderxx/p/16643776.html
Author: Coder小明
Title: 刘亦菲生日当天,引发了我对正则的思考

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/610592/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 认识JavaWeb

    JavaWeb Java Web 1、基本概念 1.1、前言 web开发: web,网页的意思 , www.baidu.com 静态web html,css 提供给所有人看的数据始…

    Java 2023年6月8日
    077
  • MapReduce报错Exception in thread “main” java.lang.UnsatisfiedLinkError: org.apache.hadoop.io.nativeio

    在使用MapReduce的小测试的时候,Driver类启动,或报下面的错误共有两种解决方案 java;gutter:true; log4j:WARN No appenders co…

    Java 2023年6月9日
    0123
  • Java基础语法02——流程控制

    流程控制:顺序结构、分支结构(if-else、switch-case)、循环结构(for、while、do-while) 实现从键盘获取不同类型的变量——Scanner类 步骤: …

    Java 2023年6月5日
    082
  • Docker安装InfluxDB

    时序型数据库 时序数据库就是存放事件序列数据的数据库,需要支持时序数据的快速写入、持久化、多维度的聚合查询等基本功能。 时间序列数据 时间序列数据是基于时间的一系列数据。在有时间的…

    Java 2023年6月7日
    088
  • Spring

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年6月15日
    069
  • 约瑟夫环数学问题,最容易看懂的教程。

    先大概看一下图片中的内容,下面做详细解释 其中字母的意义代表A倒数第二个死亡,B倒数第三个死亡,以此类推。前几个可能不容易看懂,但是仔细看 第四步到第五步的下标变化, 相当于把第四…

    Java 2023年6月5日
    0153
  • IBM MQ Explorer 示例操作

    此示例为双向传输 建立队列管理器 建立【test01】【test02】两个队列管理器,一直下一步即可,端口号不能一致(需要记住设置的端口号,后面会用到) 【test01】端口号 1…

    Java 2023年5月29日
    075
  • Docker容器化技术

    初始Docker 1.1 Docker概念 Docker概念:Docker是一个开源的应用容器引擎 诞生于2013年初,基于Go实现,dotCloud公司出品(后改名为Docker…

    Java 2023年6月6日
    0104
  • ReentrantLock可重入、可打断、Condition原理剖析

    本文紧接上文的AQS源码,如果对于ReentrantLock没有基础可以先阅读我的上一篇文章学习ReentrantLock的源码 重入加锁其实就是将AQS的state进行加一操作 …

    Java 2023年6月16日
    064
  • autocomplete=”off”清空输入框

    有过表单设计经验的朋友肯定知道,当我们在浏览器中输入表单信息的时候,往往input文本输入框会记录下之前提交表单的信息,以后每次只要双击 input文本输入框就会出现之前输入的文本…

    Java 2023年6月5日
    087
  • Java的值传递

    特别注意:java只有值传递没有引用传递。 一、值传递和引用传递的定义 值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进…

    Java 2023年5月29日
    0102
  • 线程笔记:Future模式

    线程技术可以让我们的程序同时做多件事情,线程的工作模式有很多,常见的一种模式就是处理网站的并发,今天我来说说线程另一种很常见的模式,这个模式和前端里的ajax类似:浏览器一个主线程…

    Java 2023年5月30日
    093
  • 获取一个字符串中的指定字符

    在写代码的过程中总是会遇到提取字符传中想要的部分,但每次遇到的情况不一样,在这里做个总结 例如:9天,取出数字 9 String Str = "9&#x5929;…

    Java 2023年6月8日
    056
  • nginx 学习,详细总结

    一 、nginx介绍 1.简介 Nginx 是高性能的 HTTP 和反向代理的web服务器,处理高并发能力是十分强大的,能经受高负 载的考验,有报告表明能支持高达 50,000 个…

    Java 2023年6月8日
    075
  • 基于多数据源零代码同时生成多个数据库CRUD增删改查RESTful API接口——MySql,PostgreSql,Oracle,Microsoft SQL Server

    多数据源 回顾 通过前面文章的介绍,目前已经支持主流数据库,包括MySql,PostgreSql,Oracle,Microsoft SQL Server等,通过配置零代码实现了CR…

    Java 2023年6月6日
    0100
  • 将.cer证书导入java密钥库?

    导入 .cer从浏览器下载的证书文件(打开网址并挖掘详细信息)到cacerts keystore中 java_home\jre\lib\security为我工作,而不是尝试生成和使…

    Java 2023年5月29日
    070
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球