Java -- 正则表达式

本篇是Java编程思想第四版的正则表达式笔记,因为正则表达式语法很容易忘记,自己整理整理。感觉好多。。还没写完

介绍

正则表达式是一种强大而灵活的文本处理工具。通过正则表达式,我们可以构造一个复杂的文本模式,对输入的字符串进行搜索,一旦找到了匹配这些模式的部分(就是找到了你想要找的字符串),你就可以随心所欲地处理了。

可以参考JDK文档的java.util.regex包中的Pattern类,我将其书上列出的放在文章最后面

示例

String类内建的功能

1. matches

引用正则表达式最简单的途径就是利用String类的matches方法,但是要注意的是这里是全字符串匹配

String str1 = "How are you?";
System.out.println(str1.matches("you")); //flase
System.out.println(str1.matches("How are you")); //ture

这里我一开始就觉得很奇怪,为什么不能匹配一个确切的单词呢,后来发现了一篇博客,才知道原来它会在原来的基础上自动加上^和$(这两个都是边界匹配符表示一行的起始和结束),这样就变成匹配整个字符串了

如果想要找某个单词,可以这么写

System.out.println("How are you?".matches(".*(are)*"));

点可以匹配任意一个字符,are要括号起来表示一个整体。

数字字符串

System.out.println("+3254".matches("(-|\\+)?\\d+")); //true

这里\\表示转义,\\+表示+号字符,不转移表示重复前面的内容一个或多个,| 表示或者,\d表示就是0-9字符,问号表示重复前面内容的0次或一次,也就是要么不出现,要么出现一次。这都是最后面表中的量词

 

2. split方法

String类还有一个正则表达式工具,split方法,返回值是一个String数组,它会将字符串从正则表达式匹配的地方切开

for(String temp : "boo:and:foo".split(":")){
    System.out.println(temp + " ");
}
//boo and foo
for(String temp : "boo:and:foo".split("o")){
    System.out.print(temp + " ");
}
b  :and:f

冒号换成\W结果一样,从第二个看出,匹配的是o,它以o为分隔符进行分解

split还有一个重载版本,可以指定分割的次数,放上文档里面的示例

 

The string "boo:and:foo", for example, yields the following results with these parameters:

Split example showing regex, limit, and result
Regex Limit Result
: 2 { "boo", "and:foo" }
: 5 { "boo", "and", "foo" }
: -2 { "boo", "and", "foo" }
o 5 { "b", "", ":and:f", "", "" }
o -2 { "b", "", ":and:f", "", "" }
o 0 { "b", "", ":and:f" }

Pattern和Matcher

一般来说,比起有限的的String类,我们更愿意构造功能强大的正则表达式对象。

你可以通过调用Pattern.compile方法来编译你的正则表达式,它会生成一个Pattern对象,然后把你想要检索的字符串传入Pattern对象的.matcher()方法中,它会生成一个Matcher对象,它有很多功能可以使用。

1. Matcher,public boolean find​()

它会查找与模式匹配的输入序列的下一个子序列,若之前的find方法调用成功,且Matcher并未被重置,若继续调用find,则它会从之前匹配的最后一个字符继续匹配。一旦匹配成功,可以通过start()获取匹配子串的开始位置,end()获取结束位置,但是匹配的子串并不包括该索引上的字符,group获取匹配的字符串,相当于substring(start, end)。

例如写一个可以匹配1到10个数字和字母的qq邮箱(随便编的)

查找字符串中所有匹配的子串,输出起止索引

String str = "[email protected]@qq.com";
Pattern p = Pattern.compile("\\w{1,10}@qq\\.com");
Matcher m = p.matcher(str);
while(m.find()){
    System.out.println(m.start() + " " + m.end()
        + " " + m.group());
}
//0 17 [email protected]
//20 37 [email protected]

输出匹配的字符索引0-17,不包括17,继续调用find,他会从上一个查找的最后一个索引开始继续往后找。

 

2. Pattern,public static boolean matches​(String regex, CharSequence input)

这个方法和String类的matchers方法很像

 

()括号的作用

括号可以起到很好的区分作用,比如:(abc)+和abc+表达的意思就不同,后者是匹配ab随后匹配1个或多个c,前者是匹配1个或多个abc序列

 

正则表达式构造列表

字符

  1. x --- 字符x
  2. \\ --- 反斜杠
  3. \t --- 制符表
  4. \n --- 换行符
  5. \r --- 回车
  6. \f --- 换页
  7. \e --- 转义

字符类

  1. . --- dot,点,可以匹配任意一个字符
  2. [abc] --- 包含a,b,c的任何字符,和a|b|c功能相同
  3. [^abc] --- 1的否定
  4. [a-zA-Z] --- a-z或A-Z的任何字符
  5. [a-d[m-p]] --- 相当于[a-dm-p]
  6. f
  7. \s --- 空白符,就是在屏幕上显示空白的符号(空格,tab,换行,换页,回车)
  8. \S --- 非空白符,相当于[^\S]
  9. \d --- 数字0-9,相当于[0-9]
  10. \D --- 8的否定
  11. \w --- 词符相当于[a-zA-Z0-9]
  12. \W --- 11的否定

逻辑操作符

  1. XY --- Y在X后面
  2. X|Y --- X或Y
  3. (X)

边界匹配符

  1. ^ --- 一行的起始
  2.  
  3. $ --- 一行的结束
  4. \b --- 词的边界
  5. \B --- 非词的边界
  6. \G --- 前一个匹配的结束

量词

贪婪型

除非有其他的选项设置,贪婪表达式会为所有可能的符合条件的字符串去匹配。这样会有一个问题,比如我们的模式只能匹配第一个可能的字符组,但是他还是会继续匹配。

勉强型

和上面相反,它总是尽可能的匹配满足模式的所需的最少字符数,懒惰

占有型

当正则表达式匹配字符串时,它会产生相当多的状态,以便在匹配失败的时候可以回溯。而占有型并不会保存这些中间状态,因此它可以防止回溯。常用于防止正则表达式失控,因此可以使正则表达式执行起来更有效。(没有去深究里面的原理)

 

 

贪婪型 勉强型 占有型 如何匹配
X? X?? X?+ 一个或零个X
X* X*? X*+ 零个或多个X
X+ X+? X++ 一个或多个X
X{n} X{n}? X{n}+ 恰好n次X
X{n,} X{n,}? X{n,}+ 至少n次X
X{n,m} X{n,m}? X{n,m}+ 至少n次,不超过X次

 

 

 

 

 

 

 

你可能感兴趣的:(Java)