正则表达式的学习
闲来无事,学习一下正则表达式(regular expression)其实我挺不喜欢这个翻译的,regular翻译成正则,读起来就不太舒服,还不如规则表达式,一看就知道是怎么一回事。
言归正传,正则表达式(regular expression)就是用一个“字符串”来描述一个特征,然后去验证另一个“字符串”是否符合这个特征。比如 表达式“ab+” 描述的特征是“一个 'a' 和 任意个 'b' ”,那么 'ab', 'abb', 'abbbbbbbbbb' 都符合这个特征,说到这里似乎想起来,好像编译原理里面也提到过,只不过早已忘记了,还是学习的不扎实啊。
正则表达式的历史可以追溯到1956年的一位数学家研究神经网络时发表的一篇论文。想想这样的论文才叫论文嘛,造福后代。
正则表达式可以用来:(1)验证字符串是否符合指定特征,比如验证是否是合法的邮件地址。(2)用来查找字符串,从一个长的文本中查找符合指定特征的字符串,比查找固定字符串更加灵活方便。(3)用来替换,比普通的替换更强大,其实这点在我们常用的编辑器就可以发现,大多的文本编辑器都应用了正则表达式。
开始我们的正则表达式的“Hello World”吧。这里采用jdk1.5+
jakarta-oro-2.0.1
(
apaache
的一个包)。目的是找到一个
ipv4
的地址。
package
regularExp;
import
org.apache.oro.text.regex.MalformedPatternException;
import
org.apache.oro.text.regex.Pattern;
import
org.apache.oro.text.regex.PatternCompiler;
import
org.apache.oro.text.regex.PatternMatcher;
import
org.apache.oro.text.regex.Perl5Compiler;
import
org.apache.oro.text.regex.Perl5Matcher;
/*
*
正则表达式的测试类
*/
public
class
TestRegular
{
/**
*
@param
args
*/
public
static
void
main(String[] args)
{
PatternCompiler patternCompiler=
new
Perl5Compiler();
//In general, different regular expression compilers will produce
//different types of pattern representations,so we use the interface
Pattern ipv4Pattern=
null
;
try
{
String ipv4Exp=
"\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"
;
ipv4Pattern=patternCompiler.compile(ipv4Exp);
}
catch
(MalformedPatternException e)
{
e.printStackTrace();
}
//
通过
PatternMatcher
类用该
Pattern
对象进行模式匹配。
PatternMatcher patternMatcher=
new
Perl5Matcher();
boolean
isMatch=patternMatcher.contains(
"hfgh-192.168.111.255g2"
, ipv4Pattern);
if
(isMatch)
System.
out
.println(
"The match result is:"
+patternMatcher.getMatch());
}
}
输出结果如下:
The match result is:192.168.111.255
Jdk
在
1.4
也加入了java.util.regex,正式对正则表达式的支持,再看看在jdk1.4中怎么使用。(MatchResult 在1.5中)
String ipv4Exp=
"\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"
;
Pattern pattern = Pattern.compile(ipv4Exp);
Matcher matcher = pattern.matcher(
"hfgh-192.168.111.255g2"
);
if
(matcher.find())
System.
out
.println(
"The match result is:"
+matcher.toMatchResult().group());
有了一个直观的入门后,我们再仔细学习一下正则表达式的语法。网上有一些很不错的文章,
copy
一下。
文章中的每一个举例,都可以点击进入到测试页面进行测试。闲话少说,开始。
1.
正则表达式规则
1.1
普通字符
字母、数字、汉字、下划线、以及后边章节中没有特殊定义的标点符号,都是
"
普通字符
"
。表达式中的普通字符,在匹配一个字符串的时候,匹配与之相同的一个字符。
举例1:表达式 "c",在匹配字符串 "abcde" 时 ,匹配结果是:成功;匹配到的内容是: "c" ;匹配到的位置是:开始于 2 ,结束于 3 。(注:下标从 0 开始还是从 1 开始,因当前编程语言的不同而可能不同)
举例2:表达式 "bcd",在匹配字符串 "abcde" 时 ,匹配结果是:成功;匹配到的内容是: "bcd" ;匹配到的位置是:开始于 1 ,结束于 4 。
举例1:表达式 "c",在匹配字符串 "abcde" 时 ,匹配结果是:成功;匹配到的内容是: "c" ;匹配到的位置是:开始于 2 ,结束于 3 。(注:下标从 0 开始还是从 1 开始,因当前编程语言的不同而可能不同)
举例2:表达式 "bcd",在匹配字符串 "abcde" 时 ,匹配结果是:成功;匹配到的内容是: "bcd" ;匹配到的位置是:开始于 1 ,结束于 4 。
1.2
简单的转义字符
一些不便书写的字符,采用在前面加
"\"
的方法。这些字符其实我们都已经熟知了。
表达式
|
可匹配
|
\r, \n
|
代表回车和换行符
|
\t
|
制表符
|
\\
|
代表
"\"
本身
|
还有其他一些在后边章节中有特殊用处的标点符号,在前面加
"\"
后,就代表该符号本身。比如:
^, $
都有特殊意义,如果要想匹配字符串中
"^"
和
"$"
字符,则表达式就需要写成
"\^"
和
"\$"
。
表达式
|
可匹配
|
\^
|
匹配
^
符号本身
|
\$
|
匹配
$
符号本身
|
\.
|
匹配小数点(
.
)本身
|
这些转义字符的匹配方法与
"
普通字符
"
是类似的。也是匹配与之相同的一个字符。
举例1:表达式 "\$d",在匹配字符串 "abc$de" 时 ,匹配结果是:成功;匹配到的内容是: "$d" ;匹配到的位置是:开始于 3 ,结束于 5 。
举例1:表达式 "\$d",在匹配字符串 "abc$de" 时 ,匹配结果是:成功;匹配到的内容是: "$d" ;匹配到的位置是:开始于 3 ,结束于 5 。
1.3
能够与
'
多种字符
'
匹配的表达式
正则表达式中的一些表示方法,可以匹配
'
多种字符
'
其中的任意一个字符。比如,表达式
"\d"
可以匹配任意一个数字。虽然可以匹配其中任意字符,但是只能是一个,不是多个。这就好比玩扑克牌时候,大小王可以代替任意一张牌,但是只能代替一张牌。
表达式
|
可匹配
|
\d
|
任意一个数字,
0~9
中的任意一个
|
\w
|
任意一个字母或数字或下划线,也就是
A~Z,a~z,0~9,_
中任意一个
|
\s
|
包括空格、制表符、换页符等空白字符的其中任意一个
|
.
|
小数点可以匹配除了换行符(
\n
)以外的任意一个字符
|
举例1:表达式 "\d\d",在匹配 "abc123" 时
,匹配的结果是:成功;匹配到的内容是:
"12"
;匹配到的位置是:开始于
3
,结束于
5
。
举例2:表达式 "a.\d",在匹配 "aaa100" 时 ,匹配的结果是:成功;匹配到的内容是: "aa1" ;匹配到的位置是:开始于 1 ,结束于 4 。
举例2:表达式 "a.\d",在匹配 "aaa100" 时 ,匹配的结果是:成功;匹配到的内容是: "aa1" ;匹配到的位置是:开始于 1 ,结束于 4 。
1.4
自定义能够匹配
'
多种字符
'
的表达式
使用方括号
[ ]
包含一系列字符,能够匹配其中任意一个字符。用
[^ ]
包含一系列字符,则能够匹配其中字符之外的任意一个字符。同样的道理,虽然可以匹配其中任意一个,但是只能是一个,不是多个。
表达式
|
可匹配
|
[ab5@]
|
匹配
"a"
或
"b"
或
"5"
或
"@"
|
[^abc]
|
匹配
"a","b","c"
之外的任意一个字符
|
[f-k]
|
匹配
"f"~"k"
之间的任意一个字母
|
[^A-F0-3]
|
匹配
"A"~"F","0"~"3"
之外的任意一个字符
|
举例1:表达式 "[bcd][bcd]" 匹配 "abc123" 时
,匹配的结果是:成功;匹配到的内容是:
"bc"
;匹配到的位置是:开始于
1
,结束于
3
。
举例2:表达式 "[^abc]" 匹配 "abc123" 时 ,匹配的结果是:成功;匹配到的内容是: "1" ;匹配到的位置是:开始于 3 ,结束于 4 。
举例2:表达式 "[^abc]" 匹配 "abc123" 时 ,匹配的结果是:成功;匹配到的内容是: "1" ;匹配到的位置是:开始于 3 ,结束于 4 。
1.5
修饰匹配次数的特殊符号
前面章节中讲到的表达式,无论是只能匹配一种字符的表达式,还是可以匹配多种字符其中任意一个的表达式,都只能匹配一次。如果使用表达式再加上修饰匹配次数的特殊符号,那么不用重复书写表达式就可以重复匹配。
使用方法是: " 次数修饰 " 放在 " 被修饰的表达式 " 后边。比如: "[bcd][bcd]" 可以写成 "[bcd]{2}" 。
使用方法是: " 次数修饰 " 放在 " 被修饰的表达式 " 后边。比如: "[bcd][bcd]" 可以写成 "[bcd]{2}" 。
表达式
|
作用
|
{n}
| |
{m,n}
| |
{m,}
| |
?
| |
+
| |
*
|
举例1:表达式 "\d+\.?\d*" 在匹配 "It costs $12.5" 时
,匹配的结果是:成功;匹配到的内容是:
"12.5"
;匹配到的位置是:开始于
10
,结束于
14
。
举例2:表达式 "go{2,8}gle" 在匹配 "Ads by goooooogle" 时 ,匹配的结果是:成功;匹配到的内容是: "goooooogle" ;匹配到的位置是:开始于 7 ,结束于 17 。
举例2:表达式 "go{2,8}gle" 在匹配 "Ads by goooooogle" 时 ,匹配的结果是:成功;匹配到的内容是: "goooooogle" ;匹配到的位置是:开始于 7 ,结束于 17 。
1.6
其他一些代表抽象意义的特殊符号
一些符号在表达式中代表抽象的特殊意义:
表达式
|
作用
|
^
|
与字符串开始的地方匹配,不匹配任何字符
|
$
|
与字符串结束的地方匹配,不匹配任何字符
|
\b
|