• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Java正则表达式

武飞扬头像
Real_man
帮助86

前言

在项目开发的过程中,涉及到字符串处理的部分经常要用到正则表达式,但是发现自己容易忘掉这部分知识... 里面零散的点挺多的,为了加深记忆方便以及后续回来检索,梳理下正则相关的知识;

正文

语法

常见正则规则

正则表达式 Description
. 匹配任意的字符串
^regex 仅仅匹配regex必须在一行的开头字符。
regex$ 仅仅匹配regex出现在一行的末尾的字符串。比如 xxxxxregex。 而xxxregexyyy不行。
[abc] 匹配[]中的任意字符
[abc][vz] 首先任意匹配a、b、c;然后任意匹配v、z;总共有6种结果:av、az、bv、bz、cv、cz
[^abc] 匹配任何不是a、b、c的字符
[a-d1-7] 匹配一个范围,具体位置可以是a-d中的任何一个字符,1-7之间的任何一个数字。
`X Z` 匹配X或者Z

正则元字符

一些预定义的元字符,让我们更容易使用正则表达式,可以看做替我们提前写好了上述的一些常见正则规则。

元字符 描述
\d 任何数字,即[0-9]
\D 任何非数字,即 [^0-9]
\s 任何空白字符,即 [ \t\n\x0b\r\f]
\S 任何非空白字符。即[^ \t\n\x0b\r\f]
\w 任意单词类型字符, 即 [a-zA-Z_0-9]
\W 任意非单词字符,即 [^\w]
\S 多个非空白字符
\b 匹配一个字边界,即字与空格间的位置。例如,"er\b"匹配"never"中的"er",但不匹配"verb"中的"er"。
\B 非字边界匹配。"er\B"匹配"verb"中的"er",但不匹配"never"中的"er"。

正则量词

量词即匹配一个字符串出现了多少次。

字符 描述
* 零次或多次匹配前面的字符或子表达式。例如,zo 匹配"z"和"zoo"。 等效于 {0,}。
匹配一次或多次前面的字符,{1, }
? 匹配前一个字符不超过一次,即{0,1}
{X} X为数字,代表精确的匹配前一个字符几次。\d{3},代表精确匹配三个数字。
{X,Y} 匹配前一个字符,X次到Y次之间
*? 即只匹配一次就停止接下来的匹配。

参考:www.runoob.com/java/java-r…

常见案例

附上一些常见的用法,字符串中使用到正则的方法:

  • matches
  • split
  • replaceFirst
  • replaceAll

replace方法不支持正则表达式。

提取数字

@Test
public void regextExtractNumber(){
    // 匹配任意的数字
    Pattern p = Pattern.compile("\\d ");
    Matcher m = p.matcher("string1234more567string890");
    while(m.find()) {
        System.out.println(m.group());
    }
}

匹配手机号

@Test
public void regexPhone(){
    // 手机号的第一位必须为 1。   ^[1]
    // 手机号的第二位必须为 3,4,5,7,8 中的任意一个。 [34578]
    // 紧接着有9位数字,只要是数字就行。[0-9]{9}
    // 没有其它额外的内容。最后一位$
    Pattern pattern = Pattern.compile("^[1][34578][0-9]{9}$");

    String p1 = "13855683754";
    String p2 = "15880975963";
    System.out.println(pattern.matcher(p1).matches());
    System.out.println(pattern.matcher(p2).matches());
}

匹配IP地址

这个属于比较复杂的案例,能看懂这个正则就ok了。

@Test
public void regexIpv4(){
    // IP地址长度不固定。因此可能出现误匹配
    // 将如下的正则表达式分为4段内容看即可。因为IP由三个  . 分隔开,以下正则也是又3个.分隔,最终以数字结尾。

    // ^[01]?\\d\\d?   如果是三个数字,第一位必须是0或1。但是可以为1位到2位数字。
    //  2[0-4]\\d    如果是以2开头的,那么接下来必须是0~4之间的一个数,第三位为任意数字
    //  25[0-5]    如果是以25开头的,那么最后一个数字只能是  0~5。
    // 其余一样
    String ip_pattern =
            "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."  
                    "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."  
                    "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."  
                    "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";

    Pattern pattern = Pattern.compile(ip_pattern);

    List<String> strings = Arrays.asList(
            "0.1.1.1",
            "0.02.0.0",
            "192.168.1.1",
            "132.254.111.10",
            "127.0.0.1"
    );

    for (String string : strings) {
        System.out.println(pattern.matcher(string).matches());
    }
}

提取html中href地址。

@Test
    public void testHref(){
        String aTag = "<a href=\"https://sensiolabs.com\" title=\"SensioLabs, PHP services and software solutions for enterprise and community.\">\n"  
                "                                <img loading=\"eager\" height=\"17\" src=\"/images/pictos/slsponsor.svg\" alt=\"Symfony is sponsored by SensioLabs\">\n"  
                "                            </a>";

        // html的连接标签,属性为href。
        // 地址中不为空,但可能有?#等内容,因此用非空匹配。
        // href地址由""引起来,因此两边加上""
        // 使用正则的反向引用特性
        Pattern pattern = Pattern.compile("href=\"(\\S )\".*");
        Matcher matcher = pattern.matcher(aTag);
        if (matcher.find()){
            System.out.println(matcher.group(1));
        }
    }

短信消息模板替换

 @Test
    public void testMatchs(){
        Pattern patternWithLimitFunction = Pattern.compile("\\$\\{[a-z0-9A-Z#_] }");
        String template = "${nick},你购买的${shopName}正在运输中${shopName}";
        Matcher matcher = patternWithLimitFunction.matcher(template);

        HashMap<String, Object> templateData = new HashMap<>();
        templateData.put("nick","aihe");
        templateData.put("shopName","鸡蛋");

        Set<String> vars = new HashSet<>();
        while (matcher.find()) {
            int start = matcher.start();
            int end = matcher.end();
            String holder = template.substring(start, end);
            String holderContent = template.substring(start   2, end - 1);
            // 拿到的占位符,是否在系统中支持,能发从Tair中获取
            if (!templateData.containsKey(holderContent)){
                throw new RuntimeException("无法替换");
            }
            vars.add(holderContent);
        }

        String finalContent = template;
        for (String var : vars) {
            finalContent = finalContent.replaceAll("\\$\\{"   var   "\\}", String.valueOf(templateData.get(var)));

        }
        System.out.println(finalContent);
    }

总结

正则表达式在开发项目的时候经常用到,但是其中的涉及到的知识要记忆的比较多,容易忘记...

梳理了下本文,后续在写正则相关内容的时候可以回来参考下;

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanfbgji
系列文章
更多 icon
同类精品
更多 icon
继续加载