随笔-61  评论-159  文章-0  trackbacks-0
        最近深入看struts2的validation校验框架,看到底层的很多的实现都用到正则表达式来实现。其中用得比较多的是两个类,一个是java.util.regex.Matcher和java.util.regex.Pattern
        现在通过例子来说明:
        1、要求查找一段字符串里面相关匹配的字符串,然后根据要求奇偶大小写替换。
        1、1先从不考虑奇偶考虑
程序如下:
1Pattern p = Pattern.compile("hello");
2        Matcher m = p.matcher("hello Hello HELLo HeLLo HelLoworld HellOWORLD dafdasfadsf");
3        
4        while(m.find()){
5            System.out.println(m.group());
6        }

7        System.out.println("----------------");
8        System.out.println(m.replaceAll("HELLO"));
输出如下:
hello
----------------
HELLO Hello HELLo HeLLo HelLoworld HellOWORLD dafdasfadsf

注:只有第一个hello是匹配的,所以打印出来只有一个hello
*在JDK文档中对Pattern的描述是:A compiled representation of a regular expression. 
其中complie( )方法是把里面的字符串"hello"先编译
matcher( )方法就是把要校验的字符串加载进来:

matcher

public Matcher matcher(CharSequence input)
Creates a matcher that will match the given input against this pattern.
Parameters:
input - The character sequence to be matched
Returns:
A new matcher for this pattern

**Matcher在JDK文档里面描述是:

An engine that performs match operations on a character sequence by interpreting a Pattern.

A matcher is created from a pattern by invoking the pattern's matcher method. Once created, a matcher can be used to perform three different kinds of match operations:

注:(英文通俗易懂就不翻译了)
***其中replaceAll方法是替换字符串里面符合“hello”的字符串     
源码为:
 
 1public String replaceAll(String replacement) {
 2        reset();
 3        boolean result = find();
 4        if (result) {
 5            StringBuffer sb = new StringBuffer();
 6            do {
 7                appendReplacement(sb, replacement);
 8                result = find();
 9            }
 while (result);
10            appendTail(sb);
11            return sb.toString();
12        }

13        return text.toString();
14    }
--------------------------------------------------------------------------------------
1、2下面对1、1中实现所有替换所有符合的字符串程序进行重构
源码如下:
 1Pattern p = Pattern.compile("hello",Pattern.CASE_INSENSITIVE);
 2        Matcher m = p.matcher("hello Hello HELLo HeLLo HelLoworld HellOWORLD dafdasfadsf");
 3        StringBuffer sb= new StringBuffer();
 4        int i = 0;
 5        while(m.find())
 6        {
 7            i++;
 8            if(i%2 == 0)
 9            {
10                m.appendReplacement(sb, "hello");
11            }
else{
12                m.appendReplacement(sb, "HELLO");
13            }

14            
15        }

16        m.appendTail(sb);
17        System.out.println(sb);
控制台输出:
HELLO hello HELLO hello HELLOworld helloWORLD dafdasfadsf
第1行中的Pattern.CASE_INSENSITIVE是忽略字母大小写
其中第5----13行加入就奇偶判断
appendReplacement就是把替换后的字符串放进StringBuffer的引用里面
源码为:
 1public Matcher appendReplacement(StringBuffer sb, String replacement) {
 2
 3        // If no match, return error
 4        if (first < 0)
 5            throw new IllegalStateException("No match available");
 6
 7        // Process substitution string to replace group references with groups
 8        int cursor = 0;
 9        String s = replacement;
10        StringBuffer result = new StringBuffer();
11
12        while (cursor < replacement.length()) {
13            char nextChar = replacement.charAt(cursor);
14            if (nextChar == '\\'{
15                cursor++;
16                nextChar = replacement.charAt(cursor);
17                result.append(nextChar);
18                cursor++;
19            }
 else if (nextChar == '$'{
20                // Skip past $
21                cursor++;
22
23                // The first number is always a group
24                int refNum = (int)replacement.charAt(cursor) - '0';
25                if ((refNum < 0)||(refNum > 9))
26                    throw new IllegalArgumentException(
27                        "Illegal group reference");
28                cursor++;
29
30                // Capture the largest legal group string
31                boolean done = false;
32                while (!done) {
33                    if (cursor >= replacement.length()) {
34                        break;
35                    }

36                    int nextDigit = replacement.charAt(cursor) - '0';
37                    if ((nextDigit < 0)||(nextDigit > 9)) // not a number
38                        break;
39                    }

40                    int newRefNum = (refNum * 10+ nextDigit;
41                    if (groupCount() < newRefNum) {
42                        done = true;
43                    }
 else {
44                        refNum = newRefNum;
45                        cursor++;
46                    }

47                }

48
49                // Append group
50                if (group(refNum) != null)
51                    result.append(group(refNum));
52            }
 else {
53                result.append(nextChar);
54                cursor++;
55            }

56        }

57
58        // Append the intervening text
59        sb.append(getSubSequence(lastAppendPosition, first));
60        // Append the match substitution
61        sb.append(result.toString());
62
63        lastAppendPosition = last;
64    return this;
65    }

注:通过在java中使用正则表达式,可以很方便进行字符串校验。
附(例子):邮件格式校验
System.out.println("aa.a-aaa@163.com".matches("[\\w[.-]]+@[\\w[.-]]+\\.[\\w]+"));
等价于以下代码:
Pattern pp = Pattern.compile("[\\w[.-]]+@[\\w[.-]]+\\.[\\w]+");
  Matcher m =pp.matcher("aa.a-aaa@163.com");
  System.out.println(m.matches());

如果符合matches里面的校验规则,则打印出true,否则是false。
matches方法是String里面一个方法,看源码实现
1public boolean matches(String regex) {
2        return Pattern.matches(regex, this);
3    }


1public static boolean matches(String regex, CharSequence input) {
2        Pattern p = Pattern.compile(regex);
3        Matcher m = p.matcher(input);
4        return m.matches();
5    }

总结:深入一些框架的底层,其中很多校验功能都是用到正则表达式,你会发觉使用正则表达式功能很强大。

-------------------------------------------------------------------------------------------------
PS:本博客文章,如果没有注明是有“转”字样,属于本人原创。如果需要转载,务必注明作者文章的详细出处地址,否则不允许转载,多谢合作!
posted on 2008-12-06 23:42 apple0668 阅读(2529) 评论(0)  编辑  收藏 所属分类: java

只有注册用户登录后才能发表评论。


网站导航: