一文读懂java正则表达式基础知识,动手试试吧

Posted on 2017-03-28 by 毛三胖

摘要

本文简要介绍了java正则表达式的基础知识,包括简单字符类,预定义字符类,量词,分组,边界匹配及Pattern和Matcher类的基本释意和用法。想要熟练掌握,还需多多的动手实践和阅读文档。


1 Hello 正则

1.1 Maven导入junit

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

1.2 编写测试类

import static org.junit.Assert.*;
import org.junit.Test;
public class BaseTest {
    @Test
    public void testBase() {
        String str = "hello regex";
        assertTrue(str.matches("hello regex"));
    }
}

2 基础

2.1 简单字符类

构造 描述
[abc] a,b或c
[^abc] 除a,b或c外的字符
[a-zA-Z] a至z 或 A至Z
[a-d[m-p]] a至d 或 m至p
[a-z&&[def]] d,e或f
@Test
public void testChar() {
    //匹配 b,c或d
    assertTrue("d".matches("[bcd]"));
    //匹配除 a,b,c 以外的字符 (否定)
    assertTrue("d".matches("[^abc]"));
    //匹配 a至z 的任一字符 (范围)
    assertTrue("d".matches("[a-z]"));
    //匹配 d,e或f (交集)
    assertTrue("d".matches("[a-z&&[def]]"));
}

2.2 预定义字符类

构造 描述
. 任意字符
\d 一个数字 [0-9]
\D 一个非数字 [^0-9]
\s 空白字符 [ \t\n\x0B\f\r]
\S 非空字符
\w 常规字符 [a-zA-Z_0-9]
\W 非常规字符
@Test
public void testPredef() {
    //匹配 任意字符 (可能不匹配行终止符)
    assertTrue("d".matches("."));
    //匹配 数字
    assertTrue("4".matches("\\d"));
    //匹配 非数字
    assertTrue("d".matches("\\D"));
    //匹配 空白字符 [ \t\n\x0B\f\r]
    assertTrue(" ".matches("\\s"));
    //匹配 非空字符
    assertTrue("d".matches("\\S"));
    //匹配 常规字符 [a-zA-Z_0-9]
    assertTrue("d".matches("\\w"));
    //匹配 非常规字符
    assertTrue("!".matches("\\W"));
}

2.3 量词

贪心 勉强 描述
X? X?? X出现一次或没有
X* X*? X出现零次或多次
X+ X+? X出现一次或多次
X{n} X{n}? X出现n次
X{n,} X{n,}? X出现至少n次
X{n,m} X{n,m}? X出现至少n次,至多m次
@Test
public void testQuant() {
    // * 表示出现0次或多次 (贪心,最大匹配)
    assertEquals("<b>d<b>".replaceAll("<.*>","#"),"#");
    // * 表示出现0次或多次,? 表示最小匹配
    assertEquals("<b>d<b>".replaceAll("<.*?>","#"),"#d#");
    // + 表示出现1次或多次 (贪心,最大匹配)
    assertEquals("<b>d<b>".replaceAll("<.+>","#"),"#");
    // * 表示出现1次或多次,? 表示最小匹配
    assertEquals("<b>d<b>".replaceAll("<.+?>","#"),"#d#");
    // {1} 表示出现1次
    assertEquals("<b>d<b>".replaceAll("<.{1}>","#"),"#d#");
    // {1,} 表示出现1次至多次
    assertEquals("<b>d<b>".replaceAll("<.{1,}>","#"),"#");
    // {1,8} 表示出现1次至8次
    assertEquals("<b>d<b>".replaceAll("<.{1,8}>","#"),"#");
}

2.4 分组

@Test
public void testGroup() {
    // () 表示分组,?表示出现0次或1次,\\d\\d表示两个数字
    assertFalse("du2".matches("du(\\d\\d)?"));
    // 匹配
    assertTrue("du12".matches("du(\\d\\d)?"));
    // 不匹配,分组条件出现了2次
    assertFalse("du1212".matches("du(\\d\\d)?"));
    // 匹配
    assertTrue("du1212".matches("du(\\d\\d)+"));
}

2.5 边界匹配

边界构造 描述
^ 行开始
$ 行结尾
\b 单词边界
\B 非单词边界
\A 输入开始
\z 输入结尾
@Test
public void testBound() {
    // ^ 行开始
    assertTrue("42du".matches("^(\\d\\d)du"));
    // $ 行结尾
    assertTrue("42du".matches("\\d\\d(du)$"));
    // \\b 表示单词边界
    assertTrue("a dog".matches(".*\\bdog\\b"));
    // \\B 表示非单词边界
    assertTrue("a doggie".matches(".*\\bdog\\B.*"));
}

2.6 Pattern和Matcher基本

import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MatcherDemo {
    public static void main(String[] args){
        // 不区分大小写
        Pattern pattern = Pattern.compile("\\bdog\\B",Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher("The Doggie plays");
        while (matcher.find()) {
            System.out.println(matcher.group());
            System.out.println(matcher.start());
            System.out.println(matcher.end());
        }
    }
}

输出

Dog
4
7

3 示例

3.1 用户名正则

/*
*  ^            开头
*   [a-z0-9_-]  匹配a-z,0-9,下划线,中线
*    {4,10}     长度4至10
*  $            结尾
*/
String unReg = "^[a-z0-9_-]{4,10}$";

3.2 颜色正则

/*
*    ^    开头
*     #         "#" 符号
*    (         开始分组
*      [A-Fa-f0-9]{6} 长度为6的字母数字
*      |              或
*      [A-Fa-f0-9]{3} 长度为3的字母数字
*    )         分组结束
*    $    结尾
*/
String coReg = "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$";

3.3 24时制时间

/*
 *  (    分组开始
 *    [01]?[0-9]    0-9,00-09,10-19
 *    |                或
 *    2[0-3]        20-23
 *  )    分组结束
 *  :     :符号
 *  [0-5][0-9]    00 至 59
 */
String tiReg = "([01]?[0-9]|2[0-3]):[0-5][0-9]";

4 结语

本文简要介绍了java正则表达式的最基础的知识内容,并给出了简单实用的小例子来理解消化所学内容。要想熟练掌握这些基础知识,还要动手多加以练习,阅读官方文档。java正则表达式的进阶的内容我会在下一篇文章里进行介绍。 推荐java正则表达式学习的一些资料:

官方:docs.oracle.com

英文:vogella.com

中文:runoob.com