Java正则表达式及字符串处理详解

java正则表达式及字符串处理详解

本篇博文主要是对java String类涉及正则表达式方法及java.util.regex包中相关类和方法的一个总结

String类

相关方法

    boolean     matches(String regex)
              告知此字符串是否匹配给定的正则表达式
    String  replaceAll(String regex, String replacement)
              使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
    String  replaceFirst(String regex, String replacement)
              使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。
    String[]    split(String regex)
              根据给定正则表达式的匹配拆分此字符串。
    String[]    split(String regex, int limit)
              根据匹配给定的正则表达式来拆分此字符串。

注意事项:
在使用replaceAll和replaceFirst方法时后一个参数(replacement)的转义字符也是正则形式。

    replaceAll("\\\\","\\\\\\\\")//将字面的单斜杠替换为双斜杠

Pattern类

组和捕获
捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C))) 中,存在四个这样的组:

1       ((A)(B(C)))
2       \A
3       (B(C))
4       (C)

组零始终代表整个表达式。

之所以这样命名捕获组是因为在匹配中,保存了与这些组匹配的输入序列的每个子序列。捕获的子序列稍后可以通过 Back 引用在表达式中使用,也可以在匹配操作完成后从匹配器获取。

与组关联的捕获输入始终是与组最近匹配的子序列。如果由于量化的缘故再次计算了组,则在第二次计算失败时将保留其以前捕获的值(如果有的话)例如,将字符串 “aba” 与表达式 (a(b)?)+ 相匹配,会将第二组设置为 “b”。在每个匹配的开头,所有捕获的输入都会被丢弃。

以 (?) 开头的组是纯的非捕获 组,它不捕获文本,也不针对组合计进行计数。

相关方法

    static Pattern  compile(String regex)
          将给定的正则表达式编译到模式中。
    static Pattern  compile(String regex, int flags)
              将给定的正则表达式编译到具有给定标志的模式中。
    int     flags()
              返回此模式的匹配标志。
    Matcher     matcher(CharSequence input)
              创建匹配给定输入与此模式的匹配器。
    static boolean  matches(String regex, CharSequence input)
              编译给定正则表达式并尝试将给定输入与其匹配。
    String  pattern()
              返回在其中编译过此模式的正则表达式。
    static String   quote(String s)
              返回指定 String 的字面值模式 String。
    String[]    split(CharSequence input)
              围绕此模式的匹配拆分给定输入序列。

注意事项:
Pattern.split和String.split的区别:

String.split每次调用时都会重新编译传入的正则表达式,然后调用Pattern.split进行分割,所以当分割次数多的时候String.split的代价会更加高

Matcher类

通过调用模式的 matcher 方法从模式创建匹配器。创建匹配器后,可以使用它执行三种不同的匹配操作:

matches 方法尝试将整个输入序列与该模式匹配。

lookingAt 尝试将输入序列从头开始与该模式匹配。

find 方法扫描输入序列以查找与该模式匹配的下一个子序列。

每个方法都返回一个表示成功或失败的布尔值。通过查询匹配器的状态可以获取关于成功匹配的更多信息。

匹配器在其输入的子集(称为区域)中查找匹配项。默认情况下,此区域包含全部的匹配器输入。可通过 region 方法修改区域,通过 regionStart 和 regionEnd 方法查询区域。区域边界与某些模式构造交互的方式是可以更改的。有关此内容更多的信息,请参阅 useAnchoringBounds 和 useTransparentBounds。

此类还定义使用新字符串替换匹配子序列的方法,需要时,可以从匹配结果计算出新字符串的内容。可以先后使用 appendReplacement 和 appendTail 方法将结果收集到现有的字符串缓冲区,或者使用更加便捷的 replaceAll 方法创建一个可以在其中替换输入序列中每个匹配子序列的字符串。

匹配器的显式状态包括最近成功匹配的开始和结束索引。它还包括模式中每个捕获组捕获的输入子序列的开始和结束索引以及该子序列的总数。出于方便的考虑,还提供了以字符串的形式返回这些已捕获子序列的方法。
此类的实例用于多个并发线程是不安全的。

