You are on page 1of 66

中关 村国际 软件 人才 教育联


第二十五讲

正则表 达式
中关村国际软件人才教育联盟

这些是什 么?
 “[0-9A-Za-z]+@([0-9a-zA-
Z]+.){1,2}(com|net|cn|
com.cn)”
 “[\u4e00-\u9fa5]”
 “http://([\w-]+\.)+[\w-]+(/[\w-
./?%&=]*)?”
 “1\\d{2}”

2
中关村国际软件人才教育联盟

目标

 正则表达式的概 念
 正则表达式的基 本语法
 在 Java 中使用正则 表达式
 常用正则表达式

3
中关村国际软件人才教育联盟

正则 表达式 的概 念
 正则表达式 (regular expression) 是由
普通字符(例如字符 a 到 z )以及特
殊字符(称为元字符)组成的文字模式。
正则表达式作为一个模板,将某个字符模
式与所搜索的字符串进行匹配

4
中关村国际软件人才教育联盟

正则表 达式 的组成 部分
11-1
 普通字符
– 由所有那些未显式指定为元字符的打印和非打印字符
组成。这包括所有的大写和小写字母字符、所有数字
、所有标点符号以及一些符号
 非打印 字符
– \f 匹配一个换页符
– \n 匹配一个换行符
– \r 匹配一个回车符
– \s 匹配任何空白字符,包括空格、制表符、换页
符等等
– \S 匹配任何非空白字符
– \t 匹配一个制表符
– \v 匹配一个垂直制表符
5
中关村国际软件人才教育联盟

正则表 达式 的组成 部分
11-2
 特殊字 符
