Javase | 正则表达式

目录:

    • 1.正则表达式:
      • 1.1 正则表达式概念
      • 1.2 正则表达式语法表
      • 1.3 正则表达式语法示例
    • 2.字符类:
      • 2.1 字符类概念及语法
      • 2.2 字符类示例
    • 3.创建 “特殊字符失效区” / 还原特殊符号:
    • 4.正则表达式对象 (Pattern对象) :
      • 4.1 创建Pattern对象
      • 4.2 Pattern对象的作用
      • 4.3 Pattern类能调用的方法
      • 4.4 Matcher类能调用的方法
    • 5.正则表达式对象 与 正则表达式参数 的区别:
    • 6.正反向预搜索:
      • 6.1 正向预搜索
      • 6.2 反向预搜索
    • 7.反向引用:
      • 7.1 反向引用的 概念
      • 7.2 反向引用的 作用

1.正则表达式:

1.1 正则表达式概念

  • 正则表达式,又称规则表达式(Regular Expression,简写为regex、regexp或RE),是一种强大的文本模式匹配工具,用于在字符串中匹配、搜索、获取和替换文本。
  • 正则表达式是由一系列字符和特殊字符组成的模式,用于定义要匹配的文本的规则。
  • 正则表达式可用于各种应用,如文本搜索、数据验证、字符串分割、格式字符串等。

1.2 正则表达式语法表

  • Java中单一个斜杠 (\) 表示转义字符,而在正则表达式语法中直接用一个斜杠 (\) 是会报错的,因为正则表达式语法中用到的是斜杠字符本身,此时用两个斜杠 (\\)进行转义得到斜杠字符本身,所以例子如:\d在开发中实际输入的是\\d。

  • 语法\d的斜杠是 \ (斜杠)字符本身,而不是转义字符

表达式 描述
\d 匹配一个数字字符。即0~9中的数字都能被匹配。
\D 匹配一个非数字字符。包括字母、符号和空格等,即键盘上除了数字之外的字符。
\w 匹配一个单词字符。既数字、字母和下划线。
\W 匹配所有\w不匹配的字符。即匹配非单词字符,除了数字、字母、下划线之外的字符。
\s 匹配空白字符。包括空格符、制表符(\t)、换行符(\n)、回车符(\r)、换页符(\f)等。
\S 匹配所有\s不匹配的字符。即匹配非空白字符,匹配空格符、制表符(\t)、换行符(\n)、回车符(\r)、换页符(\f)之外的其他字符。
. 匹配除了换行符 (\n)之外的所有字符。一个.仅能匹配一个字符。
+ 表示前面的元素可以出现一次或多次。
^ ①在字符类中表示 : 匹配指定字符之外的其他字符

②在非字符类,即正常的正则表达式中表示 : 匹配在开头位置的特定字符串
表达式 描述
[ ] 创建一个字符类,用于匹配一个字符的集合。
{ } 用于指定前面元素的匹配次数。
{n} : 匹配前面的元素恰好n次。
{n,} : 匹配前面的元素至少n次,不限制超过次数。
{n,m} : 匹配前面的元素至少n次,但不超过m次。
\\Q \\E 创建特殊字符失效区。
? 表示前面的元素可以出现0次或1次。
* 表示前面的元素可以出现0次或多次。 (相连的字符会被当做一个整体来看待)
+ 表示前面的元素可以出现1次或多次 (相连的字符会被当做一个整体来看待)
| 表示两种选择,选择匹配中的一个。
( ) 括号内的表达式作为一个整体。
表达式 描述 示例
^ (在字符类中) 匹配指定字符之外的其他字符 “[^abc]” :
匹配除了abc这三个字符之外的其他字符
^ (在非字符类中,即在正常的
“ ”中)
匹配在开头位置的特定字符串 “^abc” :
匹配在开头位置的abc这个三个字符 (是一个整体)
$ (有两种含义) ①匹配在末尾位置的特定字符串 (在正常正则表达式中的含义)

