将很久以前进行页面解析工作时,收集的正则表达式相关帖子进行了整理,便于日后查看。
一。JAVA 正则表达式4种基本的用途
正则表达式在字符串处理上有着强大的功能,sun在jdk1.4加入了对它的支持
1.查询:
以下是代码片段:
String str="abc efg ABC";
String regEx="a|f"; //表示a或f
Pattern p=Pattern.compile(regEx);
Matcher m=p.matcher(str);
boolean rs=m.find();
如果str中有regEx,那么rs为true,否则为flase。如果想在查找时忽略大小写,则可以写成Pattern p=Pattern.compile(regEx,Pattern.CASE_INSENSITIVE);
ps:查找的效率问题待确认
2.提取:
以下是代码片段:
String regEx=".+\(.+)$";//正则表达式
String str="c:\dir1\dir2\name.txt";//待分析字符串
Pattern p=Pattern.compile(regEx);
Matcher m=p.matcher(str);
boolean rs=m.find();
for(int i=1;i<=m.groupCount();i++)
{
System.out.println(m.group(i));
}
以上的执行结果为name.txt,提取的字符串储存在m.group(i)中,其中i最大值为m.groupCount();
3.分割:
以下是代码片段:
String regEx="::";
Pattern p=Pattern.compile(regEx);
String[] r=p.split("xd::abc::cde");
执行后,r就是{"xd","abc","cde"},其实分割时还有跟简单的方法(可以代替StringTokenizer进行更为复杂的切分):
String str="xd::abc::cde";
String[] r=str.split("::");
4.替换(删除):
以下是代码片段:
String regEx="a+"; //表示一个或多个a
Pattern p=Pattern.compile(regEx);
Matcher m=p.matcher("aaabbced a ccdeaa");
String s=m.replaceAll("A");
结果为"Abbced A ccdeA"
如果写成空串,既可达到删除的功能,比如:
String s=m.replaceAll("");
结果为"bbced ccde"
二。 JAVA 正则表达式的解释说明
1.字符
- x 字符 x。例如a表示字符a
- \\ 反斜线字符。在书写时要写为\\\\ 。(注意:因为java在第一次解析时,把\\\\ 解析成正则表达式\\,在第二次解析时再解析为\,所以凡是不是1.1列举到的转义字符,包括1.1的\\,而又带有\的都要写两次)
- \0n 带有八进制值 0的字符 n (0 <= n <= 7)
- \0nn 带有八进制值 0的字符 nn (0 <= n <= 7)
- \0mnn 带有八进制值 0的字符 mnn(0 <= m <= 3、0 <= n <= 7)
- \xhh 带有十六进制值 0x的字符 hh
- \uhhhh 带有十六进制值 0x的字符 hhhh
- \t 制表符 ('\u0009')
- \n 新行(换行)符 ('\u000A')
- \r 回车符 ('\u000D')
- \f 换页符 ('\u000C')
- \a 报警 (bell) 符 ('\u0007')
- \e 转义符 ('\u001B')
- \cx 对应于 x 的控制符
2.字符类
- [abc] a、b或 c(简单类)。例如[egd]表示包含有字符e、g或d。
- [^abc] 任何字符,除了 a、b或 c(否定)。例如[^egd]表示不包含字符e、g或d。
- [a-zA-Z] a到 z或 A到 Z,两头的字母包括在内(范围)
- [a-d[m-p]] a到 d或 m到 p:[a-dm-p](并集)
- [a-z&&[def]] d、e或 f(交集)
- [a-z&&[^bc]] a到 z,除了 b和 c:[ad-z](减去)
- [a-z&&[^m-p]] a到 z,而非 m到 p:[a-lq-z](减去)
3.预定义字符类 (注意反斜杠要写两次,例如\d写为 \\d ) 任何字符
(与行结束符可能匹配也可能不匹配)
- \d 数字:[0-9]
- \D 非数字: [^0-9]
- \s 空白字符:[ \t\n\x0B\f\r]
- \S 非空白字符:[^\s]
- \w 单词字符:[a-zA-Z_0-9]
- \W 非单词字符:[^\w]
4.POSIX 字符类 (仅 US-ASCII)(注意反斜杠要写两次,例如\p{Lower}写为\\p{Lower})
- \p{Lower} 小写字母字符:[a-z]。
- \p{Upper} 大写字母字符:[A-Z]
- \p{ASCII} 所有 ASCII:[\x00-\x7F]
- \p{Alpha} 字母字符:[\p{Lower}\p{Upper}]
- \p{Digit} 十进制数字:[0-9]
- \p{Alnum} 字母数字字符:[\p{Alpha}\p{Digit}]
- \p{Punct} 标点符号:!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
- \p{Graph} 可见字符:[\p{Alnum}\p{Punct}]
- \p{Print} 可打印字符:[\p{Graph}\x20]
- \p{Blank} 空格或制表符:[ \t]
- \p{Cntrl} 控制字符:[\x00-\x1F\x7F]
- \p{XDigit} 十六进制数字:[0-9a-fA-F]
- \p{Space} 空白字符:[ \t\n\x0B\f\r]
5.java.lang.Character 类 (简单的 java 字符类型)
- \p{javaLowerCase} 等效于 java.lang.Character.isLowerCase()
- \p{javaUpperCase} 等效于 java.lang.Character.isUpperCase()
- \p{javaWhitespace} 等效于 java.lang.Character.isWhitespace()
- \p{javaMirrored} 等效于 java.lang.Character.isMirrored()
6.Unicode 块和类别的类
- \p{InGreek} Greek 块(简单块)中的字符
- \p{Lu} 大写字母(简单类别)
- \p{Sc} 货币符号
- \P{InGreek} 所有字符,Greek 块中的除外(否定)
- [\p{L}&&[^\p{Lu}]] 所有字母,大写字母除外(减去)
7.边界匹配器
- ^ 行的开头,请在正则表达式的开始处使用^。例如:^(abc)表示以abc开头的字符串。注意编译的时候要设置参数MULTILINE,如 Pattern p = Pattern.compile(regex,Pattern.MULTILINE);
- $ 行的结尾,请在正则表达式的结束处使用。例如:(^bca).*(abc$)表示以bca开头以abc结尾的行。
- \b 单词边界。例如\b(abc)表示单词的开始或结束包含有abc,(abcjj、jjabc 都可以匹配)
- \B 非单词边界。例如\B(abc)表示单词的中间包含有abc,(jjabcjj匹配而jjabc、abcjj不匹配)
- \A 输入的开头
- \G 上一个匹配的结尾(个人感觉这个参数没什么用)。例如\\Gdog表示在上一个匹配结尾处查找dog如果没有的话则从开头查找,注意如果开头不是dog则不能匹配。
- \Z 输入的结尾,仅用于最后的结束符(如果有的话)
- 行结束符 是一个或两个字符的序列,标记输入字符序列的行结尾。
- 以下代码被识别为行结束符:
- ‐新行(换行)符 ('\n')、
- ‐后面紧跟新行符的回车符 ("\r\n")、
- ‐单独的回车符 ('\r')、
- ‐下一行字符 ('\u0085')、
- ‐行分隔符 ('\u2028') 或
- ‐段落分隔符 ('\u2029)。
- \z 输入的结尾
- 当编译模式时,可以设置一个或多个标志,例如
- Pattern pattern = Pattern.compile(patternString,Pattern.CASE_INSENSITIVE + Pattern.UNICODE_CASE);
- 下面六个标志都是支持的:
- ‐CASE_INSENSITIVE:匹配字符时与大小写无关,该标志默认只考虑US ASCII字符。
- ‐UNICODE_CASE:当与CASE_INSENSITIVE结合时,使用Unicode字母匹配
- ‐MULTILINE:^和$匹配一行的开始和结尾,而不是整个输入
- ‐UNIX_LINES: 当在多行模式下匹配^和$时,只将'\n'看作行终止符
- ‐DOTALL: 当使用此标志时,.符号匹配包括行终止符在内的所有字符
- ‐CANON_EQ: 考虑Unicode字符的规范等价
8.Greedy 数量词
- X? X,一次或一次也没有
- X* X,零次或多次
- X+ X,一次或多次
- X{n} X,恰好 n 次
- X{n,} X,至少 n 次
- X{n,m} X,至少 n 次,但是不超过 m 次
9.Reluctant 数量词
- X?? X,一次或一次也没有
- X*? X,零次或多次
- X+? X,一次或多次
- X{n}? X,恰好 n 次
- X{n,}? X,至少 n 次
- X{n,m}? X,至少 n 次,但是不超过 m 次
10.Possessive 数量词
- X?+ X,一次或一次也没有
- X*+ X,零次或多次
- X++ X,一次或多次
- X{n}+ X,恰好 n 次
- X{n,}+ X,至少 n 次
- X{n,m}+ X,至少 n 次,但是不超过 m 次
- Greedy,Reluctant,Possessive的区别在于:(注意仅限于进行.等模糊处理时)
- greedy量 词被看作“贪婪的”,因为它第一次就读入整个被模糊匹配的字符串。如果第一个匹配尝试(整个输入字符串)失败,匹配器就会在被匹配字符串中的最后一位后退 一个字符并且再次尝试,重复这个过程,直到找到匹配或者没有更多剩下的字符可以后退为止。根据表达式中使用的量词,它最后试图匹配的内容是1 个或者0个字符。
- 但是,reluctant量词采取相反的方式:它们从被匹配字符串的开头开始,然后逐步地一次读取一个字符搜索匹配。它们最后试图匹配的内容是整个输入字符串。
- 最后,possessive量词总是读完整个输入字符串,尝试一次(而且只有一次)匹配。和greedy量词不同,possessive从不后退。
11.Logical 运算符
- XY X 后跟 Y
- X|Y X 或 Y
- (X) X,作为捕获组。例如(abc)表示把abc作为一个整体进行捕获
12.Back 引用
- \n 任何匹配的 nth捕获组
- 捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C)))中,存在四个这样的组:
- 1 ((A)(B(C)))
- 2 \A
- 3 (B(C))
- 4 (C)
在表达式中可以通过\n来对相应的组进行引用,例如(ab)34\1就表示ab34ab,(ab)34(cd)\1\2就表示ab34cdabcd。
13.引用
- \ Nothing,但是引用以下字符
- \Q Nothing,但是引用所有字符,直到 \E。QE之间的字符串会原封不动的使用(1.1中转义字符的除外)。例如, ab\\Q{|}\\\\E
- 可以匹配ab{|}\\
- \E Nothing,但是结束从 \Q开始的引用
14.特殊构造(非捕获)
- (?:X) X,作为非捕获组
- (?idmsux-idmsux) Nothing,但是将匹配标志由 on 转为 off。比如:表达式 (?i)abc(?-i)def 这时,(?i) 打开不区分大小写开关,abc 匹配
- idmsux说明如下:
- ‐i CASE_INSENSITIVE :US-ASCII 字符集不区分大小写。(?i)
- ‐d UNIX_LINES : 打开UNIX换行符
- ‐m MULTILINE :多行模式(?m)
- UNIX下换行为\n
- WINDOWS下换行为\r\n(?s)
- ‐u UNICODE_CASE : Unicode 不区分大小写。(?u)
- ‐x COMMENTS :可以在pattern里面使用注解,忽略pattern里面的whitespace,以及"#"一直到结尾(#后面为注解)。(?x)例如(?x)abc#asfsdadsa可以匹配字符串abc
- (?idmsux-idmsux:X) X,作为带有给定标志 on - off 的非捕获组。与上面的类似,上面的表达式,可以改写成为:(?i:abc)def,或者 (?i)abc(?-i:def)
- (?=X) X,通过零宽度的正 lookahead。零宽度正先行断言,仅当子表达式 X 在 此位置的右侧匹配时才继续匹配。例如,\w+(?=\d) 表示字母后面跟数字,但不捕获数字(不回溯)
- (?!X) X,通过零宽度的负 lookahead。零宽度负先行断言。仅当子表达式 X 不在 此位置的右侧匹配时才继续匹配。例如,\w+(?!\d) 表示字母后面不跟数字,且不捕获数字。
- (?<=X) X,通过零宽度的正 lookbehind。零宽度正后发断言。仅当子表达式 X 在 此位置的左侧匹配时才继续匹配。例如,(?<=19)99 表示99前面是数字19,但不捕获前面的19。(不回溯)
- (?<!-- x) X,通过零宽度的负 lookbehind。零宽度负后发断言。仅当子表达式 X 不在此位置的左侧匹配时才继续匹配。例如,(?<!19)99 表示99前面不能是19,且不捕获前面的东东。<br /--> (?>X) X,作为独立的非捕获组(不回溯)
- (?=X)与(?>X)的区别在于(?>X)是不回溯的。例如被匹配的字符串为abcm
- 当表达式为a(?:b|bc)m是可以匹配的,而当表达式是a(?>b|bc)时是不能匹配的,因为当后者匹配到b时,由于已经匹配,就跳出了非捕获组,而不再次对组内的字符进行匹配。可以加快速度。
三 。 正则表达式的常用表达式
1.中文、全半角、双字节等
- 匹配中文字符的正则表达式: \[\u4e00-\u9fa5\]
- 匹配双字节字符(包括汉字在内):\[^\x00-\xff\]
- 匹配空行的正则表达式:\n\[\s\| \]*\r
- \un 匹配 n,其中 n 是一个用四个十六进制数字表示的Unicode字符。
2.经典格式匹配
- 匹配HTML标记的正则表达式:/<(.*)>.*</1>\|<(.*) />/
- 匹配首尾空格的正则表达式:(^s*)\|(s*$)
- 匹配Email地址的正则表达式:\w+(\[-+.\]w+)*@w+(\[-.\]w+)*.w+(\[-.\]w+)\*
- 匹配网址URL的正则表达式:^\[a-zA-z\]+://(\\w+(-\\w+)*)(\\.(\\w+(-\\w+)*))*(\\?\\S*)?$
- 匹配网址URL的正则表达式:http://(\[w-\]+.)+\[w-\]+(/\[w\ - ./?%&=\]*)?
- 匹配首尾空格的正则表达式:(^\s*)\|(\s*$)
- 匹配IP地址的正则表达式:"^(d{1,2}\|1dd\|2\[0-4\]d\|25\[0-5\]).(d{1,2}\|1dd\|2\[0-4\]d\|25\[0-5\]).(d{1,2}\|1dd\|2\[0-4\]d\|25\[0-5\]).(d{1,2}\|1dd\|2\[0-4\]d\|25\[0-5\])$"
- 匹配年-月-日的正则表达式:/^(d{2}\|d{4})-((0(\[1-9\]{1}))\|(1\[1\|2\]))-((\[0-2\](\[1-9\]{1}))\|(3\[0\|1\]))$/
- 匹配年/月/日的正则表达式:/^((0(\[1-9\]{1}))\|(1\[1\|2\]))/((\[0-2\](\[1-9\]{1}))\|(3\[0\|1\]))/(d{2}\|d{4})$/
- 匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^\[a-zA-Z\]\[a-zA-Z0-9_\]{4,15}$
- 匹配国内电话号码:(\d{3}-\|\d{4}-)?(\d{8}\|\d{7})?
- 匹配腾讯QQ号:^\[1-9\]*\[1-9\]\[0-9\]*$
3.数字,字符
"^\d+$" //非负整数(正整数 + 0)
"^\[0-9\]*\[1-9\]\[0-9\]*$" //正整数
"^((-\d+)\|(0+))$" //非正整数(负整数 + 0)
"^-\[0-9\]*\[1-9\]\[0-9\]*$" //负整数
"^-?\d+$" //整数
"^\d+(\.\d+)?$" //非负浮点数(正浮点数 + 0)
"^((\[0-9\]+\.\[0-9\]*\[1-9\]\[0-9\]*)\|(\[0-9\]*\[1-9\]\[0-9\]*\.\[0-9\]+)\|(\[0-9\]*\[1-9\]\[0-9\]*))$" //正浮点数
"^((-\d+(\.\d+)?)\|(0+(\.0+)?))$" //非正浮点数(负浮点数 + 0)
"^(-((\[0-9\]+\.\[0-9\]*\[1-9\]\[0-9\]*)\|(\[0-9\]*\[1-9\]\[0-9\]*\.\[0-9\]+)\|(\[0-9\]*\[1-9\]\[0-9\]*)))$" //负浮点数
"^(-?\d+)(\.\d+)?$" //浮点数
"^\[A-Za-z\]+$" //由26个英文字母组成的字符串
"^\[A-Z\]+$" //由26个英文字母的大写组成的字符串
"^\[a-z\]+$" //由26个英文字母的小写组成的字符串
"^\[A-Za-z0-9\]+$" //由数字和26个英文字母组成的字符串
"^\w+$" //由数字、26个英文字母或者下划线组成的字符串
4.javascript中的用法
利用正则表达式限制网页表单里的文本框输入内容1、用正则表达式限制只能输入中文:οnkeyup="value="/value.replace(/\ ["^u4E00-u9FA5\]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/\[^u4E00-u9FA5\]/g,''))"
2、用正则表达式限制只能输入全角字符: οnkeyup="value="/value.replace(/\["^uFF00-uFFFF\]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/\[^uFF00-uFFFF\]/g,''))"
3、用正则表达式限制只能输入数字:οnkeyup="value="/value.replace(/\["^d\]/g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/\[^d\]/g,''))"
4、用正则表达式限制只能输入数字和英文:οnkeyup="value="/value.replace(/\[W\]/g,"'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace
5.正则表达式使用基础说明(与第二部分略有重复)
- 元字符及其在正则表达式上下文中的行为\ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个后向引用、或一个八进制转义符。
^ 匹配输入字符串的开始位置。如果设置了 RegExp 对象的Multiline 属性,\^ 也匹配 '\n' 或 '\r' 之后的位置。
$ 匹配输入字符串的结束位置。如果设置了 RegExp 对象的Multiline 属性,$ 也匹配 '\n' 或 '\r' 之前的位置。
\* 匹配前面的子表达式零次或多次。
+ 匹配前面的子表达式一次或多次。\+ 等价于 {1,}。
? 匹配前面的子表达式零次或一次。? 等价于 {0,1}。 - {n} n 是一个非负整数,匹配确定的n 次。
{n,} n 是一个非负整数,至少匹配n 次。
{n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。在逗号和两个数之间不能有空格。 - ? 当该字符紧跟在任何一个其他限制符 (*, \+, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。
. 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '\[.\n\]' 的模式。 - (pattern) 匹配pattern 并获取这一匹配。
(?:pattern) 匹配pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。
(?=pattern) 正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。
(?\!pattern) 负向预查,与(?=pattern)作用相反 - x\|y 匹配 x 或 y。
\[xyz\] 字符集合。
\[^xyz\] 负值字符集合。
\[a-z\] 字符范围,匹配指定范围内的任意字符。
\[^a-z\] 负值字符范围,匹配任何不在指定范围内的任意字符。 - \b 匹配一个单词边界,也就是指单词和空格间的位置。
\B 匹配非单词边界。
\cx 匹配由x指明的控制字符。
\d 匹配一个数字字符。等价于 \[0-9\]。
\D 匹配一个非数字字符。等价于 \[^0-9\]。
\f 匹配一个换页符。等价于 \x0c 和 \cL。
\n 匹配一个换行符。等价于 \x0a 和 \cJ。
\r 匹配一个回车符。等价于 \x0d 和 \cM。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于\[ \f\n\r\t\v\]。
\S 匹配任何非空白字符。等价于 \[\^ \f\n\r\t\v\]。
\t 匹配一个制表符。等价于 \x09 和 \cI。
\v 匹配一个垂直制表符。等价于 \x0b 和 \cK。
\w 匹配包括下划线的任何单词字符。等价于'\[A-Za-z0-9_\]'。
\W 匹配任何非单词字符。等价于 '\[^A-Za-z0-9_\]'。 - \xn 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。
\num 匹配 num,其中num是一个正整数。对所获取的匹配的引用。
\n 标识一个八进制转义值或一个后向引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为后向引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。
\nm 标识一个八进制转义值或一个后向引用。如果 \nm 之前至少有is preceded by at least nm 个获取得子表达式,则 nm 为后向引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的后向引用。如果前面的条件都不满足,若 n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm。
\nml 如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。
\un 匹配 n,其中 n 是一个用四个十六进制数字表示的Unicode字符。