一、前言部分
控制台输入的字符串,编译成java字符串之后才送进内存,比如控制台打\,送进内存的是\\
java字符串中的特殊字符只有转义字符 \ 和表示边界的字符 "
转义字符的作用是:(1)将边界符转义成普通字符
(2)将自身转义成普通字符
(3)将无法用26字母表示的输入转义出来,如 \t 表示制表符 \r表示回车 \n表示换行等
在java字符串,字符 \ 只能组成\b \t \n \f \r \" \' \\ 这几种形式。
使用时:
Pattern pattern = Pattern.compile("\\d{6}");
对于某些函数的正则表达式(字符串)参数,比如split的参数,写好正则表达式,然后转义其中的java字符串特殊字符 \ 和 " 即可
二、使用范例简介:
(1)将正则表达式的字符串编译成pattern,
Pattern pattern = Pattern.compile("^Java.*");
(2)利用pattern的matcher方法,构造matcher对象,参数是待匹配字符串:Java不是人。
Matcher matcher = pattern.matcher("Java不是人");
(3)根据自己需求,调用matcher的方法
例如:
boolean b= matcher.matches() //当条件满足时,将返回true,否则返回false
matcher.replaceAll("Java") //返回的是替换后的字符串,
//调用find方法递归出匹配结果
while (matcher.find()) {
System.out.printf(
"I found the text \"%s\" starting at index %d and ending at index %d.%n",
matcher.group(), matcher.start(), matcher.end()
);
}
另外:Pattern对象还有个split方法,来根据 正则表达式 分割串(三种:逗号 空格 竖线)
Pattern pattern1 = Pattern.compile("[, |]+");
String[] strs = pattern1.split("Java Hello World Java,Hello,,World|Sun");
上述语句中字符 | 在方括号中,表示普通字符,不用转义,当然转义也没错:[, \\|]+,但是用在括号外,则一定转义
字符 - 在方括号中如果前面或后面没有数字,不闭合,则表示普通字符:正则 [4-] 匹配 - 当然正则 [4\\-] 也匹配 -
像^ * .等单独使用作为分割符,虽然不会报错(可以通过java的字符串检查机制),但是结果会是意想不到。因此需要加上\\
三、简单规则
----------------------------------------------------------------------------
正则表达式的特殊字符(元字符 meta characters)
(1) - 连字符,在[]中用作范围时需要转义,例如[0-9]
(2) \ 转义字符
\\ 反斜杠
\t 制表符 ('/u0009')
\n 换行 ('/u000A')
\r 回车 ('/u000D')
\d 数字 等价于[0-9]
\D 非数字 等价于[^0-9]
\s 空白符号 [/t/n/x0B/f/r]
\S 非空白符号 [^/t/n/x0B/f/r]
\w 单词字符 [a-zA-Z_0-9]
\W 非单词字符 [^a-zA-Z_0-9]
\b 单词边界
er\b 匹配never,不能匹配version,因为er在一个词的中间
\bdog\b 匹配dog 不匹配doggie
\B 非单词边界
\bdog\B 匹配doggie 不匹配dog
\A 输入的开头
\z 输入的结尾
\G 上一个匹配的结尾
\Gdog 匹配dogdog两个,匹配“dog dog”一个,
由于第二次出现的“dog”不是在前一个匹配结尾的开始
(3) . 单个任意字符(除换行外)
(4) * 前面的字符出现0次以上
J* 0个以上J
.* 0个以上任意字符
J.*D J与D之间0个以上任意字符
(5) + 前面的字符出现1次以上
J+ 1个以上J
.+ 1个以上任意字符
J.+D J与D之间1个以上任意字符
(6) ^ 以后面出现的字符开头 ^java 以Java为开头字符
(7) $ 以前面出现的字符结尾 java$ 以java为结尾字符
(8) [] 里面出现的字符任意一个(待选字符连着写,中间无空格,如果是[, |] 则是三种分隔符:空格 逗号 竖线)
[aeio] aeio其中任意之一
[0-9a-z] 0 to 9或a to z范围中一个字符
[0-9[a-z]] 0 to 9或a to z范围中一个字符(同上),并集
[a-z&&[^bc]] a-z除去b和c中的任意一个,&&是交集,同:[ad-z]
[^a-z] 不在a to z范围中的任意一个字符
(9) () 表示一个组,其中的文字表示一个单位。前面的 + | $ ^ * 都可以用这个表示组来限定范围
(z|f)ood zood或food
do(es) do或does
(10) | 前后两者取一
J|A J或A
Java|Hello Java或Hello
z|food z或food
(z|f)ood zood或food
(11) {} 限制为连续出现指定次数字符
J{2} JJ
J{3} JJJ
J{3,} JJJ,JJJJ,JJJJJ,???(3次以上J并存)
J{3,5} JJJ或JJJJ或JJJJJ
(12) ? 匹配前面表达式0次或一次
非贪婪模式匹配
ja? j或者ja
do(es)? do或does
四、 量词
----------------------------------------------------------------------------
a? 可以匹配空字符串“” 可以匹配“a”串两次(一次是a 一次是结尾空串) 可以匹配“aaa”四次(三个a和一个结尾空串) 可以匹配“aaabab”七次(单独的a四次,非a处(b)匹配两次,结尾空串一次)
a* 可以匹配空字符串“” 可以匹配“a”串两次(一次是a 一次是结尾空串) 可以匹配“aaa”两次(一个aaa和一个结尾空串)可以匹配“aaabab”五次(aaa一次,a一次,非a处(b)匹配两次,结尾空串一次)
a+ 只能匹配多个“a”的串
a{3} 匹配“aaa”一次 匹配“aaaaa”一次 匹配“aaaaaa”两次(aaa和aaa)
a{3,} 匹配“aaaaaa”一次
a{3,6} 匹配“aaaaaaaaa”两次(一次aaaaaa,一次aaa)
abc+ 匹配“abc”,“abcc”,“abcccc...” 量词仅仅可能附在一个字符后面一次(此处依附的是c)
[abc]+ 匹配的是一个以上的abc中的字符组成的串
(abc)+ 匹配的是一个以上的abc串 如abc, abcabcabc
五、贪婪式、勉强式、侵占式
----------------------------------------------------------------------------
<.*> 贪婪式 匹配了 <abbbb>
(1)首先吞掉整个字符串, < 匹配 < ,然后.*匹配abbb>,发现无法匹配 > 之后,回退一个字符(>)
(2)此时可以匹配
从后向前回退
<.*?> 勉强式 匹配了 <abbbb>
首先 < 匹配 < ,吞掉a,吞掉b,吞掉b,吞掉b,发现 > 可以匹配
从前向后吞并
<.*+> 侵占式 无法匹配 <abbbb>
首先 < 匹配 < ,然后.*匹配abbb>,发现无法匹配 > 之后,不回退,直接汇报无法匹配
一次匹配结束
对于待匹配串 xfooxxxxxxfoo
.*foo 贪婪式 (1)吞掉整个串,不匹配 (2)回退一个o,不匹配
(3)回退一个o,不匹配 (4)回退一个f,匹配 xfooxxxxxxfoo
.*?foo 勉强式 (1)匹配x,匹配foo (2)继续,匹配xxxxxx,匹配foo
.*+foo 侵占式 吞掉所有串,无法匹配foo,不回退,匹配失败
六、捕捉组
----------------------------------------------------------------------------
反向引用:在正则表达式中,反向引用使用反斜线(\)后跟一个表示需要再调用组号的数字来表示。
例如,表达式(\d\d)定义了匹配一行中的两个数字的捕获组,通过反向引用\1,表达式稍候会被再次调用。
(\d\d)\1 匹配1212,而不能匹配1234 两组数字相同
七、边界匹配
----------------------------------------------------------------------------
反向引用:在正则表达式中,反向引用使用反斜线(\)后跟一个表示需要再调用组号的数字来表示。
例如,表达式(\d\d)定义了匹配一行中的两个数字的捕获组,通过反向引用\1,表达式稍候会被再次调用。
(\d\d)\1 匹配1212,而不能匹配1234 两组数字相同
八、Pattern类的方法
----------------------------------------------------------------------------
(1)关于complain方法的第二个参数(整数)(可用位操作符|表示并列)
举例:pattern = Pattern.compile("[az]$", Pattern.MULTILINE | Pattern.UNIX_LINES)
|-----------------------------------|-------------------|------------------------------------------------|
| 使用标志构建模式 | 内嵌标志表达式 | 意义 |
|-----------------------------------|-------------------|-------------------------------------------------|
| Pattern.CASE_INSENSITIVE | 等价于(?i) | 不区分大小写 |
| Pattern.COMMENTS | 等价于(?x) | 忽略空白和以#开始的直到行尾的内嵌注释 |
| Pattern.DOTALL | 等价于(?s) | 表达式.匹配包括行结束符在内的任意字符 |
|-----------------------------------|--------------------|------------------------------------------------|
(2)matches方法返回boolean方法
Pattern.matches("\\d","1")
(3)matcher方法返回Matcher类对象
Pattern.matcher("待匹配字串")
(4)split(方法
Pattern pattern1 = Pattern.compile("[, |]");
String[] strs = pattern1.split("Java Hello World Java,Hello,,World|Sun");
九、Matcher类的方法
----------------------------------------------------------------------------
(1)索引方法
start() 匹配索引开始
start(int group) 组匹配索引开始
end() 匹配索引结束
end(int group) 组匹配索引结束
(2)研究方法
matches() boolean b= matcher.matches() 将整个匹配串与正则进行匹配的boolean值
find方法,查找下一个匹配的字符串序列,相当于rs.next
while (matcher.find()){System.out.printf(matcher.group(), matcher.start(), matcher.end() );}
find(int index) 从索引处开始
lookingAt() 与matches不同,这个从头匹配,有即可。
(3)替换方法
replaceFirst方法替换一个, matcher.replaceFirst(String s);
replaceAll方法替换所有匹配(参数是替换串) matcher.replaceAll(String s);
str.replaceAll(regex, repl)方法与使用 Pattern.compile(regex).matcher(str).replaceAll(repl)
十、参考
http://www.java3z.com/cwbwebhome/article/article8/Regex/Java.Regex.Tutorial.html