随机名言

正则表达式



平时用得少,遇到就得到处找。这里总结一下用法,方便复查


1. 正则表达式(regular expression)

描述了字符串的模式匹配,可用于检索、替换、截取符合模式(规则)的串


预习内容:

  • 需正则引擎来进行处理,通常该引擎嵌入程序中(Java正则包嵌到RT里面)
  • 正则会首先返回第一个匹配的串,即使后面还有匹配的模式(急切性)
  • 某些特殊字符需预处理才能传递给引擎(+,*,?),匹配特殊字符要用 \ 转义
  • 匹配 \ 要用 \\,Java匹配路径用到正则,那么地址写法有两种:
    • C:\\dir\\xxx.txt
    • C:/dir/xxx.txt
    • Windows路径用 \,Linux用 /,为了跨平台性推荐使用 / 来写路径
  • 换行符(\n)、回车符(\r),二者区别类似上世纪打字机,不同系统对换行有不同要求:
    • Windows:\r\n
    • Linux:\n
    • Max:\r




2. 正则的组成

  • 普通字符
    • 字母 abcABC
    • 数字 0123
    • 标点符号 , . ?
    • 其他符号
  • 特殊字符(元字符)
    • 非打印字符 \r \n
    • 限定符 * + ?
    • 定位符 ^ $
    • 选择 ( )
    • 反向引用

2.1 非打印字符

字符 描述
. 除换行符 \n之外的任意单字符
|
\n 换行符
\t 回车符
\d 数字(digit)
\D 除了数字
\w 单词(word),数字,大小写字母,下划线
\W 非单词
\s 空白符(空格,制表符,换页符等)
\S 非空白符

2.2 限定符

字符 描述
* 0或多次
+ 1或多次
0或一次
出现几次
至少几次
出现n~m次

2.3 定位符

字符 描述
^ 开始
$ 结束
\b 单词边界(字与空格间的位置)
\B 非单词边界

2.4 选择

字符 描述
() 标记子表达式

补充:

  • 字符集[]仅仅匹配里面的其中的一个
  • [^] 表示取反,即不在字符集里面的内容,[^0-9],表示不匹配数字




3. 正则优先级

正则表达式从左到右进行计算,并遵循优先级顺序,下表优先级从高到低

运算符 描述
\ 转义符
()、[] 圆括号、方括号
*、+、?、 限定符
^、$、\num 定位符、分组编号
| 替换




4. 匹配模式

修饰符 描述
i ignore:大小写不敏感
g global:全局匹配
m multiline:多行匹配,^$会匹配新行符
s single:单行匹配,.会匹配新行符




5. 选择 ()


5.1 分组

可将括号内容看成一个整体进行匹配

(abc+),表示:abc出现1或多次

5.2 分支

使用分支时要用括号包裹

a(b | c | d),表示:ab、ac、ad的其中一个

5.3 分组引用

字符串:2020-11-07
模式串:(\d{4})-(\d{2})-(\d{2})
不需要分组引用:(?:\d{4})-(\d{2})-(\d{2}),引用需要缓存降低了速度

引用会把匹配到的组按编号存入缓存,0编号表示整体,后面依次是匹配的内容,使用\n来访问分组:

  • 0:2020-11-07
  • 1:2020
  • 2:11
  • 3:07




6. 贪婪和惰性

贪婪是尽可能匹配多的字符,而惰性则是尽可能匹配少的字符(后面加 ? 实现惰性)


6.1 引擎工作原理

字符串:<h1>This is H1</h1>
贪婪模式串:<.+>
惰性模式串:<.+?>

模式串中:< 匹配该字符,.匹配任意非换行字符,+匹配1或多次前置字符直到换行,>匹配该字符,表示惰性


贪婪流程:

  • <匹配字符串的第一个<
  • .一直匹配前面所有字符,直到最后的换行匹配失败
  • 然后引擎对下一个正则符号匹配,即匹配>,这时会进行回溯,即</h1>的>会被匹配到即立刻急切返回

惰性流程:

  • <匹配字符串的第一个<
  • .匹配h,因为是惰性,所以匹配了.就开启匹配>,尽可能返回少的字符
  • >匹配1失败,就会进行后移,用.继续匹配后面的1,然后重复上面一步
  • 最终返回<h1>




7. 正负向预查

  • xxx(?=pattern):捕获xxx,而xxx是以xxxpattern结尾
  • xxx(?!pattern):上面的否定,即不以pattern结尾
  • (?<=pattern)xxx:捕获xxx,而xxx是以pattern开头
  • (?<!pattern)xxx:上面的否定,即不以pattern开头




8. Java里的正则使用

java.util.regex 包主要包括以下三个类:

  • Pattern:正则表达式的编译表示,不可变类能多线程使用
    • Pattern.compile(reg,flag):表示匹配模式
  • Matcher:是对输入字符串进行解释和匹配操作的引擎
  • PatternSyntaxException:是一个非强制异常类,它表示一个正则表达式模式中的语法错误

8.1 匹配查找

public static void main(String[] args) throws InterruptedException {

    String str = "123456789";             // 字符串
    String reg = "\\d+";     			  // 模式串

    Pattern pattern = Pattern.compile(reg);
    Matcher matcher = pattern.matcher(str);
    boolean b = matcher.matches();		 // true
}

8.2 捕获组

public static void main(String[] args) throws InterruptedException {

    String str = "020-123456";             // 字符串
    String reg = "(\\d{3})-(\\d{6})";     // 模式串

    Pattern pattern = Pattern.compile(reg);
    Matcher matcher = pattern.matcher(str);

    if(matcher.find()){
        System.out.println(matcher.group(0));	// 020-123456
        System.out.println(matcher.group(1));	// 020
        System.out.println(matcher.group(2));	// 123456
    }
}

8.3 替换

public static void main(String[] args) throws InterruptedException {

    String str = "The dog is mine which dog is playing";             // 字符串
    String reg = "dog";                                              // 模式串

    Pattern pattern = Pattern.compile(reg);
    Matcher matcher = pattern.matcher(str);
    String strNew = matcher.replaceAll("cat");
    System.out.println(strNew);			// "The cat is mine which cat is playing"
}

8.4 String类的正则

public static void main(String[] args) throws InterruptedException {

    String str = "123456789";             // 字符串
    String reg = "\\d+";     			  // 模式串
    
    boolean matches = str.matches(reg);
    System.out.println(matches);		  // true
}



参考:

菜鸟教程

摩诘



posted @ 2020-11-07 13:18  Howlet  阅读(165)  评论(0编辑  收藏  举报

Copyright © By Howl