– 所谓特殊字符,就是一些有特殊含义的字符
– 特殊字符 说明
– $ 匹配输入字符串的结尾位置
– () 标记一个子表达式的开始和结束位置。子表达
式可以获取供以后使用
– * 匹配前面的子表达式 0 次或多次
– + 匹配前面的子表达式 1 次或多次
– . 匹配除换行符 \n 之外的任何单字符
– [ 标记一个中括号表达式的开始
– ? 匹配前面的子表达式 0 次或 1 次

6
中关村国际软件人才教育联盟

正则表 达式 的组成 部分
11-3
– 特殊字符 说明
– \ 将下一个字符标记为或特殊字符、或原义
字符、或向后引用、或八进制转义符。例如, ‘
n’ 匹配字符 ‘ n‘ ,而 '\n' 匹配换行符。序列
'\\' 匹配 "\" ,而 '\(' 则匹配 "("
– ^ 匹配输入字符串的开始位置,除非在方括
号表达式中使用,此时它表示不接受该字符集合
– { 标记限定符表达式的开始
– | 指明两项之间的一个选择

7
中关村国际软件人才教育联盟

正则表 达式 的组成 部分
11-4
 限定 符
– 限定符用来指定正则表达式的一个给定组件必须要
出现多少次才能满足匹配。共 6 种:
– 限定符 说明
– * 匹配前面的子表达式 0 次或多次
– + 匹配前面的子表达式 1 次或多次
– ? 匹配前面的子表达式 0 次或 1 次
– {n} n 是一个非负整数。匹配确定的 n 次
– {n,} n 是一个非负整数。至少匹配 n 次
– {n,m} m 和 n 均为非负整数,其中 n <=
m 。最少匹配 n 次且最多匹配 m 次。注意在逗
号和两个数之间不能有空格
8
中关村国际软件人才教育联盟

正则表 达式 的组成 部分
11-5
 定位符
– 用来描述字符串或单词的边界, ^ 和 $ 分别指
字符串的开始字符与结束字符
– 不能对定位符使用限定符
 选择
– 用圆括号 () 将所有选择项括起来,相邻的选择
项之间用 | 分隔

9
中关村国际软件人才教育联盟

正则表 达式 的组成 部分
11-6
 其它
– (pattern) 匹配 pattern 并获取这一匹配。
所获取的匹配可以从产生的 Matches 集合得到
– (?:pattern) 匹配 pattern 但不获取匹配结果
,也就是说这是一个非获取匹配,不进行存储供
以后使用。这在使用 " 或 " 字符 (|) 来组合一
个模式的各个部分是很有用。例如,
'industr(?:y|ies) 就是一个比 'industry|
industries' 更简略的表达式

10
中关村国际软件人才教育联盟

正则表 达式 的组成 部分
11-7
– (?=pattern) 正向预查,在任何匹
配 pattern 的字符串开始处匹配查找字
符串。这是一个非获取匹配,也就是说,
该匹配不需要获取供以后使用。例
如, 'Windows (?=95|98|NT|2000)'
能匹配 "Windows 2000" 中的
"Windows" ,但不能匹配 "Windows
3.1" 中的 "Windows" 。当找到一个匹
配后,从 Windows 后面开始进行下一次
的检索匹配
11
中关村国际软件人才教育联盟

正则表 达式 的组成 部分
11-8
– (?!pattern) 负向预查,在任何不
匹配 pattern 的字符串开始处匹配查找
字符串。这是一个非获取匹配,也就是说
,该匹配不需要获取供以后使用。例如‘
Windows (?!95|98|NT|2000)’ 能匹配
“ Windows 3.1” 中的
“ Windows” ,但不能匹配
“ Windows 2000” 中的
“ Windows” 。当找到一个匹配后,从
Windows 后面开始进行下一次的检索匹
配 12
中关村国际软件人才教育联盟

正则表 达式 的组成 部分
11-9
– \xn 匹配 n ,其中 n 为十六进制转义值。
十六进制转义值必须为确定的两个数字长。例
如, '\x41' 匹配 "A" 。 '\x041' 则等价于
'\x04' & "1" 。正则表达式中可以使用 ASCII
编码
– \num 匹配 num ,其中 num 是一个正整数。
对所获取的匹配的引用。例如,‘ (.)\1’ 匹配两
个连续的相同字符
– \un 匹配 n ,其中 n 是一个用四个十六进
制数字表示的 Unicode 字符。例如, \u00A9
匹配版权符号 (?)

13
中关村国际软件人才教育联盟

正则表 达式 的组 成部分
11-10
 JavaScript 中的正则表达式
– 格式: /pattern/flags
– 参数说明:
 pattern -- 一个正则表达式文本
 flags -- 如果存在,将是以下值:
g: 全局匹配
i: 忽略大小写进行匹配
gi: 以上组合
– 例如:
– /perl/  找到含有  perl  的字符串
– /abc/i  找寻符合  abc  的字符串而且不考虑这
些字符串的大小写
– /[^\u4E00-\u9FA5]/g 只能是中文字符

14
中关村国际软件人才教育联盟

正则表达 式的 组成部 分
11-11
 各种操作符的运算优先级
– 相同优先级的从左到右进行运算,不同优先级的运算
先高后低。各种操作符的优先级从高到低如下:
– 操作符 描述
– \ 转义符
– (), (?:), (?=), [] 圆括号和方括号
– *, +, ?, {n}, {n,}, {n,m} 限定符
– ^, $ 位置和顺序
– | “ 或”操作

15
中关村国际软件人才教育联盟

正则表 达式 匹配规 则 15-


1
 基本模式匹配
– ^once 表示该模式只匹配那些以 once 开
头的字符串。例如该模式与字符串“ once
upon a time” 匹配,与“ There once
was a man from NewYork” 不匹配
– bucket$ 表示该模式只匹配那些以
bucket 结尾的字符串。例如这个模式
与 "Who kept all of this cash in a
bucket" 匹配,与 "buckets" 不匹配

16
中关村国际软件人才教育联盟

正则表 达式 匹配规 则 15-


2
– 字符 ^ 和 $ 同时使用时,表示精确匹配(字符
串与模式一样)。例如: ^bucket$ 只
匹配字符串 "bucket“
– 如果一个模式不包括 ^ 和 $ ,那么它与任何包
含该模式的字符串匹配。例如:模式 once
与字符串 There once was a man from
NewYork Who kept all of his cash in a
bucket. 是匹配的。 在该模式中的字母 (o-n-
c-e) 是字面的字符,也就是说,他们表示该字
母本身,数字也是一样的
17
中关村国际软件人才教育联盟

正则表 达式 匹配规 则 15-


3
– 其他一些稍微复杂的字符,如标点符号和空
格、制表符等,要用到转义序列。所有的转
义序列都用反斜杠 (\) 打头。制表符的转义序
列是: \t 。所以如果我们要检测一个字符串
是否以制表符开头,可以用这个模式:
^\t 。类似的,用 \n 表示“新行”, \r 表示
回车。其它的特殊符号,可以在前面加上反
斜杠,如反斜杠本身用 \\ 表示,句号 . 用 \.
表示,以此类推

18
中关村国际软件人才教育联盟

正则表 达式 匹配规 则 15-


4
 句点符号 .
– 匹配除换行符 \n 之外的任何单字符

19
中关村国际软件人才教育联盟

正则表 达式 匹配规 则 15-


5
 方括号符号
– 为了解决句点符号匹配范围过于广泛这一问题,
你可以在方括号(“ []” )里面指定字符。此时
,只有方括号里面指定的字符才参与匹配。也就
是说,正则表达式“ t[aeio]n” 只匹配“ tan” 、
“ Ten” 、“ tin” 和“ ton” ,但“ Toon” 不匹
配,因为在方括号之内你只能匹配单个字符

20
中关村国际软件人才教育联盟

正则表 达式 匹配规 则 15-


6
 “ 或”符号
– 如果除了上面匹配的所有单词之外,你还想要匹
配“ toon” ,那么,你可以使用“ |” 操作符。“
|” 操作符的基本意义就是“或”运算。要匹配“
toon” ,使用“ t(a|e|i|o|oo)n” 正则表达式。这
里不能使用方括号,因为方括号只允许匹配单个
字符;这里必须使用圆括号“ ()”

21
中关村国际软件人才教育联盟

正则表 达式 匹配规 则 15-


7
 表示匹配次数的符号
– 表一显示了表示匹配次数的符号,这些符号用来确
定紧靠该符号左边的内容出现的次数:

22
中关村国际软件人才教育联盟

正则表 达式 匹配规 则 15-


8
– 假设我们要在文本文件中搜索美国的社会安全号码。
这个号码的格式是 999-99-9999 。用来匹配它的
正则表达式如图一所示。在正则表达式中,连字符
(“ -” )有着特殊的意义,它表示一个范围,比如
从 0 到 9 。因此,匹配社会安全号码中的连字符号
时,它的前面要加上一个转义字符“ \”

23
中关村国际软件人才教育联盟

正则表 达式 匹配规 则 15-


9
– 假设进行搜索的时候,你希望连字符号出现
,也可以不出现——即, 999-99-9999 和
999999999 都属于正确的格式。这时,你
可以在连字符号后面加上“?”数量限定符
号,如图二所示:

24
中关村国际软件人才教育联盟

正则表 达式 匹配规 则 15-


10
– 下面我们再来看另外一个例子。美国汽车牌
照的一种格式是四个数字加上二个字母。它
的正则表达式前面是数字部分“ [0-
9]{4}” ,再加上字母部分“ [A-Z]{2}” 。
图三显示了完整的正则表达式

25
中关村国际软件人才教育联盟

正则表 达式 匹配规 则 15-


11
 “ 否”符号
– “^” 符号称为“否”符号。如果用在方括号
内,“ ^” 表示不想要匹配的字符。例如,图
四的正则表达式匹配所有单词,但以“ X” 字
母开头的单词除外

26
中关村国际软件人才教育联盟

正则表 达式 匹配规 则 15-


12
 圆括号和空白符号
– 假设要从格式为“ June 26, 1951” 的生日
日期中提取出月份部分,用来匹配该日期的
正则表达式可以如图五所示:

27
中关村国际软件人才教育联盟

正则表 达式 匹配规 则 15-


13
– 新出现的“ \s” 符号是空白符号,匹配所有的
空白字符,包括 Tab 字符。如果字符串正确
匹配,如何提取出月份部分呢?只需在月份
周围加上圆括号创建一个组,然后用正则 API
提取出它的值。修改后的正则表达式六所示

28
中关村国际软件人才教育联盟

正则表 达式 匹配规 则 15-


14
 其它符号
– 为简便起见,你可以使用一些为常见正则
表达式创建的快捷符号。如表二所示:

29
中关村国际软件人才教育联盟

正则表 达式 匹配规 则 15-


15
– 例如,在前面社会安全号码的例子中,所有
出现“ [0-9]” 的地方我们都可以使
用“ \d” 。修改后的正则表达式如图七所示

30
中关村国际软件人才教育联盟

Java 正则 表达式 API 18-


1
 java.util.regex 是一个用正则表 达
式所订制的模式 来对字符串 进行匹
配工作的类库包 。它包括两 个类:
Pattern 和 Matcher
– Pattern 一个 Pattern 是一个 正则
表达式 经编译 后的 表现模 式
– Matcher 一个 Matcher 对象 把
Pattern 对象做 为匹配 模式 对给定 的字
符串进 行匹配 检查
31
中关村国际软件人才教育联盟

Java 正则 表达式 API 18-


2
 Pattern 类
– Pattern 的方法 如下 :
– static Pattern compile(String regex)
将给定的 正则表达式编 译到模式中
– static Pattern compile(String regex, int
flags)
同上,但 增加 flag 参数 的指定,可 选的 flag 参数包括
: CASE INSENSITIVE,MULTILINE,DOTALL,UNICODE
CASE , CANON EQ
– int flags()
返回当前 Pattern 的匹配 flag 参数
– Matcher matcher(CharSequence input)
创建匹配 给定输入与此 模式的匹配 器

32
中关村国际软件人才教育联盟

Java 正则 表达式 API 18-


3
– static boolean matches(String regex,
CharSequence input)
编译给定 的正则表达式 并且对输入 的字串以该 正则表达
式为模式 进行匹配 , 该方法 适合于该正则 表达式只会 使
用一次的 情况,也就是 只进行一次 匹配工作, 因为这种
情况下并 不需要生成一 个 Matcher 实例
– String pattern()
返回该 Pattern 对象所 编译的正则 表达式
– String[] split(CharSequence input)
将目标字 符串按照 Pattern 里所包 含的正则表达 式为
模式进行 分割
– String[] split(CharSequence input, int limit)
作用同上 ,增加参数 limit 目的 在于要指定 分割的段 数
,如将 limi 设为 2 ,那么目标 字符串将根 据正则表达
式分为割 为两段
33
中关村国际软件人才教育联盟

Java 正则 表达式 API 18-


4
 示例:
– import java.util.regex.*;
– public class Replacement{
– public static void main(String[] args) throws
Exception {
– // 生成一个 Pattern, 同时 编译一 个正 则表达 式
– Pattern p = Pattern.compile("[/]+");

– // 用 Pattern 的 split() 方法 把字 符串 按“ /” 分割
– String[] result = p.split( "Kevin has
seen 《 LEON 》 seveal times,because it is a good
film." +"/ 凯文已 经看 过《这 个杀 手不太 冷》 几次了 ,因为 它
是一 部 " +" 好电影。 / 名词 : 凯文。 ");
– for (int i=0; i<result.length; i++)
– System.out.println(result[i]);
– }
– }
34
中关村国际软件人才教育联盟

Java 正则 表达式 API 18-


5
– 输出结果 为:
 Kevin has seen 《 LEON 》 seveal times,because
it is a good film.
 凯文已 经看 过《 这个杀 手不 太冷》 几次了 ,因 为它是 一部
好电影 。
 名词 : 凯文。
– 将程序改 动为:
 tring[] result = p.split("Kevin has
seen 《 LEON 》 seveal times,because it is a
good film./ 凯文 已经看 过《 这个杀 手不 太冷》 几次了
,因为 它是 一部 好电影 。 / 名词 : 凯文。 " , 2);
 这里面 的参 数 "2" 表明 将目标 语句 分为 两段
– 输出结果 则为:
 Kevin has seen 《 LEON 》 seveal times,because
it is a good film.
 凯文已 经看 过《 这个杀 手不 太冷》 几次了 ,因 为它是 一部
好电影 。 / 名词 : 凯文 。

35
中关村国际软件人才教育联盟

Java 正则 表达式 API 18-


6
 Matcher 类
– Matcher 方法 如下:
– Matcher appendReplacement(StringBuffer sb,
String replacement)
将当 前匹配 子串 替换为 指定 字符串 ,并且 将替 换后的 子串 以
及其 之前到 上次 匹配子 串之 后的字 符串段 添加 到一个
StringBuffer 对象里
– StringBuffer appendTail(StringBuffer sb)
将最 后一次 匹配 工作后 剩余 的字符 串添加 到一 个
StringBuffer 对象里
– int end()
返回 当前匹 配的 子串的 最后 一个字 符在原 目标 字符串 中的 索
引位 置
– int end(int group)
返回 与匹配 模式 里指定 的组 相匹配 的子串 最后 一个字 符的 位

– boolean find()
尝试 在目标 字符 串里查 找下 一个匹 配子串
36
中关村国际软件人才教育联盟

Java 正则 表达式 API 18-


7
– Pattern pattern()
返回 该 Matcher 对象的现 有匹 配模式 ,也 就是对 应的
Pattern 对象
– String replaceAll(String replacement)
将目 标字 符串里 与既 有模式 相匹 配的子 串全部 替换 为指定 的
字符 串
– String replaceFirst(String replacement)
将目 标字 符串里 第一 个与既 有模 式相匹 配的子 串替 换为指 定
的字 符串
– Matcher reset()
重设 该 Matcher 对象
– Matcher reset(CharSequence input)
重设 该 Matcher 对象并且 指定 一个新 的目 标字符 串
– int start()
返回 当前 查找所 获子 串的开 始字 符在原 目标字 符串 中的位 置
– int start(int group)
返回 当前 查找所 获得 的和指 定组 匹配的 子串的 第一 个字符 在
原目 标字 符串中 的位 置

37
中关村国际软件人才教育联盟

Java 正则 表达式 API 18-


8
 一个 Matcher 实例是被用 来对目标
字符串进行基于 既有模式( 也就是
一个给定的 Pattern 所编 译的正则
表达式)进行匹 配查找的, 所有往
Matcher 的输入都是 通过
CharSequence 接口提供的

38
中关村国际软件人才教育联盟

Java 正则 表达式 API 18-


9
 matches()/lookingAt ()/find() :
– 一个 Matcher 对象是 由一 个 Pattern 对象
调用其 matcher() 方法而 生成的 ,一 旦该
Matcher 对象生 成 , 它就可 以进行 三种 不同
的匹配 查找 操作:
– matches() 方法尝 试对 整个目 标字符 展开 匹
配检测 ,也 就是只 有整 个目 标字符 串完 全匹配
时才返 回 true
– lookingAt () 方法 将检 测目标 字符 串是否 以
匹配的 子串 起始
– find() 方法尝 试在 目标字 符串 里查 找下一 个
匹配子 串
– 以上三 个方 法都将 返回 一个 布尔值 来表 明成功
与否
39
中关村国际软件人才教育联盟

Java 正则 表达式 API 18-


10
 replaceAll ()
/appendReplacement()/appen
dTail() :
– Matcher 类同 时提供 了四 个将匹 配子
串替换 成指定 字符 串的方 法:
– replaceAll()
– replaceFirst()
– appendReplacement()
– appendTail()
40
中关村国际软件人才教育联盟

Java 正则 表达式 API 18-


11
– boolean find(int start)
重设 Matcher 对象, 并且尝试 在目标字符 串里从指定
的位置开 始查找下一个 匹配的子串
– String group()
返回当前 查找而获得的 与组匹配的 所有子串内 容
– String group(int group)
返回当前 查找而获得的 与指定的组 匹配的子串 内容
– int groupCount()
返回当前 查找所获得的 匹配组的数 量
– boolean lookingAt()
检测目标 字符串是否以 匹配的子串 起始
– boolean matches()
尝试对整 个目标字符展 开匹配检测 ,也就是只 有整个目
标字符串 完全匹配时才 返回真值

41
中关村国际软件人才教育联盟

Java 正则 表达式 API 18-


12
 appendReplacement(StringBuffer
sb, String replacement)
– 将当前匹 配子串替换为 指定字符串 ,并且将替 换后的子
串以及其 之前到上次匹 配子串之后 的字符串段 添加到一
个 StringBuffer 对象里, 而
appendTail(StringBuffer sb) 方法 则将最后一 次
匹配工作 后剩余的字符 串添加到一 个 StringBuffer 对
象里。
– 例如,有 字符串 fatcatfatcatfat, 假设既 有正则表达
式模式为 "cat" ,第一次匹 配后调用
appendReplacement(sb,"dog"), 那么这 时
StringBuffer sb 的内容 为 fatdog ,也就是 fatcat
中的 cat 被替换 为 dog 并且与 匹配子串前的 内容加到
sb 里,而第二次匹 配后调用
appendReplacement(sb,"dog") ,那么 sb 的内容
就变为 fatdogfatdog ,如果最后 再调用一次 42
中关村国际软件人才教育联盟

Java 正则 表达式 API 18-


13
 // 该例将 把句子 里的 "Kelvin" 改为 "Kevin“
 import java.util.regex.*;
 public class MatcherTest{
– public static void main(String[] args) throws
Exception {
– // 生成 Pattern 对象并且编 译一个简单 的正则表达
式 "Kelvin“
– Pattern p = Pattern.compile("Kevin");
– // 用 Pattern 类的 matcher() 方法生 成一个
Matcher 对象
– Matcher m = p.matcher("Kelvin Li and Kelvin
Chan are both working in Kelvin Chen's
KelvinSoftShop company");
– StringBuffer sb = new StringBuffer();
– int i=0;
– // 使用 find() 方法 查找第一个 匹配的对 象
43
中关村国际软件人才教育联盟

Java 正则 表达式 API 18-


14
– // 使用 循环将 句子 里所有 的 kelvin 找出并替 换再 将内容 加到
sb 里
– while(result) {
– i++;
– m.appendReplacement(sb, "Kevin");
– System.out.println(" 第 "+i+" 次匹配后 sb 的内容
是: "+sb);
– // 继续查 找下 一个匹 配对 象
– result = m.find();
– }
– // 最后调 用 appendTail() 方法 将最 后一次 匹配 后的剩 余字
符串 加到 sb 里;
– m.appendTail(sb);
– System.out.println(" 调用 m.appendTail(sb) 后 sb
的最 终内 容是 :"+ sb.toString());
– }
 }
44
中关村国际软件人才教育联盟

Java 正则 表达式 API 18-


15
 最终输 出结果 为:
– 第 1 次匹 配后 sb 的内容是 : Kevin
– 第 2 次匹 配后 sb 的内容是 : Kevin Li and
Kevin
– 第 3 次匹 配后 sb 的内容是 : Kevin Li and
Kevin Chan are both working in Kevin
– 第 4 次匹 配后 sb 的内容是 : Kevin Li and
Kevin Chan are both working in Kevin
Chen's Kevin
– 调用 m.appendTail(sb) 后 sb 的最终 内容
是: Kevin Li and Kevin Chan are both
working in Kevin Chen's
KevinSoftShop company.
45
中关村国际软件人才教育联盟

Java 正则 表达式 API 18-


16
 group()/group(int
group)/groupCount() :
– 这些方 法都是 要返 回与组 匹配 的子串 内
容,下 面代码 将很 好解释 其用 法:

46
中关村国际软件人才教育联盟

Java 正则 表达式 API 18-


17
 import java.util.regex.*;
 public class GroupTest{
– public static void main(String[] args) throws
Exception {
– Pattern p = Pattern.compile("(ca)(t)");
– Matcher m = p.matcher("one cat,two cats in the
yard");
– StringBuffer sb = new StringBuffer();
– boolean result = m.find();
– System.out.println(" 该次查 找获 得匹配 组的 数量
为: "+m.groupCount());
– for(int i=1;i<=m.groupCount();i++){
– System.out.println(" 第 "+i+" 组的 子串内 容为 :
"+m.group(i));
– }
– }
 }
47
中关村国际软件人才教育联盟

Java 正则 表达式 API 18-


18
 输出为:
– 该次查 找获得 匹配 组的数 量为 : 2
– 第 1 组的子 串内 容为: ca
– 第 2 组的子 串内 容为: t

48
中关村国际软件人才教育联盟

检验 Email 地址的 小程 序
4-1
 import java.util.regex.*;
 public class Email {
– public static void main(String[] args) throws
Exception {
– String input = args[0];
– // 检测输 入的 EMAIL 地址是 否以 非法 符号 “ .” 或“ @” 作为
起始 字符
– Pattern p = Pattern.compile("^\\.|^\\@");
– Matcher m = p.matcher(input);
– if (m.find()){
– System.err.println("EMAIL 地址不能 以 '.' 或 '@' 作为起
始字 符 ");
– }
– // 检测是否 以“ www.” 为起 始
– p = Pattern.compile("^www\\.");
– m = p.matcher(input);
– if (m.find()) {
– System.out.println("EMAIL 地址不 能以 'www.' 起始 "); 49
中关村国际软件人才教育联盟

检验 Email 地址的 小程 序
4-2
– // 检测是 否包含非法 字符
– p = Pattern.compile("[^A-Za-z0-9\\.\\@_\\-
~#]+");
– m = p.matcher(input);
– StringBuffer sb = new StringBuffer();
– boolean result = m.find();
– boolean deletedIllegalChars = false;
– while(result) {
– // 如果 找到了非法 字符那么 就设下标记
– deletedIllegalChars = true;
– // 如果 里面包含非 法字符如 冒号双引号 等,那么就
把他们消 去,加到 SB 里面
– m.appendReplacement(sb, "");
– result = m.find();
– }
50
中关村国际软件人才教育联盟

检验 Email 地址的 小程 序
4-3
– m.appendTail(sb);
– input = sb.toString();
– if (deletedIllegalChars) {
– System.out.println(" 输入的 EMAIL 地
址里包 含有 冒号、 逗号 等非 法字符 ,请 修
改 ");
– System.out.println(" 您现在的 输入 为 :
"+args[0]); System.out.println(" 修改后
合法的 地址 应类似 : "+input);
– }
– }
 }

51
中关村国际软件人才教育联盟

检验 Email 地址的 小程 序
4-4
 例如 ,我 们在命令 行输入: java Email
www.kevin@163.net ,那么输 出结 果将会 是:
– EMAIL 地址不 能以 'www.' 起始
 如果 输入 的 EMAIL 为 @kevin@163.net ,则输
出为 :
– EMAIL 地址不 能以 '.' 或 '@' 作为起 始字符
 当输 入为 : cgjmail#$%@163.net ,那么输 出
是:
– 输入的 EMAIL 地址里包 含有冒号、 逗号等非法字 符,请
修改
– 您现在的 输入为 : cgjmail#$%@163.net 修改后合法
的地址应 类似 : cgjmail@163.net

52
中关村国际软件人才教育联盟

正则 表达式 应用 3-1
 检查邮政编码
 boolean checkPostcode(){
– Pattern p=Pattern.compile("[0-9]{6}");
– Matcher m=p.matcher(inputStr);
– if (!m.matches()){
– System.out.println("**** 邮政编码格式不符!
*****");
– return false;
– }
– return true;
 }
 “[0-9]{6}” 的意思:一个 [] 只能允许匹配单个字符。
0-9 表示 0 到 9 之间的任意数字, {} 大括号表示匹
配次数,这里就表示匹配 6 次,即必须有 6 个数字
53
中关村国际软件人才教育联盟

正则 表达式 应用 3-2
 检查 EMAIL
 boolean checkEmail(){
– Pattern p=Pattern.compile("[0-9A-Za-
z]+@([0-9a-zA-Z]+.){1,2}(com|net|cn|
com.cn)");
– Matcher m=p.matcher(inputStr);
– if(!m.matches()){
– System.out.println("**** 电子邮件格式不符
! *****");
– return false;
– }
– return true;
 } 54
中关村国际软件人才教育联盟

正则 表达式 应用 3-3
 检查 IP 地址
 boolean ipValid(String s) {
– String regex0="(2[0-4]\\d)" + "|(25[0-5])";
– String regex1="1\\d{2}";
– String regex2="[1-9]\\d";
– String regex3="\\d";
– String regex= "("+regex0+")|("+regex1+")|
("+regex2+")|("+regex3+")";
regex="("+regex+").("+regex+").("+regex+").("+r
egex+")";
– Pattern p=Pattern.compile(regex);
– Matcher m=p.matcher(s);
– return m.matches();
 }
55
中关村国际软件人才教育联盟

常用 正则表 达式 10-1
 验证日期格式为 YYYY-MM-DD 的正则表达
式为:
– (([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-
9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-
(((0[13578]|1[02])-(0[1-9]|[12][0-9]|
3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|
(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-
9]{2})(0[48]|[2468][048]|[13579][26])|
((0[48]|[2468][048]|[3579][26])00))-02-29)

56
中关村国际软件人才教育联盟

常用 正则表 达式 10-2
 验证日期格式为 DD/MM/YYYY 的正则表达
式为:
– (((0[1-9]|[12][0-9]|3[01])/((0[13578]|
1[02]))|((0[1-9]|[12][0-9]|30)/(0[469]|11))|
(0[1-9]|[1][0-9]|2[0-8])/(02))/([0-9]{3}[1-
9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-
9]{2}|[1-9][0-9]{3}))|(29/02/(([0-
9]{2})(0[48]|[2468][048]|[13579][26])|
((0[48]|[2468][048]|[3579][26])00)))

57
中关村国际软件人才教育联盟

常用 正则表 达式 10-3
 匹配中文字符的正则表达式: [\u4e00-
\u9fa5]
 匹配双字节字符 ( 包括汉字在内 ) : [^\x00-
\xff]
 应用:计算字符串的长度(一个双字节字符长
度计 2 , ASCII 字符计 1 )
– String.prototype.len=function(){return
this.replace([^\x00-\xff]/g,"aa").length;}

 匹配空行的正则表达式: \n[\s| ]*\r


 匹配 HTML 标记的正则表达式:
58
中关村国际软件人才教育联盟

常用 正则表 达式 10-4
 匹配首尾空格的正则表达式: (^\s*)|(\s*$)
 应用: javascript 中没有像 vbscript 那样
的 trim 函数,我们就可以利用这个表达式来
实现,如下: String.prototype.trim =
function() { return this.replace(/(^\s*)|
(\s*$)/g, ""); }

 匹配 Email 地址的正则表达式: \w+([-


+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
 匹配网址 URL 的正则表达式: http://([\w-]
+\.)+[\w-]+(/[\w- ./?%&=]*)?
59
中关村国际软件人才教育联盟

常用 正则表 达式 10-5
 利用正则表达式去除字串中重复的字符的算
法程序:
– var s="abacabefgeeii"
– var s1=s.replace(/(.).*\1/g,"$1")
– var re=new RegExp("["+s1+"]","g")
– var s2=s.replace(re,"")
– alert(s1+s2) // 结果为: abcefgi
– 思路是使用后向引用取出包括重复的字符,再以
重复的字符建立第二个表达式,取到不重复的字
符,两者串连。这个方法对于字符顺序有要求的
字符串可能不适用

60
中关村国际软件人才教育联盟

常用 正则表 达式 10-6
 利用正则表达式从 URL 地址中提取文
件名的 javascript 程序如下,结果为
page1
– s=http://www.9499.net/page1.htm

s=s.replace(/(.*\/){0,}([^\.]+).*/ig,"$
2")
– alert(s)

61
中关村国际软件人才教育联盟

常用 正则表 达式 10-7
 利用正则表达式限制网页表单里的文本
框输入内容:
 用正则表达式限制只能输入中文:
– onkeyup="value=value.replace(/[^\
u4E00-\u9FA5]/g,'')“
– onbeforepaste="clipboardData.setD
ata('text',clipboardData.getData('tex
t').replace(/[^\u4E00-\u9FA5]/g,''))"

62
中关村国际软件人才教育联盟

常用 正则表 达式 10-8
 用正则表达式限制只能输入全角字符:
– onkeyup="value=value.replace(/[^\
uFF00-\uFFFF]/g,'')“
– onbeforepaste="clipboardData.setD
ata('text',clipboardData.getData('tex
t').replace(/[^\uFF00-\uFFFF]/g,''))"

63
中关村国际软件人才教育联盟

常用 正则表 达式 10-9
 用正则表达式限制只能输入数字:
– onkeyup="value=value.replace(/[^\
d]/g,'')“
– onbeforepaste="clipboardData.setD
ata('text',clipboardData.getData('tex
t').replace(/[^\d]/g,''))"

64
中关村国际软件人才教育联盟

常用 正则表 达式 10-10
 用正则表达式限制只能输入数字和英文

– onkeyup="value=value.replace(/[\W
]/g,'') “
– onbeforepaste="clipboardData.setD
ata('text',clipboardData.getData('tex
t').replace(/[^\d]/g,''))"

65
中关村国际软件人才教育联盟

小结

66

You might also like