当前位置:编程学习 > JSP >>

jsp 正则表达式教程

package regex;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* 注意,Matcher才是正则式的主要操作类,它里面包含了抽取替换最重要的方法.Pattern不是主要的类.
* replaceAll用来全部替换.replaceFirst或replaceEnd可以做递归替换.
*
* @author gaoyibo
*
*/
public class RegexAPITest {

    public static final int TITLE_LEN = 50;
    public static final int DESC_LEN = 80;
    // u4e00-u9fa5表示中文,uFF00-uFFFF表示全角 其它表示一些特殊字符.
    public static String regexStr = "{([u4e00-u9fa5A-Za-z0-9'",;.:?!、<>‘“,;。:?!<>:suFF00-uFFFF]*)}";

    public static enum IdeaContentType {
        TITLE, DESC1, DESC2, ACCESS_URL, SHOW_URL
    }

    /**
     * 需求描述:admin中广告搜索,审核日志搜索,行业审核中需要用到替换默认关键词. 替换的规则是:
     * 1.对于title,如果替换后的长度超过50,对于desc1,desc2,如果替换后的长度超过80,则不做替换,使用默认关键词并且显示为绿色字体;
     * 2.如果未超过,则使用指定的关键词替换并且使用红色字体.
     *
     * @author gaoyibo
     * @param source
     *            要替换的title or desc1 or desc2
     * @param key
     *            指定的关键词
     * @param type
     * @return
     */
    public static String replaceDefaultKey(String source, String key,
            IdeaContentType type) {
        String result = "";
        if (source == null || source.length() <= 0)
            return result;
        Matcher matcher = Pattern.compile(regexStr).matcher(source);
        if (!matcher.find()) {
            return source;
        }
        String replaceFormatKey = "<font color='red'>" + key + "</font>";
        // 先根据全部替换之后的值的长度判断,如果超长,就不用[格式化后的key]去替换source里面的默认关键词.如果未超长,则替换.
        result = Pattern.compile(regexStr).matcher(source).replaceAll(key);
        switch (type) {
        case TITLE:
            // 不替换,使用默认关键词,但默认关键词要格式化
            if (result.length() > TITLE_LEN) {
                return doReplace(source);
            }
            // 替换
            return matcher.replaceAll(replaceFormatKey);
        case DESC1:
            if (result.length() > DESC_LEN) {
                return doReplace(source);
            }
            return matcher.replaceAll(replaceFormatKey);
        case DESC2:
            if (result.length() > DESC_LEN) {
                return doReplace(source);
            }
            return matcher.replaceAll(replaceFormatKey);
        default:
            return source;
        }

    }

    /**
     * 递归方法,每次格式化第一个匹配到的默认关键词.
     *
     * @author gaoyibo
     * @param source
     * @return
     */
    public static String doReplace(String source) {
        Matcher matcher = Pattern.compile(regexStr).matcher(source);
        while (matcher.find()) {
            // 匹配内容的提取.
            String keytmp = matcher.group();
            String defaultFormatKey = "<font color='green'>"
                    + keytmp.substring(1, keytmp.length() - 1) + "</font>";

            // 第一个匹配内容替换,替换之后,再递归.
            return doReplace(matcher.replaceFirst(defaultFormatKey)); // 将当前的默认关键词格式化之后,将返回的字符串递归.直到所有的默认关键词都被格式化.
        }
        return source;
    }

    public static void main(String[] args) throws IOException {
        // 下面的字符串里面有多个默认关键词的通配符,每个默认关键词都不一样.
        String testStr = "asd:{重1:}23:{:}saA{d中ks1}asdadsa{DK2}asda{dk}sad2rty34";
        System.out.println(replaceDefaultKey(testStr, "kkkkkk",
                IdeaContentType.TITLE));

    }

}

1. 在 java.util.regex 包中有哪三个公共的类?描述一下它们的作用。
2. 考虑一下字符串“foo”,它的开始索引是多少?结束索引是多少?解释一下这些编号的意思。
3. 普通字符和元字符有什么不同?各给出它们的一个例子。
4. 如何把元字符表现成像普通字符那样?
5. 附有方括号的字符集称为什么?它有什么作用?
6. 这里是三个预定义的字符类:d、s和w。描述一下它们各表示什么?并使用方括号的形式将它们重写。
7. 对于d、s和w,写出两个简单的表达式,匹配它们相反的字符集。
8. 思考正则表达式(dog){3},识别一下其中的两个子表达式。这个表达式会匹配什么字符串?

