众所周知,在程序开发中,难免会遇到需要匹配、查找、替换、判断字符串的情况发生,而这些情况有时又比较复杂,如果用纯编码方式解决,往往会浪费程序员的时间及精力。因此,学习及使用正则表达式,便成了解决这一矛盾的主要手段。
大 家都知道,正则表达式是一种可以用于模式匹配和替换的规范,一个正则表达式就是由普通的字符(例如字符a到z)以及特殊字符(元字符)组成的文字模式,它 用以描述在查找文字主体时待匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
自从jdk1.4推出java.util.regex包,就为我们提供了很好的JAVA正则表达式应用平台。
因为正则表达式是一个很庞杂的体系,所以我仅例举些入门的概念,更多的请参阅相关书籍及自行摸索。
\\ |
反斜杠 |
\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] |
\f |
换页符 |
\e |
Escape |
\b |
一个单词的边界 |
\B |
一个非单词的边界 |
\G |
前一个匹配的结束 |
^为限制开头 |
^java |
条件限制为以Java为开头字符 |
$为限制结尾 |
java$ |
条件限制为以java为结尾字符 |
. 条件限制除\n以外任意一个单独字符 |
java.. |
条件限制为java后除换行外任意两个字符 |
加入特定限制条件“[]” |
[a-z] |
条件限制在小写a to z范围中一个字符 |
[A-Z] |
条件限制在大写A to Z范围中一个字符 |
[a-zA-Z] |
条件限制在小写a to z或大写A to Z范围中一个字符 |
[0-9] |
条件限制在小写0 to 9范围中一个字符 |
[0-9a-z] |
条件限制在小写0 to 9或a to z范围中一个字符 |
[0-9[a-z]] |
条件限制在小写0 to 9或a to z范围中一个字符(交集) |
[]中加入^后加再次限制条件“[^]” |
[^a-z] |
条件限制在非小写a to z范围中一个字符 |
[^A-Z] |
条件限制在非大写A to Z范围中一个字符 |
[^a-zA-Z] |
条件限制在非小写a to z或大写A to Z范围中一个字符 |
[^0-9] |
条件限制在非小写0 to 9范围中一个字符 |
[^0-9a-z] |
条件限制在非小写0 to 9或a to z范围中一个字符 |
[^0-9[a-z]] |
条件限制在非小写0 to 9或a to z范围中一个字符(交集) |
在限制条件为特定字符出现0次以上时,可以使用“*” |
J* |
0个以上J |
.* |
0个以上任意字符 |
J.*D |
J与D之间0个以上任意字符 |
在限制条件为特定字符出现1次以上时,可以使用“+” |
J+ |
1个以上J |
.+ |
1个以上任意字符 |
J.+D |
J与D之间1个以上任意字符 |
在限制条件为特定字符出现有0或1次以上时,可以使用“?” |
JA? |
J或者JA出现 |
限制为连续出现指定次数字符“{a}” |
J{2} |
JJ |
J{3} |
JJJ |
文字a个以上,并且“{a,}” |
J{3,} |
JJJ,JJJJ,JJJJJ,???(3次以上J并存) |
文字个以上,b个以下“{a,b}” |
J{3,5} |
JJJ或JJJJ或JJJJJ |
两者取一“|” |
J|A |
J或A |
Java|Hello |
Java或Hello |
“()”中规定一个组合类型
比如,我查询
1 |
< a href=\"index.html\">index</ a > |
中
间的数据,可写作
1 |
< a. *href=\".*\">(.+?)</ a > |
在使用Pattern.compile函数时,可以加入控制正则表达式的匹配行为的参数:
1 |
Pattern
Pattern.compile(String regex, int flag) |
flag的取值范围如下:
Pattern.CANON_EQ |
当且仅当两个字符的”正规分解(canonical decomposition)”都完全相同的情况下,才认定匹配。比如用了这个标志之后,表达式”a\u030A”会匹配”?”。默认情况下,不考虑”规 范相等性(canonical equivalence)”。 |
Pattern.CASE_INSENSITIVE(?i) |
默认情况下,大小写不明感的匹配只适用于US-ASCII字符集。这个标志能让表达式忽略大小写进行匹配。要想对Unicode字符进行大小不明感的匹 配,只要将UNICODE_CASE与这个标志合起来就行了。 |
Pattern.COMMENTS(?x) |
在这种模式下,匹配时会忽略(正则表达式里的)空格字符(译者注:不是指表达式里的”\\s”,而是指表达式里的空格,tab,回车之类)。注释从#开始,一直到这行结束。可以通过嵌入式的标志来启用Unix行模式。 |
Pattern.DOTALL(?s) |
在这种模式下,表达式’.'可以匹配任意字符,包括表示一行的结束符。默认情况下,表达式’.'不匹配行的结束符。 |
Pattern.MULTILINE(?m) |
在这种模式下,’^'和’$'分别匹配一行的开始和结束。此外,’^'仍然匹配字符串的开始,’$'也匹配字符串的结束。默认情况下,这两个表达式仅仅匹配字符串的开始和结束。 |
Pattern.UNICODE_CASE(?u) |
在这个模式下,如果你还启用了CASE_INSENSITIVE标志,那么它会对Unicode字符进行大小写不明感的匹配。默认情况下,大小写不敏感的匹配只适用于US-ASCII字符集。 |
Pattern.UNIX_LINES(?d) |
在这个模式下,只有’\n’才被认作一行的中止,并且与’.',’^',以及’$'进行匹配。 |
抛开空泛的概念,下面写出几个简单的Java正则用例:
-
在字符串包含验证时
2 |
Pattern
pattern = Pattern.compile( "^Java.*" ); |
3 |
Matcher
matcher = pattern.matcher( "Java不是人" ); |
4 |
boolean b=
matcher.matches(); |
-
以多条件分割字符串时
1 |
Pattern
pattern = Pattern.compile( "[,
|]+" ); |
2 |
String[]
strs = pattern.split( "Java
Hello World Java,Hello,,World|Sun" ); |
3 |
for ( int i= 0 ;i<strs.length;i++)
{ |
4 |
System.out.println(strs[i]); |
-
文字替换(首次出现字符)
1 |
Pattern
pattern = Pattern.compile( "正则表达式" ); |
2 |
Matcher
matcher = pattern.matcher( "正则表达式
Hello World,正则表达式 Hello World" ); |
4 |
System.out.println(matcher.replaceFirst( "Java" )); |
-
文字替换(全部)
1 |
Pattern
pattern = Pattern.compile( "正则表达式" ); |
2 |
Matcher
matcher = pattern.matcher( "正则表达式
Hello World,正则表达式 Hello World" ); |
4 |
System.out.println(matcher.replaceAll( "Java" )); |
-
文字替换(置换字符)
1 |
Pattern
pattern = Pattern.compile( "正则表达式" ); |
2 |
Matcher
matcher = pattern.matcher( "正则表达式
Hello World,正则表达式 Hello World " ); |
3 |
StringBuffer
sbr = new StringBuffer(); |
4 |
while (matcher.find())
{ |
5 |
matcher.appendReplacement(sbr, "Java" ); |
7 |
matcher.appendTail(sbr); |
8 |
System.out.println(sbr.toString()); |
-
验证是否为邮箱地址
1 |
String
str= "ceponline@yahoo.com.cn<script
type=" text/javascript"> |
6 |
Pattern
pattern = Pattern.compile( "[\\w\\.\\-]+@([\\w\\-]+\\.)+[\\w\\-]+" ,Pattern.CASE_INSENSITIVE); |
7 |
Matcher
matcher = pattern.matcher(str); |
8 |
System.out.println(matcher.matches()); |
-
去除html标记
1 |
Pattern
pattern = Pattern.compile( "<.+?>" ,
Pattern.DOTALL); |
2 |
Matcher
matcher = pattern.matcher( "<a
href=\"index.html\">主页</a>" ); |
3 |
String
string = matcher.replaceAll( "" ); |
4 |
System.out.println(string); |
-
查找html中对应条件字符串
1 |
Pattern
pattern = Pattern.compile( "href=\"(.+?)\"" ); |
2 |
Matcher
matcher = pattern.matcher( "<a
href=\"index.html\">主页</a>" ); |
4 |
System.out.println(matcher.group( 1 )); |
-
截取http://地址
2 |
Pattern
pattern = Pattern.compile( "(http://|https://){1}[\\w\\.\\-/:]+" ); |
3 |
Matcher
matcher = pattern.matcher( "dsdsds<http://dsds//gfgffdfd>fdf" ); |
4 |
StringBuffer
buffer = new StringBuffer(); |
6 |
buffer.append(matcher.group()); |
8 |
System.out.println(buffer.toString()); |
-
替换指定{}中文字
01 |
String
str = "Java目前的发展史是由{0}年-{1}年" ; |
02 |
String[][]
object={ new String[]{ "\\{0\\}" , "1995" }, new String[]{ "\\{1\\}" , "2007" }}; |
03 |
System.out.println(replace(str,object)); |
05 |
public static String
replace( final String
sourceString,Object[] object) { |
06 |
String
temp=sourceString; |
07 |
for ( int i= 0 ;i<object.length;i++){ |
08 |
String[]
result=(String[])object[i]; |
09 |
Pattern
pattern = Pattern.compile(result[ 0 ]); |
10 |
Matcher
matcher = pattern.matcher(temp); |
11 |
temp=matcher.replaceAll(result[ 1 ]); |
-
以正则条件查询指定目录下文件
02 |
private ArrayList
files = new ArrayList(); |
06 |
private String
_regexp; |
08 |
class MyFileFilter implements FileFilter
{ |
13 |
public boolean accept(File
file) { |
15 |
Pattern
pattern = Pattern.compile(_regexp); |
16 |
Matcher
match = pattern.matcher(file.getName()); |
17 |
return match.matches(); |
18 |
} catch (Exception
e) { |
28 |
FilesAnalyze(String
path,String regexp) { |
29 |
getFileName(path,regexp); |
36 |
private void getFileName(String
path,String regexp) { |
40 |
File
directory = new File(_path); |
41 |
File[]
filesFile = directory.listFiles( new MyFileFilter()); |
42 |
if (filesFile
== null ) return ; |
43 |
for ( int j
= 0 ;
j < filesFile.length; j++) { |
44 |
files.add(filesFile[j]); |
53 |
public void print
(PrintStream out) { |
54 |
Iterator
elements = files.iterator(); |
55 |
while (elements.hasNext())
{ |
56 |
File
file=(File) elements.next(); |
57 |
out.println(file.getPath()); |
61 |
public static void output(String
path,String regexp) { |
62 |
FilesAnalyze
fileGroup1 = new FilesAnalyze(path,regexp); |
63 |
fileGroup1.print(System.out); |
66 |
public static void main
(String[] args) { |
67 |
output( "C:\\" , "[A-z|.]*" ); |
Java正则的功用还有很多,事实上只要是字符处理,就没有正则做不到的事情存在。(当然,正则解释时较耗时间就是了|||……)