【Java基础】正则表达式的使用与常用类分享

1. Java 正则表达式

正则表达式定义了字符串的模式。

  • 可以用来搜索、编辑或处理文本。

正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。

1.1 正则表达式实例

一个字符串其实就是一个简单的正则表达式,例如 Hello World 正则表达式匹配 "Hello World" 字符串。

.(点号) 也是一个正则表达式,它匹配任何一个字符如:

  • "a""1"

下表列出了一些正则表达式的实例及描述:

  • this is text

    • 匹配字符串 "this is text"
  • this\s+is\s+text

    • 注意字符串中的 \s+
    • 匹配单词 "this" 后面的 \s+ 可以匹配多个空格,之后匹配 is 字符串,再之后 \s+ 匹配多个空格然后再跟上 text 字符串。

可以匹配这个实例:this is text

1.2 常用符号

符号 说明
^ 以什么开始
\d+ 匹配一个或多个数字
\. 匹配 .
? 设置括号内的选项是可选的

Java 正则表达式和 Perl 的是最为相似的。

1.3 常用类

java.util.regex 包主要包括以下三个类:

1.3.1 Pattern 类:

Pattern 对象是一个正则表达式的编译表示。

Pattern 类没有公共构造方法。

要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。

  • 该方法接受一个正则表达式作为它的第一个参数。

1.3.2 Matcher 类:

Matcher 对象是对输入字符串进行解释和匹配操作的引擎

与Pattern 类一样,Matcher 也没有公共构造方法。

  • 你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。

1.3.3 PatternSyntaxException:

PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。

以下实例中使用了正则表达式 .runoob. 用于查找字符串中是否包了 runoob 子串:

实例:

java 复制代码
import java.util.regex.*;

class RegexExample1{
   public static void main(String args[]){
      String content = "I am noob " + "from runoob.com.";
      String pattern = ".*runoob.*";
      boolean isMatch = Pattern.matches(pattern, content);
      System.out.println("字符串中是否包含了 'runoob' 子字符串? " + isMatch);
   }
}

实例输出结果为:

字符串中是否包含了 'runoob' 子字符串? true

1.4 捕获组

捕获组是把多个字符当一个单独单元进行处理的方法,它通过对括号内的字符分组来创建。

例如,正则表达式 (dog) 创建了单一分组,组里包含"d","o",和"g"。

捕获组是通过从左至右计算其开括号来编号。

例如,在表达式((A)(B(C))),有四个这样的组:

bash 复制代码
((A)(B(C)))
(A)
(B(C))
(C)

可以通过调用 matcher 对象的 groupCount 方法来查看表达式有多少个分组。

  • groupCount 方法返回一个 int 值,表示matcher对象当前有多个捕获组。

还有一个特殊的组(group(0)),它总是代表整个表达式。该组不包括在 groupCount 的返回值中。

下面的例子说明如何从一个给定的字符串中找到数字串:

java 复制代码
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches

{
    public static void main( String args[] ){
      // 按指定模式在字符串查找
      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) );
         System.out.println("Found value: " + m.group(1) );
         System.out.println("Found value: " + m.group(2) );
         System.out.println("Found value: " + m.group(3) );
      } else {
         System.out.println("NO MATCH");
      }

   }

}

以上实例编译运行结果如下:

bash 复制代码
Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT
Found value: 3000
Found value: ! OK?

1.5 正则表达式语法

在其他语言中,\\ 表示:我想要在正则表达式中插入一个普通的(字面上的)反斜杠,请不要给它任何特殊的意义。

在 Java 中,\\ 表示:我要插入一个正则表达式的反斜线,所以其后的字符具有特殊的意义。

所以,在其他的语言中(如Perl),一个反斜杠 \ 就足以具有转义的作用

  • 而在 Java 中正则表达式中则需要有两个反斜杠才能被解析为其他语言中的转义作用。

也可以简单的理解在 Java 的正则表达式中,两个 \ 代表其他语言中的一个 \,这也就是为什么表示一位数字的正则表达式是 \d,而表示一个普通的反斜杠是 \\。

1.5.1 start 和 end 方法:

下面是一个对单词 "cat" 出现在输入字符串中出现次数进行计数的例子:

java 复制代码
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches
{
    private static final String REGEX = "\\bcat\\b";
    private static final String INPUT = "cat cat cat cattie cat";
    public static void main( String args[] ){
       Pattern p = Pattern.compile(REGEX);
       Matcher m = p.matcher(INPUT); // 获取 matcher 对象
       int count = 0;
       while(m.find()) {
         count++;
         System.out.println("Match number "+count);
         System.out.println("start(): "+m.start());
         System.out.println("end(): "+m.end());
      }
   }
}

以上实例编译运行结果如下:

bash 复制代码
Match number 1
start(): 0
end(): 3
Match number 2
start(): 4
end(): 7
Match number 3
start(): 8
end(): 11
Match number 4
start(): 19
end(): 22

