439. Java 正则表达式 - 字符串字面量与元字符

7 阅读3分钟

439. Java 正则表达式 - 字符串字面量与元字符

1. 字符串字面量匹配(String Literals)

正则表达式最基础的功能就是 匹配一个固定的字符串。 👉 如果正则表达式是 "foo",输入字符串也是 "foo",匹配就会成功。

🌰 示例

    public static void main(String[] args) {
        java.util.Scanner scanner = new java.util.Scanner(System.in);

        System.out.println("\n=== 正则表达式交互式测试 ===");
        System.out.println("提示: 输入 'quit' 退出程序\n");

        while (true) {
            System.out.print("Enter your regex: ");
            String regexInput = scanner.nextLine();

            if ("quit".equalsIgnoreCase(regexInput)) {
                System.out.println("程序已退出");
                break;
            }

            try {
                Pattern userPattern = Pattern.compile(regexInput);

                System.out.print("Enter input string to search: ");
                String inputString = scanner.nextLine();

                Matcher userMatcher = userPattern.matcher(inputString);

                boolean found = false;
                while (userMatcher.find()) {
                    found = true;
                    System.out.printf("I found the text \"%s\" starting at index %d and ending at index %d.%n",
                            userMatcher.group(), userMatcher.start(), userMatcher.end());
                }

                if (!found) {
                    System.out.println("No match found.");
                }

            } catch (Exception e) {
                System.out.println("正则表达式错误: " + e.getMessage());
            }

            System.out.println(); // 空行分隔
        }

        scanner.close();
    }
Enter your regex: foo
Enter input string to search: foo
I found the text foo starting at index 0 and ending at index 3.

这里有几个细节:

  • 输入 "foo" 长度是 3,但结果显示:
    • start index = 0
    • end index = 3
  • 为什么?因为正则里的索引范围是:
    • 起始索引 inclusive(包含)
    • 结束索引 exclusive(不包含)

👉 用一个图来帮助理解:

String:   f   o   o
Index:   0   1   2   3
  • "foo" 实际占用的是 0, 1, 2 三个单元格
  • 但结束索引指向 3(相当于最后一个字符的“后面”)

🌰 连续匹配的例子

Enter your regex: foo
Enter input string to search: foofoofoo
I found the text foo starting at index 0 and ending at index 3.
I found the text foo starting at index 3 and ending at index 6.
I found the text foo starting at index 6 and ending at index 9.

👉 可以看到,下一个匹配的开始位置就是上一个匹配的结束位置。这就是正则引擎的匹配机制。


2. 元字符(Metacharacters)

正则表达式并不仅仅是匹配固定字符串,它有一组 特殊字符(metacharacters),能让匹配变得更灵活。

🌰 示例:.(点号)

如果正则表达式是 "cat.",输入字符串是 "cats",结果如下:

Enter your regex: cat.
Enter input string to search: cats
I found the text cats starting at index 0 and ending at index 4.

👉 注意:虽然输入中没有写 .,但匹配依然成功。 原因是:. 是一个元字符,表示 任意单个字符。 所以 "cat." 可以匹配:

  • "cats"
  • "cata"
  • "cat!"
  • "cat?" 等等。

Java 正则里的元字符列表

<([{\^-=$!|]})?*+.>

这些符号在正则表达式里都有特殊含义。 👉 但注意:像 @# 这样的符号永远没有特殊含义,始终是普通字符。


3. 如何匹配“普通的元字符”

有时我们并不想让 . 当作“任意字符”,而是就想匹配一个真正的点号 "."。 👉 这时有两种方式:

  1. 用反斜杠 \ 转义

    Pattern p = Pattern.compile("cat\\.");
    Matcher m = p.matcher("This is a cat.");
    System.out.println(m.find()); // true
    
    • "cat\\." 表示 匹配字面量字符串 "cat."
    • 之所以要写两个 \\,是因为在 Java 字符串里 \ 也需要转义。
  2. \Q...\E 引用区块

    Pattern p = Pattern.compile("\\Qcat.\\E");
    Matcher m = p.matcher("This is a cat.");
    System.out.println(m.find()); // true
    
    • \Q 开始转义,直到 \E 结束。
    • 中间的所有字符都会被当作普通字符。
    • 所以 "\\Qcat.\\E" 等价于 "cat\\."

4. 小结 ✅

  • 字符串字面量:正则 "foo" 匹配输入 "foo"
  • 索引规则:开始索引包含,结束索引不包含
  • 元字符. 表示任意单字符
  • 转义方法
    • \\ 转义(常见方式)
    • \Q...\E 包裹

🎤QA

  • 让学员尝试写出一个能匹配 "1+1=2" 的正则(需要转义 +=
  • 提问:".*" 能匹配什么内容?
  • 提问:"foo.""foo\\." 有什么区别?