〖练习〗
1. 使用反向引用写一个表达式,用于匹配一个人的名字,假设这个人的 first 名字与 last 名字是相同的。

【问题答案】
1. 问:在 java.util.regex 包中有哪三个公共的类?描述一下它们的作用。

答:
编译后的 Pattern 实例表示正则表达式。
Matcher 实例是解析模式和靠着输入的字符串完成匹配操作的引擎。
PatternSyntaxException 定义一个未检查异常,指示正则表达式中的语法错误。
2. 问:考虑一下字符串“foo”,它的开始索引是多少?结束索引是多少?解释一下这些编号的意思。

答:字符串中的每一个字符位于其自身的单元格中。索引位置在两个单元格之间。字符串“foo”开始于索引 0,结束于索引 3,即便是这些字符仅占用了 0、1 和 2 号单元格。
3. 问:普通字符和元字符有什么不同?各给出它们的一个例子。
答:正则表达式中的普通字符匹配其本身。元字符是一个特殊的字符,会影响被匹配模式的方式。字母A是一个普通字符。标点符号.是一个元字符,其匹配任意的单字符。
4. 问:如何把元字符表现成像普通字符那样?
答:有两种方法:
在元字符前加上反斜线();
把元字符置于Q(开始)E(结束)的引用表达式中。
5. 问:附有方括号的字符集称为什么?它有什么作用?
答:是一个字符类。通过方括号间的表达式,匹配指定字符类中的任意一个字符。
6. 问:这里是三个预定义的字符类:d、s和w。描述一下它们各表示什么?并使用方括号的形式将它们重写。
答:d 匹配任意数字[0-9]
  s 匹配任意空白字符[ tn-x0Bfr]
  w 匹配任意单词字符[a-zA-Z_0-9]
7. 问:对于d、s和w,写出两个简单的表达式,匹配它们相反的字符集。
答:d D [^d]
  s S [^s]
  w W [^w]
8. 问:思考正则表达式(dog){3},识别一下其中的两个子表达式。这个表达式会匹配什么字符串?
答:表达式由捕获组(dog)和接着的贪婪量词{3}所组成。它匹配字符串“dogdogdog”。
【练习答案】
1. 练习:使用反向引用写一个表达式,用于匹配一个人的名字,假设这个人的 first 名字与 last 名字是相同的。
解答:([A-Z][a-zA-Z]*)s1
注释返回目录[1]  本文全文译自 Java Tutorial 的 Regular Expressions,标题是译者自拟的。——译者注

[2]  Unix 工具,用于文件中的字符串查找,它是最早的正则表达式工具之一。——译者注

[3]  若要退出可以使用 Ctrl + C 来中断。——译者注

[4]  图中的“索引 3”指示是译者所加,原文中并没有。——译者注

[5]  这种方式在 JDK 6.0 以前版本使用需要注意,在字符类中使用这种结构是有 bug 的,不过在 JDK 6.0 中已经修正。——译者注

[6]  若E前没有Q时会产生 PatternSyntaxException 异常指示语法错误。——译者注

[7]  第一次匹配时仅匹配字符串的开始部分,与A类似。(引自 Jeffrey E.F.Friedl, Mastering Regular Expressions, 3rd ed., §3.5.3.3, O'Reilly, 2006.)——译者注

[8]  u030A,即字符 å 上半部分的小圆圈( ̊ )(该字符在 IE 浏览器上无法正确显示,在 Firefox 浏览器上可以正常地显示)。——译者注

[9]  JDK 5.0 新增的方法,JDK 1.4 中不能使用。——译者注

[10]  JDK 1.4 和 JDK 5.0 适用的版本在所附的源代码中。适用于 JDK 1.4 的文件名为 RegexTestHarness2V4.java,JDK 1.5 的文件名为 RegexTestHarness2V5.java。——译者注

[11]  第三版是本书的最新版本。第三版的中译本《精通正则表达式》已由电子工业出版社于 2007 年 7 月出版。——译者注

 

 

发现appendReplacement与appendTail方法搭配也能起到上面递归方法的作用.如下例:
    public static String doReplace2(String source) {        Matcher matcher = Pattern.compile(regexStr).matcher(source);        StringBuffer sb = new StringBuffer();        while (matcher.find()) {            String keytmp = matcher.group();            String defaultFormatKey = "<font color='green'>"                    + keytmp.substring(1, keytmp.length() - 1) + "</font>";            matcher.appendReplacement(sb, defaultFormatKey);        }        matcher.appendTail(sb);        return sb.toString();    }

补充:Jsp教程,Java技巧及代码 
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,