相关方法

     int    end()
              返回最后匹配字符之后的偏移量。
     int    end(int group)
              返回在以前的匹配操作期间,由给定组所捕获子序列的最后字符之后的偏移量。
     boolean    find()
              尝试查找与该模式匹配的输入序列的下一个子序列。
     boolean    find(int start)
              重置此匹配器,然后尝试查找匹配该模式、从指定索引开始的输入序列的下一个子序列。
     String     group()
              返回由以前匹配操作所匹配的输入子序列。
     String     group(int group)
              返回在以前匹配操作期间由给定组捕获的输入子序列。
     boolean    lookingAt()
              尝试将从区域开头开始的输入序列与该模式匹配。
     boolean    matches()
              尝试将整个区域与模式匹配。
     Matcher    region(int start, int end)
              设置此匹配器的区域限制。
     String     replaceAll(String replacement)
              替换模式与给定替换字符串相匹配的输入序列的每个子序列。
     String     replaceFirst(String replacement)
              替换模式与给定替换字符串匹配的输入序列的第一个子序列。
     int    start()
              返回以前匹配的初始索引。
     int    start(int group)
              返回在以前的匹配操作期间,由给定组所捕获的子序列的初始索引。
     Matcher    useAnchoringBounds(boolean b)
              设置匹配器区域界限的定位。
     Matcher    useTransparentBounds(boolean b)
              设置此匹配器区域边界的透明度。

注意事项:
匹配多个连续相同字符时需要使用組的概念,比如匹配n个相同的单词字符(\w):

(\\w)\\* 前面括号表示的组号 *{n-1}

正则表达式典型的调用顺序:

     Pattern p = Pattern.compile("a*b");
     Matcher m = p.matcher("aaaaab");
     boolean b = m.matches();//m.find()

Java正则化中需要转义的字符

常用方法示例

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

/**
 * Created by CageTian on 2017/12/6.
 */
public class Regex {

    public static void main(String[] args) {
        String test1="dada123asd2222dddada223asd";
        String test2="asdwx78213v5cs234 \rfg6437f2345%6!@#xw$%xwsd^&**234x  s()_";
        String test3="esc\\aaaasdsd";

        //直接使用String内的方法

        test1=test1.replaceFirst("(?<=ada)\\d{3}(?=asd)","cagetian");
        //将前面字符是ada,后面字符是asd的三个数字的字符串替换为cagetian
        System.out.println(test1);
        test2=test2.replaceAll("(?,"cagetian");
        //将前面不是2-3个数字或者字母,后面没有空格或数字的234组成的三位数替换为cagetian
        System.out.println("test2: "+test2);
        System.out.println("test3: "+test3.replaceAll("\\\\","\\\\\\\\"));


        //Pattern和Matcher的用法
        Pattern p=Pattern.compile(".*((\\w)\\2{2}).*(?<=ada)(\\d{3})(?=asd)");
        //(\\w)\\1{2}匹配ddd,一共有3个组1:d; 2:dd; 3:223
        Matcher matcher=p.matcher(test1);
        //matcher.matches()会尝试匹配所有字符串,返回false
        //matcher.find()在字符串中查找子序列,存在则返回true
        System.out.println(matcher.find());
        //执行find()或matches()函数后才能调用start
        System.out.println("matcher.start(): "+matcher.start());
        //返回第一个组捕获的字符串
        System.out.println("group1: "+ matcher.group(1));
        //判断第一第二组的位置是否相等
        System.out.println(matcher.start(1)==matcher.start(2));
        //得到第三組及之后的字符串
        System.out.println(test1.substring(matcher.start(3)));

    }
}

输出结果

dadacagetianasd2222dddada223asd
fg6437f2345%6!@#xw$%xwsd^&**cagetianx  s()_
test3: esc\\aped
true
0
group1: ddd
true
223asd

参考

Java API 文档。

你可能感兴趣的:(Java正则表达式及字符串处理详解)