代码改变世界

正则表达式-Java

2017-09-27 18:13  安松  阅读(493)  评论(0编辑  收藏  举报

1. 使用正则表达式替换,按照模板替换,如将  8DD9EE67E8B543D6AFE75D793BF78939 替换为 8DDC9EE67-E8B5-43D6-AFE7-5D793BF78939

 7DC9EE62 E8B5 43D6 AFE7 5D793BF78939
public String insertGang(String str){ String template = "$1-$2-$3-$4-$5"; String regex = "(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{10})"; return str.replaceAll(regex, template); }

看源码:
public String replaceAll(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}

解释:
① : Pattern和Matcher Pattern 一个Pattern是一个正则表达式经编译后的表现模式。 
② : Matcher 一个Matcher对象是一个状态机器,它依据Pattern对象做为匹配模式对字符串展开匹配检查。 
③ : Pattern.compile(regex) 将给定的正则表达式编译并赋予给Pattern类 
Pattern.compile(regex),,这个将生成一个数组  (\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{10})    0-0  1-30 2-0 3-8 4-8 5-12 6-12 7-16 如下图 groups
④ : Matcher matcher(CharSequence input) 生成一个给定命名的Matcher对象 
⑤ :
看源码:
 public String replaceAll(String replacement) {
        reset();
        boolean result = find();
        if (result) {
            StringBuffer sb = new StringBuffer();
            do {
                appendReplacement(sb, replacement);
                result = find();
            } while (result);
            appendTail(sb);
            return sb.toString();
        }
        return text.toString();
    }

appendReplacement():就是源字符串根据 "$1-$2-$3-$4-$5"; 进行追加“-”字符,根据 Pattern.compile(regex)生成的数组groups分割添加字符“-”

 

 public Matcher appendReplacement(StringBuffer sb, String replacement) {

        // If no match, return error
        if (first < 0)
            throw new IllegalStateException("No match available");

        // Process substitution string to replace group references with groups
        int cursor = 0;
        StringBuilder result = new StringBuilder();

        while (cursor < replacement.length()) {
            char nextChar = replacement.charAt(cursor);
            if (nextChar == '\\') {
                cursor++;
                if (cursor == replacement.length())
                    throw new IllegalArgumentException(
                        "character to be escaped is missing");
                nextChar = replacement.charAt(cursor);
                result.append(nextChar);
                cursor++;
            } else if (nextChar == '$') {
                // Skip past $
                cursor++;
                // Throw IAE if this "$" is the last character in replacement
                if (cursor == replacement.length())
                   throw new IllegalArgumentException(
                        "Illegal group reference: group index is missing");
                nextChar = replacement.charAt(cursor);
                int refNum = -1;
                if (nextChar == '{') {
                    cursor++;
                    StringBuilder gsb = new StringBuilder();
                    while (cursor < replacement.length()) {
                        nextChar = replacement.charAt(cursor);
                        if (ASCII.isLower(nextChar) ||
                            ASCII.isUpper(nextChar) ||
                            ASCII.isDigit(nextChar)) {
                            gsb.append(nextChar);
                            cursor++;
                        } else {
                            break;
                        }
                    }
                    if (gsb.length() == 0)
                        throw new IllegalArgumentException(
                            "named capturing group has 0 length name");
                    if (nextChar != '}')
                        throw new IllegalArgumentException(
                            "named capturing group is missing trailing '}'");
                    String gname = gsb.toString();
                    if (ASCII.isDigit(gname.charAt(0)))
                        throw new IllegalArgumentException(
                            "capturing group name {" + gname +
                            "} starts with digit character");
                    if (!parentPattern.namedGroups().containsKey(gname))
                        throw new IllegalArgumentException(
                            "No group with name {" + gname + "}");
                    refNum = parentPattern.namedGroups().get(gname);
                    cursor++;
                } else {
                    // The first number is always a group
                    refNum = (int)nextChar - '0';
                    if ((refNum < 0)||(refNum > 9))
                        throw new IllegalArgumentException(
                            "Illegal group reference");
                    cursor++;
                    // Capture the largest legal group string
                    boolean done = false;
                    while (!done) {
                        if (cursor >= replacement.length()) {
                            break;
                        }
                        int nextDigit = replacement.charAt(cursor) - '0';
                        if ((nextDigit < 0)||(nextDigit > 9)) { // not a number
                            break;
                        }
                        int newRefNum = (refNum * 10) + nextDigit;
                        if (groupCount() < newRefNum) {
                            done = true;
                        } else {
                            refNum = newRefNum;
                            cursor++;
                        }
                    }
                }
                // Append group
                if (start(refNum) != -1 && end(refNum) != -1)
                    result.append(text, start(refNum), end(refNum));
            } else {
                result.append(nextChar);
                cursor++;
            }
        }

图groups

2. 判断字符串中是否包含子串

       String content = "I am noob from runoob.com.";

       String pattern = ".*runoob.*";

       boolean isMatch = Pattern.matches(pattern, content);
       System.out.println("字符串中是否包含了 'runoob' 子字符串? " + isMatch);    //字符串中是否包含了 'runoob' 子字符串? true

3. 

① 例子
// 按指定模式在字符串查找
String line = "This order was placed for QT3000! OK?";
String pattern = "(\\D*)(\\d+)(.*)";//

// 创建 Pattern 对象
Pattern r = Pattern.compile(pattern);

// 现在创建 matcher 对象
Matcher m = r.matcher(line);
if (m.find( )) {
System.out.println("Found value: " + m.group(0) ); //(\D*)(\d+)(.*) This order was placed for QT3000! OK?
System.out.println("Found value: " + m.group(1) ); //(\D*) This order was placed for QT
System.out.println("Found value: " + m.group(2) ); //(\d+) 3000
System.out.println("Found value: " + m.group(3) ); //(.*) ! OK?
} else {
System.out.println("NO MATCH");
}
②//如果想拿3000
String line = "This order was placed for QT3000! OK?";
String pattern = "\\D*(\\d+).*";//

// 创建 Pattern 对象
Pattern r = Pattern.compile(pattern);

// 现在创建 matcher 对象
Matcher m = r.matcher(line);
System.out.println("count : "+m.groupCount()); // 1
if (m.find()) {
System.out.println("Found value: " + m.group(0) ); // This order was placed for QT3000! OK?
System.out.println("Found value: " + m.group(1) ); // 3000
} else {
System.out.println("NO MATCH");
}

 4. 

     String REGEX = "\\bcat\\b";  // \b:匹配一个单词边界
        String INPUT = "cat cat cat cattie cat";
        Pattern p = Pattern.compile(REGEX);
        Matcher m = p.matcher(INPUT); // 获取 matcher 对象
        int count = 0;

        System.out.println("Match count "+ m.groupCount());
        while(m.find()) {
            count++;
            System.out.println("Match number "+count); // 1  2  3  4
            System.out.println("start(): "+m.start()); // 0  4  8  19
            System.out.println("end(): "+m.end());     // 3  7  11  22
        }

5.  matches和lookingAt区别

  matches 和 lookingAt 方法都用来尝试匹配一个输入序列模式。它们的不同是 matches 要求整个序列都匹配,而lookingAt 不要求。

  lookingAt 方法虽然不需要整句都匹配,但是需要从第一个字符开始匹配

String INPUT = "fooooooooooooooooo";
String INPUT2 = "ooooofoooooooooooo";
pattern = Pattern.compile(REGEX);\
matcher = pattern.matcher(INPUT);
matcher2 = pattern.matcher(INPUT2);
System.out.println("lookingAt(): "+matcher.lookingAt());  // true
System.out.println("matches(): "+matcher.matches());      // false
System.out.println("lookingAt(): "+matcher2.lookingAt()); // false

 

6. replaceFirst 和 replaceAll 方法用来替换匹配正则表达式的文本。不同的是,replaceFirst 替换首次匹配,replaceAll 替换所有匹配。

     String REGEX = "dog";
        String INPUT = "The dog says meow. All dogs say meow.";
        String REPLACE = "cat";
Pattern p
= Pattern.compile(REGEX); Matcher m = p.matcher(INPUT); INPUT = m.replaceAll(REPLACE);
System.out.println(INPUT);
// The cat says meow. All cats say meow.

7.  appendReplacement 和 appendTail

     String REGEX = "a*b";
        String INPUT = "aabfooaabfooabfoobccc";
        String REPLACE = "-";

        Pattern p = Pattern.compile(REGEX);
        // 获取 matcher 对象
        Matcher m = p.matcher(INPUT);
        StringBuffer sb = new StringBuffer();
        while(m.find()){
            m.appendReplacement(sb,REPLACE);
        }
        System.out.println("sb1 : "+sb.toString()); //  sb1 : -foo-foo-foo-
        m.appendTail(sb);     //用matcher.appendReplacement( sb, REPLACE)就是在Matcher.find()找到匹配的地方用REPLACE替换掉然后加进StringBuffer中去,这时后面可能还有字符串但是不匹配的,matcher.appendTail()就是把不匹配(ccc)的加上
        System.out.println(sb.toString());           // -foo-foo-foo-ccc

8.