可以看到这个例子是使用单词边界,以确保字母 "c" "a" "t" 并非仅是一个较长的词的子串。

它也提供了一些关于输入字符串中匹配发生位置的有用信息。

  • Start 方法返回在以前的匹配操作期间,由给定组所捕获的子序列的初始索引,end 方法最后一个匹配字符的索引加 1。

1.5.2 matches 和 lookingAt 方法:

matches 和 lookingAt 方法都用来尝试匹配一个输入序列模式。

  • 它们的不同是 matches 要求整个序列都匹配,而lookingAt 不要求。

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

这两个方法经常在输入字符串的开始使用。

我们通过下面这个例子,来解释这个功能:

java 复制代码
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches
{
    private static final String REGEX = "foo";
    private static final String INPUT = "fooooooooooooooooo";
    private static final String INPUT2 = "ooooofoooooooooooo";
    private static Pattern pattern;
    private static Matcher matcher;
    private static Matcher matcher2;
    public static void main( String args[] ){
       pattern = Pattern.compile(REGEX);
       matcher = pattern.matcher(INPUT);
       matcher2 = pattern.matcher(INPUT2);
       System.out.println("Current REGEX is: "+REGEX);
       System.out.println("Current INPUT is: "+INPUT);
       System.out.println("Current INPUT2 is: "+INPUT2);
       System.out.println("lookingAt(): "+matcher.lookingAt());
       System.out.println("matches(): "+matcher.matches());
       System.out.println("lookingAt(): "+matcher2.lookingAt());
   }
}

以上实例编译运行结果如下:

bash 复制代码
Current REGEX is: foo
Current INPUT is: fooooooooooooooooo
Current INPUT2 is: ooooofoooooooooooo
lookingAt(): true
matches(): false
lookingAt(): false

1.5.3 replaceFirst 和 replaceAll 方法:

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

下面的例子来解释这个功能:

java 复制代码
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches
{
    private static String REGEX = "dog";
    private static String INPUT = "The dog says meow. " + "All dogs say meow.";
    private static String REPLACE = "cat";
    public static void main(String[] args) {
       Pattern p = Pattern.compile(REGEX);
       // get a matcher object
       Matcher m = p.matcher(INPUT);
       INPUT = m.replaceAll(REPLACE);
       System.out.println(INPUT);
   }
}

以上实例编译运行结果如下:

bash 复制代码
The cat says meow. All cats say meow.

1.5.4 appendReplacement 和 appendTail 方法

Matcher 类也提供了appendReplacement 和 appendTail 方法用于文本替换:

看下面的例子来解释这个功能:

java 复制代码
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches
{
   private static String REGEX = "a*b";
   private static String INPUT = "aabfooaabfooabfoobkkk";
   private static String REPLACE = "-";
   public static void main(String[] args) {
      Pattern p = Pattern.compile(REGEX);
      // 获取 matcher 对象
      Matcher m = p.matcher(INPUT);
      StringBuffer sb = new StringBuffer();
      while(m.find()){
         m.appendReplacement(sb,REPLACE);

      }
      m.appendTail(sb);
      System.out.println(sb.toString());
   }
}

以上实例编译运行结果如下:

bash 复制代码
-foo-foo-foo-kkk

1.5.5 PatternSyntaxException 类的方法

PatternSyntaxException 是一个非强制异常类,它指示一个正则表达式模式中的语法错误。

PatternSyntaxException 类提供了下面的方法来帮助我们查看发生了什么错误。

java 复制代码
public String getDescription();---------------- 获取错误的描述。
public int getIndex();----------------- 获取错误的索引。
public String getPattern();--------------- 获取错误的正则表达式模式。

//返回多行字符串,包含语法错误及其索引的描述、错误的正则表达式模式和模式中错误索引的可视化指示。
public String getMessage();

2. ❤️Java基础专栏 - 前篇回顾

3. 💕👉 其他好文推荐

相关推荐
咬光空气3 分钟前
Qt 5.14.2 学习记录 —— 오 信号与槽机制(2)
开发语言·qt·学习
Stimd6 分钟前
【重写SpringFramework】第三章小结(chapter 3-16)
java·后端·spring
潜洋15 分钟前
Spring Boot教程之五十二:CrudRepository 和 JpaRepository 之间的区别
java·大数据·数据库·spring boot
Toormi16 分钟前
Python中协程间通信的方式有哪些?
开发语言·网络·python
Code花园18 分钟前
Bash语言的编程范式
开发语言·后端·golang
2401_8984106919 分钟前
MDX语言的网络编程
开发语言·后端·golang
念念不忘 必有回响21 分钟前
python初体验: 处理excel数据
开发语言·python·excel
代码驿站52026 分钟前
Bash语言的正则表达式
开发语言·后端·golang
编程|诗人26 分钟前
Bash语言的数据库编程
开发语言·后端·golang
TENET信条29 分钟前
代码随想录 day62 第十一章 图论part11
开发语言·python·图论