精通正则表达式,看完这篇就行了

新年快乐,开工大吉

对于正则表达式,不知道你有没这种感觉,总是能按照需求写出来一些,但是不执行一下总觉得不靠谱。今天我们来简单的看看正则表单时

正则表达式

一般你会用正则做什么,大部分都是做一些字符串的检查?下面有几个问题,不妨试着通过正则表达式看你是否能够解决?

  1. 校验密码是否包含字母大小写、数字、特殊字符(!@# %^&)且长度为6到12位
  2. 将数字12345678用货币格式(每3位一个,)最终效果:12,345,678
  3. 替换一段文字中的占位字符部分(比如${}包含的内容),类似ES6中的模板语法

定义

正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为regex、regexp或RE),是一种文本模式, 包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符"),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式(规则)的文本。

正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。

作用

回顾下上面的3个问题,我们使用正则基本上也就是完成类似的这些工作,从功能上我们可以划分为:

结构

正则表达式由普通字符以及元字符组成。其中普通字符包含0-9、a-z、A-Z以及各种符号;元字符则类似+ ? d s 这种具有特殊含义的字符。

字符









规则

  源字符串:...hello Regex !...
  贪婪模式:.* -> hello Regex !
  惰性模式:.*? -> hello Regex

我们可以简单的理解为,当正则匹配存在多种情况时,出现失败后的重试机制,直到所有情况都尝试失败才会最终失败。要注意有时这是非常耗费性能的

  正则:ab{1,3}c 源字符串:abc
  第一次匹配:a匹配到a
  第二次匹配:b{1,3}匹配到b
  第三次匹配:b{1,3}匹配到c,因为贪婪模式,尽可能多的匹配,当匹配到b后,会继续,碰到c,匹配失败,回溯最近一次成功的状态
  第四次匹配:b{1,3}匹配到b
  第五次匹配:c匹配到c,批次成功
为了减少回溯造成的性能问题,我们应该尽可能地明确需要匹配的目标字符,避免贪婪模式,比如使用b{1,3}?
示例:
  (A)(B(C)) 则会对应多个分组:
  0: (A)(B(C))
  1: (A)
  2: (B(C))
  3: (C)
  // 引用主要是为了减少输入,但要注意正确引用
  Pattern.compile("(###).*(1)").matcher("### this is content ###")
第一个问题的解决方案就用到了断言
只判断,不匹配

在javascript中,有i、g、m、s分别对应了不区分大小写、全局匹配、多行匹配以及包含换行符的元字符.匹配,而在Pattern中则提供了下面的几种模式:

元字符

所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。下面整理了元字符以及其对应的功能。



示例

下面来看下上面3个问题通过正则具体如何解决吧...

  1. 问题1,主要使用了断言来实现,当然你也可以拆分成多个正则进行匹配来达到相同的效果
    @Test
    public void checkPassword(){
        String password = "aaa123@Z";
        Pattern compile = Pattern.compile("(?=.*d+)(?=.*[a-z]+)(?=.*[A-Z]+)(?=.*[!@#$%^&]+)[a-zA-Zd!@#$%^&]{6,12}");
        log.info(">>> {}", compile.matcher(password).matches());
    }
  1. 问题2,同样借助了断言,实现字符串的查找,最终实现替换,当然我们替换的不是字符,而是匹配的位置
    @Test
    public void scientific(){
        String number = "123456789";
        String result = number.replaceAll("(?=B(d{3})+$)", ",");
        log.info(">> {}", result);
    }
  1. 问题3,通过分组实现字符串片段的查找,通过变量上下文重新组件字符串
    @Test
    public void replaceHolder(){
        Map context = new HashMap<>();
        context.put("company","north");
        context.put("project","blob");
        context.put("model","regex");

        String packages = "com.{company}.{project}.{model}.*";

        Pattern pattern = Pattern.compile("({[^}]*})");
        Matcher matcher = pattern.matcher(packages);

        StringBuffer result = new StringBuffer();
        while (matcher.find()){
            String group = matcher.group();
            String key = group.substring(1, group.length()-1);
            matcher.appendReplacement(result, context.getOrDefault(key,"") );
        }
        matcher.appendTail(result);
        log.info( result.toString() );
    }

工具库

https://www.runoob.com/regexp/regexp-operator.html

扩展知识

NFA引擎 DFA引擎

结束语

正则表达式是一种书写简单,功能强大且常用的技术,基本所有的编程语言都有其相关的实现与支持。因此深入了解正则实现原理与书写规范非常重要。

该篇主要通过简单的几个示例介绍了正则表达式的功能以及一些基本结构与功能,希望能够抛砖引玉,让你对正则表达式有更深的认识。

来源;https://mp.weixin.qq.com/s/XuRENQXqh8EXesnDztfi3Q

作者:指北君

展开阅读全文

页面更新:2024-03-19

标签:正则   断言   表达式   惰性   字符串   贪婪   字符   类似   规则   模式

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top