全部博文(2065)
分类: Java
2008-11-28 19:04:40
正则表达式的使用:
设有正则表达式:String regex,字符串:str
1、直接使用String类:
String[] res = str.split(regex);//把字符串str按regex查分成字符串数组
boolean isMathc = str.matches(regex);//str是否匹配正则表达式regex
String res = str.replaceAll(regex."replacement");//把所有符合正则表达式的字串替换成replacement
String res = str.replaceFirst(regex,"replacement");//把第一个符合正则表达式的字串替换成replacement
2、通过Pattern编译,使用Matcher的相关方法
首先对正则表达式进行编译,编译比直接用String类的效率会高一些
Pattern p = Pattern.compile(regex);//用Pattern的静态方法对regex进行编译
Pattern p = Pattern.compile(String regex,int flags);//重载版本,flag可以设置匹配模式,如果设置为CASE_INSENSITIVE,则大小写不敏感
编译之后,可以用Pattern类的一些方法,做一些简单的操作
String[] res = p.split(str);//拆分字符串
String orregex = p.pattern();//返回patter对应的字符串
构造Matcher,用Matcher的方法来处理字符串,功能更加强大
Matcher m = p.matcher(str);//对于给定的字符串str构造Matcher
Matcher的一些常用方法
public boolean matches()//查看是否匹配,找到第一个不匹配的字符就结束,如果调用find,则是从此字符往后调用
public boolean find();//查找子串,每次调用都是从上一次查找或匹配的后面开始找
public Matcher reset();//从开始查找
public boolean lookingAt();//每次都是从头开始找
public int start();
public int end();//如果find方法找到了匹配,用这两个方法返回匹配的起始索引,end返回的是最后匹配的字符的后一个字符的索引
public String group();//返回find找到的匹配的子串
public String replaceAll(String replacement);//把找到的字串替换成replacement
public Matcher appendReplacement(StringBuffer sb,String
replacement);//把匹配的字符串替换为replacement,然后复制到sb里,不匹配的直接复制到sb里,复制到最后一个匹配的就结束
了,往往需要appendTail()来添加最后不匹配的部分
public StringBuffer appendTail(StringBuffer sb);//添加最后不匹配的部分
这几个里面需要注意find方法,调用一次find,会影响mathces和下一次调用find,下次查找匹配是从上一次查找之后。可以使用reset来重新从头开始查找。而lookAt则不会find受影响,每次都是从头开始查找。
分组:
正则表达式可以加小括号来分组,组号分配按小括号分配,第n个左小括号为第n组,可以用group(n),来抓取符合第n组的子串。
public String group(int group);
第0组为整个字符串,组号不能超过组数,否则产生Exception
以下是javaAPI中Pattern类里关于正则表达式的一些常用语法:
Characters
x The character x
\\ The backslash character
如果想表示一个反斜杠,则应该用""
Character classes [一些特殊含义的表达式哦!]
[abc] a, b, or c (simple class)
[^abc] Any character except a, b, or c (negation) //这里的^表示取反,与边界限定符表示开始区别
[a-zA-Z] a through z or A through Z, inclusive (range)
[a-d[m-p]] a through d, or m through p: [a-dm-p] (union)
[a-z&&[def]] d, e, or f (intersection)
[a-z&&[^bc]] a through z, except for b and c: [ad-z] (subtraction)
[a-z&&[^m-p]] a through z, and not m through p: [a-lq-z](subtraction)
Predefined character classes
. Any character (may or may not match line terminators) //任何字符
\d A digit: [0-9]
\D A non-digit: [^0-9]
\s A whitespace character: [ \t\n\x0B\f\r]
\S A non-whitespace character: [^\s]
\w A word character: [a-zA-Z_0-9]
\W A non-word character: [^\w]
大小写字符正好代表的意义相反
POSIX character classes (US-ASCII only)
\p{Lower} A lower-case alphabetic character: [a-z]
\p{Upper} An upper-case alphabetic character:[A-Z]
\p{ASCII} All ASCII:[\x00-\x7F]
\p{Alpha} An alphabetic character:[\p{Lower}\p{Upper}]
\p{Digit} A decimal digit: [0-9]
\p{Alnum} An alphanumeric character:[\p{Alpha}\p{Digit}]
\p{Punct} Punctuation: One of !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
\p{Graph} A visible character: [\p{Alnum}\p{Punct}]
\p{Print} A printable character: [\p{Graph}\x20]
\p{Blank} A space or a tab: [ \t]
\p{Cntrl} A control character: [\x00-\x1F\x7F]
\p{XDigit} A hexadecimal digit: [0-9a-fA-F]
\p{Space} A whitespace character: [ \t\n\x0B\f\r]
这是Uinx标准
Boundary matchers 边界限定符
^ The beginning of a line
$ The end of a line
\b A word boundary
\B A non-word boundary
\A The beginning of the input
\G The end of the previous match
\Z The end of the input but for the final terminator, if any
\z The end of the input
Greedy quantifiers
X? X, once or not at all
X* X, zero or more times
X+ X, one or more times
X{n} X, exactly n times
X{n,} X, at least n times
X{n,m} X, at least n but not more than m times
Reluctant quantifiers
X?? X, once or not at all
X*? X, zero or more times
X+? X, one or more times
X{n}? X, exactly n times
X{n,}? X, at least n times
X{n,m}? X, at least n but not more than m times
Possessive quantifiers
X?+ X, once or not at all
X*+ X, zero or more times
X++ X, one or more times
X{n}+ X, exactly n times
X{n,}+ X, at least n times
X{n,m}+ X, at least n but not more than m times
Greedy quantifiers:默认写法,找最长的匹配,从最大的长度开始找,不匹配减小长度
Reluctant quantifiers:勉强的,不情愿的,找最短的匹配,从最短的开始匹配,不匹配增加长度
Possessive quantifiers:独占的 从最大程度开始匹配,但是不减小长度
几个实例:
空行
"^[\\s&&[^\\n]]*\\n$"
java中读取文件的一行,会把后面的换行给去掉
E-mail
"[\\w[.-]]+@[\\w[.-]]+\\.[\\w]+"
这篇整理的有点敷衍,基本都是粘贴API里的东西,正则表达式是个好东西,而且与语言无关,应该好好理解一下,听说是用自动机实现的,等把形式语言和自动机理论学完之后,自己试着用C++写个正则表达式引擎,一定别忘了。
[如何用JAVA来写正则表达式引擎啊?]
表12-8 正则表达式语法
--------------------------------------------------------------------------------
语法 解释
--------------------------------------------------------------------------------
字符
c 字符c
\unnnn, \xnn, \0n, \0nn, \0nnn 带有十六或八进制值的代码单元
\0n 八进制0n代表的字符(0<=n<=7)
\0nn 八进制0nn代表的字符(0<=n<=7)
\0mnn 八进制0mnn代表的字符(0<=m<=3,0<=n<=7)
\xnn 十六进制 0xnn所代表的字符
\uhhhh 十六进制 0xhhhh所代表的字符
\t, \n, \r, \f, \a, \e 控制字符,依次是制表符,换行符,回车符,换页符,报警符和转义符
\cc 控制字符中出现的相应字符c
--------------------------------------------------------------------------------
字符类
[C1C2. . .] C1、C2……中的任何字符。Ci可以是字符,字符范围(C1-C2)或者字符类。
[^. . .] 字符类的补集
[ . . . && . . .] 两个字符类的交集
--------------------------------------------------------------------------------
预定义字符类
. 除行终止符外的任何字符(如果DOTALL标志置位,则表示任何字符)
\d 数字[0-9]
\D 非数字[^0-9]
\s 空白字符[\t\n\r\f\x0B]
\S 非空白字符
\w 单词字符[a-zA-Z0-9_]
\W 非单词字符
\p{name} 一个指定的字符类,见表12-9
\P{name} 指定字符类的补集
--------------------------------------------------------------------------------
边界匹配符
^ $ 输入的开头和结尾(在多行模式(multiline mode)下是行的开头和结尾)
\b 单词边界
\B 非单词边界
\A 输入的开头
\z 输入的结尾
\Z 除最后行终止符之外的输入结尾
\G 上个匹配的结尾
--------------------------------------------------------------------------------
量词
X? 可选的X(即X可能出现,也可能不出现)
X* X,可以重复0次或多次
X+ X,可以重复1次或多次
X{n} X{n,} X{n,m} X重复n次,至少重复n次,重复n到m次
--------------------------------------------------------------------------------
量词后缀
? 设默认(贪婪)匹配为reluctant匹配
+ 设默认(贪婪)匹配为possessive匹配
--------------------------------------------------------------------------------
集合操作
XY X的匹配后面跟着Y的匹配
X|Y X或Y的匹配
--------------------------------------------------------------------------------
分组
(X) 匹配X并且在一个自动计数的分组中捕获它
\n 与第n个分组的匹配
--------------------------------------------------------------------------------
转义
\c 字符c(必须不是字母)
\Q...\E 逐字地引用...
(?...) 特殊构造,看Pattern类的API
--------------------------------------------------------------------------------
正则表达式的最简单使用是测试一个特殊的字符串是否与之匹配。这里有一个Java写的测试程序。首先从表示正则表达式的字符串构造一个Pattern对象。然后从该模式获得一个Matcher对象,并且调用它的matches()方法:
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(input);
if (matcher.matches()) . . .
表12.9 预定义的字符类名(Predefined Character Class Names)
--------------------------------------------------------------------------------
Lower 小写的ASII字符[a-z]
Upper 大写的ASCII字符[A-Z]
Alpha ASCII字母[A-Za-z]
Digit ASCII 数字 [0-9]
Alnum ASCII 字母或数字[A-Za-z0-9]
Xdigit 十六进制数字[0-9A-Fa-f]
Print or Graph 可打印的ASCII字符[\x21-\x7E]
Punct 非字母或数字ASCII [\p{Print}&&\P{Alnum}]
ASCII 所有ASCII字符 [\x00-\x7F]
Cntrl ASCII控制字符[\x00-\x1F]
Blank 空格符或制表符[ \t]
Space 空白符 [ \t\n\r\f\0x0B]
javaLowerCase 取决于Character.isLowerCase()的小写字符
javaUpperCase 取决于Character.isUpperCase()的大写字符
javaWhitespace 取决于Character.isWhitespace()的空白符
javaMirrored 取决于Character.isMirrored()的Mirrored(?)
InBlock 这里的Block是unicode字符的块名,用空格隔开,比如BasicLatin 或 Mongolian。块名列表