②获得指定组数的字符串 (在反向引用中的含义)
“"abc$” :
匹配在末尾位置的abc这三个字符(是一个整体) —正则表达式中的例子
^ $ 匹配在开始位置, 又在末尾位置的特定字符串 "^abc$” :
匹配在开始位置, 又在末尾位置的字符串
\b 匹配前或后有空白字符的特定字符串
ps: 字符串的的开头或结尾也被看作空白字符
“aaa aaa”;
“\\ba”;
replaceAll( )方法结果为: *aa *aa
?= xxx 要匹配的特定字符串的右边必须是xxx “windowNT windowXP”;
“window(?=NT)”
replaceAll( )方法 :( 匹配右边为NT的window,只匹配window)
?! xxx 要匹配的特定字符串右边必须不是xxx “windowNT windowXP”;
“window(?!NT)”
replaceAll( )方法 :( 匹配右边不为NT的window,只匹配window) :
?<= xxx 要匹配的特定字符串的左边必须是xxx “123window 456window”;
“(?<=123)window”
replaceAll( )方法:( 匹配左边为123的window,只匹配window)
? 要匹配的特定字符串的左边必须不是xxx “123window 456window”;
“(?replaceAll( )方法 :( 匹配左边不为123的window,只匹配window)

1.3 正则表达式语法示例

Java中单一个斜杠 (\) 表示转义字符,为了表示斜杠字符本身,要用两个斜杠 (\\)。

  • \d例子:

       //将数字字符 替换成 -
       String s ="12345~`!@#$%^&*()_+[]{}'|,.<>/abc defg世  界你好";
       String r = s.replaceAll("\\d", "-");
       System.out.println(r); //-----~`!@#$%^&*()_+[]{}'|,.<>/abc defg世  界你好
    
  • \D例子:

       //将非数字字符 替换成 -
       //非数字字符: 键盘上了除了数字之外的其他字符
       String s ="12345~`!@#$%^&*()_+[]{}'|,.<>/abc defg世  界你好";
       String r = s.replaceAll("\\D", "-");
       System.out.println(r); //12345---------------------------------------
    
  • \w例子:

//将单词字符 替换成 -
//单词字符: 数字、字母、下划线
String s ="12345~`!@#$%^&*()_+[]{}'|,.<>/abc defg世  界你好";
String r = s.replaceAll("\\w", "-");
System.out.println(r);  //-----~`!@#$%^&*()-+[]{}'|,.<>/--- ----世  界你好
  • \W例子:

       //将非单词字符 替换成 -
       //非单词字符: 除了数字、字母、下划线之外的其他字符
       String s ="12345~`!@#$%^&*()_+[]{}'|,.<>/abc defg世  界你好";
       String r = s.replaceAll("\\W", "-");
       System.out.println(r);  //12345------------_------------abc-defg------
    
  • \s例子:

      		//匹配所有空白字符。
            //空白字符: 空格符、换行符、制表符、回车符、换页符
            String text = "HelloWorld! China\nToJava\t123\rabcde\fHelloSpring";
            String[] words = text.split("\\s");
            /*
              for语句输出:
               HelloWorld!
               China
               ToJava
               123
               abcde
               HelloSpring
             */
            for (String word : words) {
                System.out.println(word);
            }
    
  • \S例子:

      String text = "HelloWorld! China\nToJava\t123\rabcde\fHelloSpring";
            //  \\S : 匹配一个非空白字符 (匹配一个则输出一个)
            //  \\S+ :匹配一个或多个非空白字符 (匹配多个则输出多个)
            Pattern pattern = Pattern.compile("\\S+");  //匹配一个或多个非空白字符
            Matcher matcher = pattern.matcher(text);
    
            /**
             * while语句输出内容为:
             *
             * HelloWorld!
             * China
             * ToJava
             * 123
             * abcde
             * HelloSpring
             */
            while (matcher.find()) {  //用于搜索是否有符合正则表达式的字符串
                System.out.println(matcher.group()); //获得符合正则表达式的字符串
            }
    
  • . 例子:

       // matches() : 检查一个字符串是否与给定的正则表达式模式匹配
       String text = "Habo";
       String pattern = "H..o";  // H+(两个除了换行符之外的任意字符)+o
       System.out.println(text.matches(pattern)); // 输出结果为 true
       String text2 = "Java is awesome";
       System.out.println(text2.matches(pattern)); // 输出结果为 false
    
  • +例子:

       String text1= "aaaaab";
       String text2 = "bccd";
       String pattern1 = "a+b"; //a+ : 匹配一个或多个a
       String pattern2 = "bc+d";//c+ : 匹配一个或多个c
    
       //.matches() : 判断字符串是否与正则表达式相匹配
       System.out.println(text1.matches(pattern1)); //true
       System.out.println(text2.matches(pattern1)); //false
       System.out.println(text2.matches(pattern2)); //true
    
  • ^例子1:(在字符类中 )

       String text = "abcHello, Worlda";
       String regex = "[^abc]+"; //匹配除了abc这三个字符之外的其他字符
       Pattern pattern = Pattern.compile(regex);
       Matcher matcher = pattern.matcher(text);
       /**
       * while语句打印内容为: Hello, World
       */
       while (matcher.find()) {
       System.out.println(matcher.group());
    }
    
  • ^例子2:(在非字符类中 / 正常“ ”中)

       String text1 = "abcabcabc";
       String text2 = "xyzabc";
       String text3 = "helloabcdi";
       // ^ : 匹配在开头位置的特定字符串
       //^abc : 匹配在开头位置的abc
       System.out.println(text1.replaceAll("^abc", "*")); //*abcabc
       System.out.println(text2.replaceAll("^abc", "*")); //xyzabc (没改变,因为没匹配成功)
       System.out.println(text3.replaceAll("^abc", "*")); //helloabcdi (没改变,因为没匹配成功)
    
  • { }例子1:

       String s = "123a2345b"; //2345有是个数字两者,能匹配到234且替换为 *
       //匹配前面元素(数字字符)恰好3次
       String r = s.replaceAll("\\d{3}", "*");  //一次匹配三个数字字符,将其替换为 *
       System.out.println(r); //*a*5b
    
       String s1 = "123a123456b";
       String r1 = s1.replaceAll("\\d{3}", "*");
       System.out.println(r1); //*a**b
    
  • { }例子2:

           String text = "abc abbc abbbc abbbbc abbbbbc";
            String pattern1 = "ab{2}c"; // 匹配 "abbc"
            String pattern2 = "ab{2,4}c"; // 匹配 "abbc", "abbbc", "abbbbc"
            String pattern3 = "ab{3,}c"; // 匹配 "abbbc", "abbbbc", "abbbbbc"
    
            //创建正则表达式对象
            Pattern regex1 = Pattern.compile(pattern1);
            Pattern regex2 = Pattern.compile(pattern2);
            Pattern regex3 = Pattern.compile(pattern3);
    
            //创建匹配器对象
            Matcher matcher1 = regex1.matcher(text);
            Matcher matcher2 = regex2.matcher(text);
            Matcher matcher3 = regex3.matcher(text);
    
            //搜索与正则表达式匹配的字符串,获得且输出该字符串
            //while语句输出: "abbc"
            while (matcher1.find()) {
                System.out.println(matcher1.group());
            }
            System.out.println();
    
            /**
             * while语句输出:
             * abbc
             * abbbc
             * abbbbc
             */
            while (matcher2.find()) {
                System.out.println(matcher2.group());
            }
            System.out.println();
    
            /**
             * while语句输出:
             * abbbc
             * abbbbc
             * abbbbbc
             */
            while (matcher3.find()) {
                System.out.println(matcher3.group());
     }
    
  • ?的例子:

       String text = "123a234567b";
       // \d? : 匹配数字字符0次或1次
       String s = text.replaceAll("\\d?", "*");
       System.out.println(s); //****a*******b*
    
  • *的例子:

       String text = "123a234567b";
       // \d* : 匹配数字字符0次或多次
       String s = text.replaceAll("\\d*", "=");
       System.out.println(s); //==a==b=
    
  • +的例子:

       String text = "123a234567b";
       // \d+ : 匹配数字字符1次或多次
       String s = text.replaceAll("\\d+", "#");
       System.out.println(s); //#a#b
    
  • | 的例子:

       String text = "Tom and Jack are my friends,but Peter is not";
       // Tom|Jack : 表示两种选择,选择匹配其中的一个。
       String s = text.replaceAll("Tom|Jack", "*");
       System.out.println(s); //* and * are my friends,but Peter is not
    
  • $ 的例子1:(正常的正则表达式中例子)

       String text1 = "abcabcabc";
       String text2 = "1abcabcabc";
       String text3 = "abcxyz";
       //匹配在末尾位置的特定字符串
       //匹配在结尾职位的abc,且替换为 #
       System.out.println(text1.replaceAll("abc$", "#")); //abcabc#
       System.out.println(text2.replaceAll("abc$", "#")); //1abcabc#
       System.out.println(text3.replaceAll("abc$", "#")); //abcxyz 没改变,因为没匹配成功)
    
  • $ 的例子2:(在反向引用中的例子)

       String text = "Hello, World!";
       String regex1 = "(\\w+), (\\w+)!"; // 匹配 Hello, World! 这整个内容
       String regex2 = "$2, $1!";
       //用新的字符串替换整个text
       String replacedText = text.replaceAll(regex1, regex2); 
       System.out.println(replacedText);//World,Hello
    
  • ^ $例子:

       String text1 = "abc";
       String text2 = "abc123abc";
       //匹配在既在开头位置又末尾位置的特定字符串
       //匹配在既在开头位置又末尾位置的 abc
       System.out.println(text1.replaceAll("^abc$", "*")); //*
       System.out.println(text2.replaceAll("^abc$", "#")); //abc123abc (没改变,因为没匹配成功)
    
  • \b 例子:

   String text = "aaa aaa";
   // \\b : 匹配前或后有空白字符的特定字符串 (字符串的的开头或结尾也被看作空白字符)
   // \\ba : 匹配前面有空白字符的字符a,且替换为*
   System.out.println(text.replaceAll("\\ba", "*"));  //*aa *aa
   /**
   *  空白字符除了常见的还包括: 字符串的的开头或结尾也被看作空白字符
   */

2.字符类:

2.1 字符类概念及语法

  • 字符类是一个括在 “中括号” : [ ] 中的可选择的字符集。如 [Jj]、[0 - 9]、[A - Za -z] 或 [^0 - 9]。
  • 字符类中无论里面有多少个字符,一次只能匹配一个字符。
  • ” - “ 表示匹配一个范围。即匹配所有Unicode值落在两个边界范围之内的字符。
  • “ ^ ” 表示除了指定字符之外的所有字符。
  • 要匹配 \ 字符本身,要用 \\
  • 要匹配 - 字符本身,要用 \\-
  • 要匹配 [ 字符本身,要用 \\[ (尽量放在开头或末尾,能减少被正则表达式引擎误解的概率)
  • 要匹配 ] 字符本身,要用 \\] (尽量放在开头或末尾,能减少被正则表达式引擎误解的概率)

2.2 字符类示例

   String text = "abcdefg";
   //这个字符类可匹配 'a', 'b', 'f', 'g',每次匹配一个字符
   String regex = "[abfg]"; //一次只能匹配一个字符
   //将匹配到的字符替换为-
   System.out.println(text.replaceAll(regex, "*"));//**cde**
   String text = "abcdefg";
   //这个字符类可匹配 'a', 'b', 'c', 'd', 'e', 'f', 'g',每次匹配一个字符
   String regex = "[abc-efg]";
   //将匹配到的字符替换为-
   System.out.println(text.replaceAll(regex, "-"));//-------
   String text = "abcdefg";
   //这个字符类可匹配所有小写字母
   String regex = "[a-z]";
   System.out.println(text.replaceAll(regex, "+"));//+++++++
   String text = "abcdefg123";
   //这个字符类匹配所有数字
   String regex = "[0-9]"; //每次匹配一个字符
   System.out.println(text.replaceAll(regex, "#")); //abcdefg###
   String text = "abcde[[]";
   String regex = "[\\[]"; // \\[ : 表示[字符本身
   System.out.println(text.replaceAll(regex, "*")); //abcde**]
   String text = "abcde]]]]]";
   String regex = "[\\]]"; // \\] : 表示]字符本身
   System.out.println(text.replaceAll(regex, "=")); //abcde=====
   String text = "abcde45hoasd";
   String regex = "[^abcd]"; //匹配除了abcd这四个字符之外的其他字符
   System.out.println(text.replaceAll(regex, "+")); //abcd+++++a+d
   String text = "abcHello, World";
   String regex = "[^abc]+"; //匹配除了abcd这四个字符之外的其他字符
   Pattern pattern = Pattern.compile(regex);
   Matcher matcher = pattern.matcher(text);
   /**
   * while语句打印内容为: Hello, World
   */
   while (matcher.find()) {
   System.out.println(matcher.group());
}

3.创建 “特殊字符失效区” / 还原特殊符号:

  • 在Java正则表达式中,有些字符有特殊含义,如:. (匹配任意字符)、+(匹配一次或多次)等,这些字符也被称为元字符。然后有时候我们需要使用这些特殊字符本身,当然可以使用转义来将特殊字符还原为普通字符。但如果要还原的元字符过多时,代码会很臃肿,这时可创建 “特殊字符失效区”,失效区内特殊字符不用转义即表示普通字符。

  • 用 \\Q开头,\\E 结尾 : 表示创建了一个特殊字符失效区,里面填的特殊字符自动还原为普通字符。一个正则表达式可以定义多个特殊字符失效区,只要它们边界不产生冲突就可以。

    例如:

       String s = "a..[a]..aaaab";
       //创建特殊字符失效区
       String r = s.replaceAll("\\Q..[a]..a\\E", "*"); // 将 ..[a]..a 替换为 *
       System.out.println(r); //a*aaab
    

4.正则表达式对象 (Pattern对象) :

4.1 创建Pattern对象

  • Java通过Pattern类的静态方法:.compile( 正则表达式参数 ) 来正则表达式对象 (Pattern对象)。

  • 注意不能直接通过new Pattern()的方式来获得正则表达式对象,因为Pattern类的构造方法是私有的。

  • 创建正则表达式的例子:

       String text = "Hello, 123 World!"; 
       String regex = "\\S+";  // 正则表达式参数 \\S+ : 匹配一个或多个非空白字符
       Pattern pattern = Pattern.compile(regex); //创建正则表达式对象
    
  • .compile()方法源码:其实调用compile()方法本质上是通过new关键字实例化对象 (Pattern类的构造方法 )的方式来获得正则表达式对象 (Pattern对象)。
    源码如:

      //complie()方法源码
       /**
         * Compiles the given regular expression into a pattern.
         *
         * @param  regex
         *         The expression to be compiled
         * @return the given regular expression compiled into a pattern
         * @throws  PatternSyntaxException
         *          If the expression's syntax is invalid
         */
    
       /**
       *将给定的正则表达式编译为模式。
       *
       *@param regex
       *要编译的表达式
       *@返回编译成模式的给定正则表达式
       *@throws PatternSyntaxException
       *如果表达式的语法无效
       */
    public static Pattern compile(String regex) {
            return new Pattern(regex, 0);
        }
    
  • Pattern()构造方法源码:

        /**
         * This private constructor is used to create all Patterns. The pattern
         * string and match flags are all that is needed to completely describe
         * a Pattern. An empty pattern string results in an object tree with
         * only a Start node and a LastNode node.
         */
         
         
         /**
         *这个私有构造函数用于创建所有模式。模式字符串和匹配标志是完整描述模式所需的全部内容
         *一个空的模式字符串会产生一个对象树只有Start节点和LastNode节点
         */
           private Pattern(String p, int f) {
            if ((f & ~ALL_FLAGS) != 0) {
                throw new IllegalArgumentException("Unknown flag 0x"
                                                   + Integer.toHexString(f));
            }
            pattern = p;
            flags = f;
    
            // to use UNICODE_CASE if UNICODE_CHARACTER_CLASS present
            if ((flags & UNICODE_CHARACTER_CLASS) != 0)
                flags |= UNICODE_CASE;
    
            // 'flags' for compiling
            flags0 = flags;
    
            // Reset group index count
            capturingGroupCount = 1;
            localCount = 0;
            localTCNCount = 0;
    
            if (!pattern.isEmpty()) {
                try {
                    compile();
                } catch (StackOverflowError soe) {
                    throw error("Stack overflow during pattern compilation");
                }
            } else {
                root = new Start(lastAccept);
                matchRoot = lastAccept;
            }
        }
    

4.2 Pattern对象的作用

  • 正则表达式对象的作用主要是编译和管理正则表达式,并提供方法执行匹配、搜索、获取、替换 (字符串) 等操作。

  • 正则表达式对象提供了一种灵活、强大和高效的方式来处理字符串。

  • 正则表达式对象可执行以下操作:

    • 编译正则表达式: 通过Pattern.compile方法 (静态方法) 将正则表达式编译为正则表达式对象,编译后正则表达式对象可重复使用,提高了性能。

    • 匹配操作:使用pattern.matcher方法 (实例方法) 来获得Matcher对象 (匹配器对象),Matcher对象提供了各种方法来查找、提取和操作与正则表达式匹配的字符串。有以下方法:

      ① .find( ) : 用于搜索是否有符合正则表达式要求的字符串。

      ② .group( ) :用于获取符合正则表达式要求的字符串。

      ③ .replaceAll( ):用于将与正则表达式匹配的字符串替换为指定的字符串

      例子如:

      String text = "HelloWorld! China\nToJava\t123\rabcde\fHelloSpring";
         //  \\S : 匹配一个非空白字符 (匹配一个则输出一个)
      //  \\S+ :匹配一个或多个非空白字符 (匹配多个则输出多个)
         Pattern pattern = Pattern.compile("\\S+");  //匹配一个或多个非空白字符
      Matcher matcher = pattern.matcher(text);
      
       /**
         * while语句输出内容为:
         *
         * HelloWorld!
         * China
         * ToJava
         * 123
         * abcde
         * HelloSpring
         */
         while (matcher.find()) {  //用于搜索是否有符合正则表达式的字符串
         System.out.println(matcher.group()); //获得符合正则表达式的字符串
      }
      
         // matcher.replaceAll()方法的例子
         String str = matcher.replaceAll("=");
         System.out.println(str);
      
  • 拓展:

    String类中的 .matches( )方法:判断字符串是否与正则表达式相匹配。

    例子如:

       String t1 = "a";
       String t2 = "aaa";
       String r1 = "\\w";   //匹配一个单词字符
       String r2 = "\\w+"; //匹配一个或多个单词字符
    
       // matches():判断字符串是否与正则表达式想匹配
       System.out.println(t1.matches(r1)); //true
       System.out.println(t1.matches(r2)); //true
       System.out.println(t2.matches(r1)); //false
       System.out.println(t2.matches(r2)); //true
    

4.3 Pattern类能调用的方法

  • Pattern compile( ) 方法:

    静态方法。可创建Pattern对象 (正则表达式对象)。

  • String[ ] split( )方法:

    实例方法,分隔字符串。

  • String quote方法 :

    静态方法。获得被加入“特殊字符失效区”的正则表达式。

4.4 Matcher类能调用的方法

  • boolean matches():

    检查整个输入字符串是否与正则表达式完全匹配。

  • boolean find():

    尝试在输入字符串中查找下一个匹配的子序列。

  • String group():

    返回最后一次匹配操作期间捕获到的子序列。

  • int start():

    返回最后匹配的子序列的起始索引。

  • int end():

    返回最后匹配的子序列的结束索引。

  • int groupCount():

    返回捕获组的数量。

  • String replaceFirst():

    将第一个匹配的子序列替换为指定的替换字符串。

  • String replaceAll():

    将所有匹配的子序列替换为指定的替换字符串。

  • Matcher reset():

    将Matcher对象重置到当前输入的初始状态。

  • boolean lookingAt():

    尝试从输入字符串的开头开始匹配。

5.正则表达式对象 与 正则表达式参数 的区别:

  • 正则表达式对象 (Pattern对象):

    正则表达式对象表示编译后的正则表达式模式,它通过Pattern.compile()方法或Pattern类的构造方法来创建。

  • 正则表达式参数:

    正则表达式参数是一个字符串,它描述了要进行匹配的模式。它是一个文本字符串,使用特定的语法和符号来表示匹配规则。

6.正反向预搜索:

  • 预搜索 是一种特殊的匹配模式,它允许你匹配某个字符串,但不会将其包含在匹配结果中。
  • 预搜索分为正向预搜索 和 反向预搜索。

6.1 正向预搜索

表达式
(正向预搜索)
描述 示例
?=xxx 要匹配的特定字符串的右边必须是xxx “windowNT windowXP”;
“window(?=NT)”
replaceAll( )方法 :( 匹配右边为NT的window,只匹配window)
?! xxx 要匹配的特定字符串右边必须不是xxx “windowNT windowXP”;
“window(?!NT)”
replaceAll( )方法 :( 匹配右边不为NT的window,只匹配window)

例子如 :

String s = "windowsNT windowsXP";
//?=xxx :要匹配特定字符串的右边必须是xxx
//?!xxx :要匹配特定字符串的右边必须不是xxx
System.out.println(s.replaceAll("windows(?=NT)", "*")); //*NT windowsXP
System.out.println(s.replaceAll("windows(?!NT)", "*")); //windowsNT *XP

6.2 反向预搜索

表达式 (反向预搜索) 描述 示例
?<=xxx 要匹配的特定字符串的左边必须是xxx “123window 456window”;
“(?<=123)window”
replaceAll( )方法 :( 匹配左边为123的window,只匹配window)
? 要匹配的特定字符串的左边必须不是xxx “123window 456window”;
“(?replaceAll( )方法 :( 匹配左边不为123的window,只匹配window)

例子如:

String s = "123windows 456windows";
//?=xxx :要匹配特定字符串的右边必须是xxx
//?!xxx :要匹配特定字符串的右边必须不是xxx
System.out.println(s.replaceAll("(?<=123)windows", "#")); //123# 456windows
System.out.println(s.replaceAll("(?, "#")); //123windows 456#

7.反向引用:

7.1 反向引用的 概念

  • 反向引用:指在正则表达式中引用之前已经被捕获/匹配过的字符串。
  • 通过反向引用,可以在正则表达式中引用先前匹配的内容,以便进行下一步的匹配和替换等操作。
  • 反向引用需要用到 圆括号 ( ) 和 \\数字。 具体来说,当我们在正则表达式中使用圆括号 ( ) 来创建一个分组时,该分组中的内容会被捕获并分配一个编号,从1开始。然后我们就可以在正则表达式中使用反向引用来引用这些已经被捕获的分组。
  • 例如:\\1表示引用第一个捕获的分组,\\2表示引用第二个捕获的分组,以此类推。 “ (.)(.)\\2\\1” : 表示匹配对称 (ABBA样式) 的字符串

7.2 反向引用的 作用

  • 重复的模式匹配: 通过引用先前捕获的分组,可以匹配重复的模式/字符串。例如:重复的单词、重复的字符 (ABAB样式字符串)等。

    例子如:

       String text = "ababab";
       /*
       (\w+)\1 : 先匹配一个字符串,而后紧跟相同的字符串,即最后匹配(ABAB规律的字符串)
       所以最后输出abab
       */
       //创建一个正则表达式对象
       Pattern pattern = Pattern.compile("(\\w+)\\1"); //abab (匹配ABAB样式的字符串)
       //创建匹配器对象
       Matcher matcher = pattern.matcher(text);
       //搜索是否有符合正则表达式要求的字符串
       while (matcher.find()) { //abab
       //获得且输出该字符串
       System.out.println(matcher.group());
    }
    
  • 替换操作: 通过引用先前捕获的分组, 在替换操作中使用这些分组的内容进行替换。

    例子如:

       String text = "Hello, World!";
       String regex1 = "(\\w+), (\\w+)!"; // 匹配 Hello, World! 这整个内容
       String regex2 = "$2, $1!";
       //用新的字符串替换整个text
       String replacedText = text.replaceAll(regex1, regex2); 
       System.out.println(replacedText);//World,Hello
    
  • 后向引用:通过引用先前捕获的分组,可以实现一些特定的模式匹配需求。例如:匹配对称的字符串(ABBA样式字符串)。

    例子如:

       String text = "123abba456cdcd789effeeee";
       //表示匹配“对称的字符串”
       /**
       (.)(.) 表示匹配任意两个字符,分别为编号1和编号2
       \\2\\1  表示匹配对应编号的字符
       */
       String s1 = text.replaceAll("(.)(.)\\2\\1", "*"); //ABBA样式的字符串
       System.out.println(s1); //123*456cdcd789*eee
       String s2 = text.replaceAll("(.)(.)\\1\\2", "*"); //ABAB样式的字符串
       System.out.println(s2); //123abba456*789eff*
    

注意:

  • 需要注意的是,反向引用只能在同一个正则表达式中使用,即在同一个正则表达式内部进行引用。在不同的正则表达式或不同的替换操作中,反向引用是无效的。
  • 如: \\2\\1 就只能在同一个正则表达式内用,跨正则表达式是无效的,但、$2 , $1这些是可跨正则表达式使用。

你可能感兴趣的:(Javase知识点-整合,正则表达式,mysql,数据库,java)