Chinaunix首页 | 论坛 | 博客
  • 博客访问: 26312198
  • 博文数量: 2065
  • 博客积分: 10377
  • 博客等级: 上将
  • 技术积分: 21525
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-04 17:50
文章分类

全部博文(2065)

文章存档

2012年(2)

2011年(19)

2010年(1160)

2009年(969)

2008年(153)

分类: Java

2008-11-28 19:04:40

正则表达式”(Regular Expression)就是一个字符构成的串,它定义了一个用来搜索匹配字符串的模式。
语法: 最简单的形式就是去寻找一个或一段字符.它使用一些特殊的字符,如[*], 表示任意形式的字符串. [.]表示任意单个字符串.
jdk中正则表达式的相关的包和类:
java.util.regex.Pattern: 建立匹配模型
java.util.regex.Matcher: 匹配器
使用这两个类的步骤:
1.编译你的正则表达式到Pattern的实例中.
2.使用Pattern对象创建Matcher对象.
3.使用Matcher对象去控制或操纵这个字符序列.
a98b   c0912d   c10b   a12345678d   ab
    我们仔细分析上面五个字符串,可以看出它们有一个共同特征,就是第一个字符必须是'a'或'c',最后一个字符必须是'b'或'd',而中间的字符是任意 多个数字组成(包括0个数字)。因此,我们可以将这五个字符串的共同特点抽象出来,这就产生了一个正则表达式:[ac]\\d*[bd]。而根据这个正则 表达式,我们可以写出无穷多个满足条件的字符串。
[因为只要打头的为ac结尾的为bd中间只要是数字就可以这样的话是可以产生无穷多个满足条件的字符串的哦]
1.在String中有四个方法可以使用正则表达式,它们是matches、split、replaceAll和replaceFirst。
一、matches方法
 
matches方法可以判断当前的字符串是否匹配给定的正则表达式。如果匹配,返回true,否则,返回false。matches方法的定义如下:

public boolean matches(String regex)
  
  如上面给出的正则表达式我们可以用如下程序验证。
 
String[] ss = new String[]{"a98b""c0912d",  "c10b",  "a12345678d",  "ab"};
for(String s: ss)
    System.out.println(s.matches(
"[ac]\\d*[bd]"));

输出结果:
true
true
true
true
true
正则表达式为[ac]\\d*[bd]
只需要与这个进行匹配就可以了哦!
二、split方法
 
split方法使用正则表达式来分割字符串,并以String数组的形式返回分割结果。split有两种重载形式,它们定义如下:
 
public String[] split(String regex)
public String[] split(String regex, int limit)

    如下面的代码将使用split的第一种重载形式来分割HTTP请求头的第一行,代码如下:
 
String s = "GET /index.html HTTP/1.1";
String ss[] 
= s.split(" +");
for(String str: ss)
System.out.println(str);

输出结果:
GET
/index.html
HTTP/1.1
三、replaceAll 和 replaceFirst方法
 
为两个方法的定义如下:
public String replaceAll(String regex, String replacement)
public String replaceFirst(String regex, String replacement)

[正则表达式中的匹配模式]
\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] 非数字与英文字 
^ 表示每行的开头
$ 表示每行的结尾
                                 java正则表达式初步

正则表达式的使用:
设有正则表达式: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。块名列表        








阅读(1237) | 评论(0) | 转发(0) |
0

上一篇:ASP实例学习一

下一篇:JAVA正则表达式二

给主人留下些什么吧!~~