如果你曾经用过Perl或任何其他内建正则表达式支持的语言,你一定知道用正则表达式处理文本和匹配模式是多么简单。如果你不熟悉这个术语,那么“正则表达式”(Regular Expression)就是一个字符构成的串,它定义了一个用来搜索匹配字符串的模式。
许多语言,包括Perl、PHP、Python、JavaScript和JScript,都支持用正则表达式处理文本,一些文本编辑器用正则表达式实现高 级“搜索-替换”功能。那么Java又怎样呢?本文写作时,一个包含了用正则表达式进行文本处理的Java规范需求(Specification Request)已经得到认可,你可以期待在JDK的下一版本中看到它。 |
然而,如果现在就需要使用正则表达式,又该怎么办呢?你可以从Apache.org下载源代码开放的Jakarta-ORO库。本文接下来的内容先简要地介绍正则表达式的入门知识,然后以Jakarta-ORO API为例介绍如何使用正则表达式。 |
我们先从简单的开始。假设你要搜索一个包含字符“cat”的字符串,搜索用的正则表达式就是“cat”。如果搜索对大小写不敏感,单词“catalog”、“Catherine”、“sophisticated”都可以匹配。也就是说: |
假设你在玩英文拼字游戏,想要找出三个字母的单词,而且这些单词必须以“t”字母开头,以“n”字母结束。另外,假设有一本英文字典,你可以用正则表达式 搜索它的全部内容。要构造出这个正则表达式,你可以使用一个通配符--句点符号“.”。这样,完整的表达式就是“t.n”,它匹配“tan”、 “ten”、“tin”和“ton”,还匹配“t#n”、“tpn”甚至“t n”,还有其他许多无意义的组合。这是因为句点符号匹配所有字符,包括空格、Tab字符甚至换行符: |
为了解决句点符号匹配范围过于广泛这一问题,你可以在方括号(“[]”)里面指定看来有意义的字符。此时,只有方括号里面指定的字符才参与匹配。也就是 说,正则表达式“t[aeio]n”只匹配“tan”、“Ten”、“tin”和“ton”。但“Toon”不匹配,因为在方括号之内你只能匹配单个字 符: |
如果除了上面匹配的所有单词之外,你还想要匹配“toon”,那么,你可以使用“|”操作符。“|”操作符的基本意义就是“或”运算。要匹配 “toon”,使用“t(a|e|i|o|oo)n”正则表达式。这里不能使用方扩号,因为方括号只允许匹配单个字符;这里必须使用圆括号“()”。圆括 号还可以用来分组,具体请参见后面介绍。 |
表一显示了表示匹配次数的符号,这些符号用来确定紧靠该符号左边的符号出现的次数: |
假设我们要在文本文件中搜索美国的社会安全号码。这个号码的格式是999-99-9999。用来匹配它的正则表达式如图一所示。在正则表达式中,连字符 (“-”)有着特殊的意义,它表示一个范围,比如从0到9。因此,匹配社会安全号码中的连字符号时,它的前面要加上一个转义字符“/”。 |
图一:匹配所有123-12-1234形式的社会安全号码 |
假设进行搜索的时候,你希望连字符号可以出现,也可以不出现--即,999-99-9999和999999999都属于正确的格式。这时,你可以在连字符号后面加上“?”数量限定符号,如图二所示: |
图二:匹配所有123-12-1234和123121234形式的社会安全号码 |
下面我们再来看另外一个例子。美国汽车牌照的一种格式是四个数字加上二个字母。它的正则表达式前面是数字部分“[0-9]{ 4} ”,再加上字母部分“[A-Z]{ 2} ”。图三显示了完整的正则表达式。 |
“^”符号称为“否”符号。如果用在方括号内,“^”表示不想要匹配的字符。例如,图四的正则表达式匹配所有单词,但以“X”字母开头的单词除外。 |
假设要从格式为“June 26, 1951”的生日日期中提取出月份部分,用来匹配该日期的正则表达式可以如图五所示: |
新出现的“/s”符号是空白符号,匹配所有的空白字符,包括Tab字符。如果字符串正确匹配,接下来如何提取出月份部分呢?只需在月份周围加上一个圆括号创建一个组,然后用ORO API(本文后面详细讨论)提取出它的值。修改后的正则表达式如图六所示: |
图六:匹配所有Month DD,YYYY格式的日期,定义月份值为第一个组 |
为简便起见,你可以使用一些为常见正则表达式创建的快捷符号。如表二所示: |
例如,在前面社会安全号码的例子中,所有出现“[0-9]”的地方我们都可以使用“/d”。修改后的正则表达式如图七所示: |
图七:匹配所有123-12-1234格式的社会安全号码
1. 用户名正则表达式模式
^[a-z0-9_-]{3,15}$
^ # 行开始
[a-z0-9_-] # 匹配列表中的字符,a-z,0–9,下划线,连字符
{3,15} # 长度至少3个字符,最大长度为15
$ # 行结束
2. 密码正则表达式模式
((?=.*/d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%]).{6,20})
( # 组开始
(?=.*/d) # 必须包含一个数字 0-9
(?=.*[a-z]) # 必须包含一个小写字符
(?=.*[A-Z]) # 必须包含一个大写字符
(?=.*[@#$%]) # 必须包含一个列表中的特殊字符"@#$%"
. # 检查所有字符串与前面的条件的匹配
{6,20} # 长度至少为6个字符,最大长度为20
) # 组结束
3. 16进制颜色代码正则表达式模式
^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$
^ # 行开始
# # 必须包含一个"#"符号
( # 组#1开始
[A-Fa-f0-9]{6} # 列表中的任意字符串,长度为6
| # ..或者
[A-Fa-f0-9]{3} # 列表中的任意字符串,长度为3
) # 组#1结束
$ # 行结束
4. Email 正则表达式模式
^[_A-Za-z0-9-]+(//.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(//.[A-Za-z0-9]+)*(//.[A-Za-z]{2,})$
^ # 行开始
[_A-Za-z0-9-]+ # 必须以中括号中的字符为起始字符[],必须包含一个或多个(+)
( # 组#1开始
//.[_A-Za-z0-9-]+ # 接下来是一个点"."和中括号内的字符[],必须包含一个或者多个(+)
)* # 组#1结束, 这个组是可选的(*)
@ # 必须包含一个"@"符号
[A-Za-z0-9]+ # 接下来是中括号内的字符[],必须包含一个或者多个(+)
( # 组 #2开始 – 一级TLD检查
//.[A-Za-z0-9]+ # 接下来是一个点"."和中括号内的字符[],必须包含一个或者多个(+)
)* # 组#2结束,这个组是可选的(*)
( # 组#3开始 – 二级TLD检查
//.[A-Za-z]{2,} # 接下来是一个点"."和中括号内的字符[], 最小长度为2
) # 组#3结束
$ # 行结束
5. 图像文件扩展名正则表达式模式
([^/s]+(/.(?i)(jpg|png|gif|bmp))$)
( # 组#1开始
[^/s]+ # 必须包含一个或更多的任意字符(除了空格)
( # 组#2开始
/. # 接下来是一个点"."
(?i) # 忽略后边字符的大小写检查
( # 组#3开始
jpg # 包含字符"jpg"
| # ..或者
png # 包含字符"png"
| # .. 或者
gif # 包含字符"gif"
| # .. 或者
bmp # 包含字符"bmp"
) # 组#3结束
) # 组#2结束
$ # 字符串的结束
) # 组#1结束
补充一个:[//s//S]*?([^///]*?//.jpg)
6. IP地址正则表达式模式
^([01]?//d//d?|2[0-4]//d|25[0-5])//.([01]?//d//d?|2[0-4]//d|25[0-5])//.
([01]?//d//d?|2[0-4]//d|25[0-5])//.([01]?//d//d?|2[0-4]//d|25[0-5])$
^ # 行开始
( # 组#1开始
[01]?//d//d? # 可以是1到2个数字. 如果出现3个数字, 必须以0或者1开始
# 例如 ([0-9], [0-9][0-9],[0-1][0-9][0-9])
| # ...或者
2[0-4]//d # 以2开始, 紧跟着是0-4,并且以任意数字结尾(2[0-4][0-9])
| # ...或者
25[0-5] # 以2开始, 紧跟着是5,并且以0-5结尾 (25[0-5])
) # 组#1结束
/. # 接下来是点"."
.... # 重复3次 (3x)
$ # 行结束
7. 时间格式正则表达式模式
12-小时制时间正则表达式模式
(1[012]|[1-9]):[0-5][0-9](//s)?(?i)(am|pm)
( # 组#1开始
1[012] # 以10, 11, 12开始
| # 或者
[1-9] # 以1,2,...9开始
) # 组#1结束
: # 接下来是一个冒号 (:)
[0-5][0-9] # 接下来是0..5和0..9,意思是00到59
(//s)? # 接下来是一个空格(可选)
(?i) # 下面的检查不区分大小写
(am|pm) # 接下来是AM或者PM
24小时制时间正则表达式模式
([01]?[0-9]|2[0-3]):[0-5][0-9]
( # 组#1开始
[01]?[0-9] # 以0-9,1-9,00-09,10-19开始
| # 或者
2[0-3] # 以20-23开始
) # 组#1结束
: # 接下来是一个冒号(:)
[0-5][0-9] # 接下来是0..5和0..9,意思是00到59
8. 日期格式 (dd/mm/yyyy) 正则表达式模式
(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)//d//d)
( # 组#1开始
0?[1-9] # 01-09或者1-9
| # ..或者
[12][0-9] # 10-19或者20-29
| # ..或者
3[01] # 30, 31
) # 组#1结束
/ # 接下来是一个"/"
( # 组#2开始
0?[1-9] # 01-09或者1-9
| # ..或者
1[012] # 10,11,12
) # 组#2结束
/ # 接下来是一个"/"
( # 组#3开始
(19|20)//d//d # 19[0-9][0-9]或者20[0-9][0-9]
) # 组#3结束
9. HTML标签正则表达式模式
<("[^"]*"|'[^']*'|[^'">])*>
< # 以"<"标签开始
( # 组#1开始
"[^"]*" # 只允许两个双引号成对出现-"string"
| # ..或者
'[^']*' # 只允许两个单引号成对出现- 'string'
| # ..或者
[^'">] # 不能出现单独的双引号、单引号和">"
) # 组#1结束
* # 0次或多次
> # 以结束标签">"结束
10. HTML链接正则表达式模式
HTML中的A标签正则表达式模式
(?i)<a([^>]+)>(.+?)</a>
( # 组#1开始
?i # 所有的检查区分大小写
) # 组#1结束
<a # 以"<a"开始
( # 组#2开始
[^>]+ # 除了(">")之外的任意字符,至少一个字符
) # 组#2结束
> # 接下来是">"
(.+?) # 匹配所有
</a> # 以"</a>结束
提取HTML链接正则表达式模式
/s*(?i)href/s*=/s*(/"([^"]*/")|'[^']*'|([^'">/s]+));
/s* # 可以以空格开始
(?i) # 所有的检查是区分大小写的
href # 接下来是一个"href"字
/s*=/s* # 等号两边都允许空格,
( # 组#1开始
"([^"]*") # 只允许2个双引号成对出现 - "string"
| # ..或者
'[^']*' # 只允许2个单引号成对出现 - 'string'
| # ..或者
([^'">]+) # 或者不允许出现单独的单引号、双引号和">"
) # 组#1结束
[注:本文来自网上一位网友的博客,见其不错,拿来给大家分享一下]