正则表达式

正则表达式

在计算理论或编译原理中曾经论述过用正则文法来做词法分析,所以正则文法具备表达任何字符串的能力。正则表达式的表达能力和正则文法相当,对于任何一类字符串描述,都可以用正则表达式表达。在实际的编程中,我们通常会遇到字符串匹配、过滤等操作,而这种操作往往可以通过正则表达式来解决;而一般常用的语言都会提供相应的语言库API来支持正则表达式,如Javajava.util.regex包下的Matcher类和Pattern类;以及对正则表达式具有全面支持和优化过的Jakarta-ORO库。

正则表达式的构成

首先,我们来看一下正则表达式中字符的种类,在《编译原理》这门课中提到字符可以分成普通字符和元字符(metacharacter)两种。正则表达式中的元字符包括:^, $, ?, *, +, (, ), {, }, [, ], \, ., 等等,这些元字符或其组合具有特殊的含义,详见下述。那如何表示这些元字符表示的普通字符呢?比如,我需要一个正则表达式以‘?’开始,应该如何表示呢?是这样吗:^?[.]*;显然不是,正确的表示方法应该为:^\?[.]*,正则表达式采用反斜杠来进行转义,反斜杠后面跟元字符可以获得元字符对应的普通字符,如\\, \*, ...;反斜杠后面跟部分普通字符可以获得一些不可表示的字符,如\n, \t, \s, \S...

^:以开头 $:以结尾

例:^s.*a$è以s开头,以a结尾的字符串

?:重复0次或1 *:重复0次或多次 +:重复1次及1次以上

例:a[cd]?可以匹配:a, ac, ad

{n}:重复n {m , n}:重复m~n {m}:重复m次以上

[] []中包含一系列字符,但只能匹配其中的任意一个,[]中所有特殊字符都将失去其特殊含义

正则表达式[]中,’-’有着特殊的意义,表示一个范围,对于’-’字符,需转义’\-’,在[]外则不需要转义

’[]’中,’^’表示不想匹配的字符

():在被修饰匹配次数的时候,括号中的表达式可以作为整体被修饰

如:(abc)+è用于匹配abc, abcabc, abcabcabc…

abc+è用于匹配abc, abcc, abccc…

取匹配结果的时候,括号中的表达式匹配到的内容可以被单独得到(见示例)

\s:匹配所有空白字符,包括Tab字符

\S:匹配所有非空白字符[^\t\n\r\f]

\w: [a-zA-Z0-9]

\d:[0-9]

\D:[^0-9]

综上所述,我们发现正则表达式足以表示任意的字符串,元字符的类型可以分成以下几类:

边界标识:^, $

选择(switch):| , [] , [ - ] , [^ ]

重复(while):?, *, +, {m, n}

跟元字符(正则表达式中最重要的元字符):\

表示字符类别的方法有[ ] , \d, \D, \s, \S, \w, \W

还有需要注意的就是在字符类别[ ]内,元字符将失去意义而变成普通字符(^除外,^表示非的意思),还有就是 '-' 在[ ]内表示范围,在[ ]外表示普通字符

Java正则表达式

对于java中的正则表达式,需要注意的一点是’\’的使用,在java的正则表达式中,表示’\’需要使用”\\\\”,因为java中表示’\’需要使用’\\’’\’java中为转义字符(如回车表示为’\r’,换行表示为’\n’,反斜杠表示为’\\’,制表符表示为’\t’),所以当java读到字符串”\\\\”时,将其解释为’\\’作为正则表达式的输入,而在正则表达式中,’\’同样为转义字符,所以其表示反斜杠需要使用’\\’,因此对于java中的字符串”\\\\”,最终被解释为’\’。而对于正则表达式中的’\w’’\d’’\D’’\s’’\S’等表达式,在java中需写为’\\w’’\\d’’\\D’’\\s’’\\S’.

示例

importorg.apache.oro.text.regex.MalformedPatternException;

importorg.apache.oro.text.regex.MatchResult;

importorg.apache.oro.text.regex.Pattern;

importorg.apache.oro.text.regex.PatternCompiler;

importorg.apache.oro.text.regex.PatternMatcher;

importorg.apache.oro.text.regex.Perl5Compiler;

importorg.apache.oro.text.regex.Perl5Matcher;

publicclassRegularExpression {

/**

*@paramargs

*/

publicstaticvoidmain(String[] args) {

//TODOAuto-generated method stub

PatternCompiler compiler =newPerl5Compiler();

try{

Pattern pattern = compiler.compile("(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})\\s-\\s-\\s\\[([^\\]]+)\\]");

String logEntry ="10.214.10.192 - - [2/Dec/1012 : 16:48:05 - 0500]\"GET /IsAlive.htm HTTP/1.0\"200 15";

PatternMatcher matcher =newPerl5Matcher();

if(matcher.contains(logEntry, pattern)){

MatchResult result = matcher.getMatch();

System.out.println("IP: "+ result.group(1));

System.out.println("TimeStamp: "+ result.group(2));

}

Pattern pattern1 = compiler.compile(".[a\\-z^]?");

String str1 ="a^";

System.out.println(matcher.matches(str1, pattern1));

}catch(MalformedPatternExceptione) {

//TODOAuto-generated catch block

e.printStackTrace();

}

}

}

输出结果为:

IP: 10.214.10.192

TimeStamp: 2/Dec/1012 : 16:48:05 - 0500

true

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值