ZetCode

Java Pattern.flags 方法

上次修改时间:2025 年 4 月 20 日

Pattern.flags 方法返回在编译 Pattern 时指定的匹配标志。这些标志修改了在匹配操作期间如何解释正则表达式模式。

可以使用位 OR 运算组合标志以同时启用多个行为。该方法返回一个整数,表示 Pattern 实例的所有已启用标志的位掩码。

模式标志概述

Java 的 Pattern 类提供了几个可以改变正则表达式匹配行为的标志。常见的标志包括 CASE_INSENSITIVEMULTILINEDOTALL。每个标志都由 Pattern 类中的一个常量整数值表示。

当您需要检查编译的 Pattern 对象上哪些标志处于活动状态时,flags 方法非常有用。这有助于调试或创建具有类似设置的新 Pattern 实例。

基本 flags 方法用法

此示例演示了 flags 方法的基本用法,用于从编译的 Pattern 中检索标志。我们将创建具有不同标志组合的模式并检查它们的值。

PatternFlagsBasic.java
package com.zetcode;

import java.util.regex.Pattern;

public class PatternFlagsBasic {

    public static void main(String[] args) {
        
        // Pattern with no flags
        Pattern noFlags = Pattern.compile("abc");
        System.out.println("No flags: " + noFlags.flags());
        
        // Pattern with CASE_INSENSITIVE flag
        Pattern caseInsensitive = Pattern.compile("abc", Pattern.CASE_INSENSITIVE);
        System.out.println("CASE_INSENSITIVE: " + caseInsensitive.flags());
        
        // Pattern with multiple flags
        Pattern multiFlags = Pattern.compile("abc", 
            Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        System.out.println("Multiple flags: " + multiFlags.flags());
    }
}

在此示例中,我们创建了三个具有不同标志组合的 Pattern 实例。flags 方法返回一个整数,表示每个 Pattern 的所有已启用标志的位掩码。

输出将显示标志组合的数值。这些值可以与 Pattern 类的常量进行比较,以确定设置了哪些标志。

检查单个标志

此示例展示了如何使用 flags() 方法的返回值检查特定标志。我们将使用位运算来测试启用了哪些标志。

PatternCheckFlags.java
package com.zetcode;

import java.util.regex.Pattern;

public class PatternCheckFlags {

    public static void main(String[] args) {
        
        Pattern pattern = Pattern.compile("^[a-z]+$", 
            Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
        
        int flags = pattern.flags();
        
        System.out.println("All flags: " + flags);
        System.out.println("CASE_INSENSITIVE enabled: " + 
            ((flags & Pattern.CASE_INSENSITIVE) != 0));
        System.out.println("MULTILINE enabled: " + 
            ((flags & Pattern.MULTILINE) != 0));
        System.out.println("DOTALL enabled: " + 
            ((flags & Pattern.DOTALL) != 0));
        System.out.println("UNICODE_CASE enabled: " + 
            ((flags & Pattern.UNICODE_CASE) != 0));
    }
}

在这里,我们创建一个带有 CASE_INSENSITIVE 和 MULTILINE 标志的 Pattern。然后,我们使用位 AND 运算来检查在返回的 flags 值中设置了哪些单独的标志。

输出演示了如何验证 Pattern 配置中是否存在特定标志。此技术对于基于 Pattern 设置的条件逻辑很有用。

使用相同标志重建 Pattern

此示例展示了如何使用 flags 方法创建一个新的 Pattern,该 Pattern 与现有 Pattern 具有相同的标志。当您需要修改正则表达式但保持相同的匹配行为时,这很有用。

PatternReuseFlags.java
package com.zetcode;

import java.util.regex.Pattern;

public class PatternReuseFlags {

    public static void main(String[] args) {
        
        Pattern original = Pattern.compile("^start.*end$", 
            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
        
        // Get flags from original pattern
        int flags = original.flags();
        
        // Create new pattern with same flags but different regex
        Pattern modified = Pattern.compile("^begin.*finish$", flags);
        
        System.out.println("Original flags: " + original.flags());
        System.out.println("Modified flags: " + modified.flags());
        
        // Verify both patterns have same flags
        System.out.println("Flags match: " + 
            (original.flags() == modified.flags()));
    }
}

在此示例中,我们首先创建一个具有特定标志的 Pattern。然后,我们提取这些标志,并使用它们创建一个新的 Pattern,该 Pattern 具有不同的正则表达式,但具有相同的匹配行为。

当需要保留标志设置时,此技术可确保不同模式之间的一致匹配行为。

与 Pattern.quote 一起使用标志

此示例演示了标志与 Pattern.quote 的交互方式。对于使用 quote 创建的模式,flags 方法将返回 0,因为没有特殊的匹配行为应用于字面引用的字符串。

PatternQuoteFlags.java
package com.zetcode;

import java.util.regex.Pattern;

public class PatternQuoteFlags {

    public static void main(String[] args) {
        
        String regex = "[a-z]+";
        Pattern normalPattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
        
        // Create quoted pattern
        Pattern quotedPattern = Pattern.compile(Pattern.quote(regex));
        
        System.out.println("Normal pattern flags: " + normalPattern.flags());
        System.out.println("Quoted pattern flags: " + quotedPattern.flags());
        
        // Attempt to add flags to quoted pattern
        Pattern quotedWithFlags = Pattern.compile(Pattern.quote(regex), 
            Pattern.CASE_INSENSITIVE);
        
        System.out.println("Quoted with flags: " + quotedWithFlags.flags());
    }
}

此示例表明,Pattern.quote 默认创建没有标志的模式。即使指定了标志,它们对引用模式的匹配行为也没有任何影响,因为它们是字面匹配的。

输出演示了引用的模式保留其 flags 返回值,而与编译期间指定的任何标志无关。

标志和 Pattern.split

此示例检查标志如何影响 Pattern.split 方法。我们将看到不同的标志如何改变分割行为以及如何检查这些标志。

PatternSplitFlags.java
package com.zetcode;

import java.util.regex.Pattern;

public class PatternSplitFlags {

    public static void main(String[] args) {
        
        String input = "Apple\nBanana\nCherry";
        String regex = "^";
        
        // Split with MULTILINE flag
        Pattern multiline = Pattern.compile(regex, Pattern.MULTILINE);
        String[] multilineResult = multiline.split(input);
        System.out.println("Multiline split count: " + multilineResult.length);
        System.out.println("Multiline flags: " + multiline.flags());
        
        // Split without MULTILINE flag
        Pattern normal = Pattern.compile(regex);
        String[] normalResult = normal.split(input);
        System.out.println("Normal split count: " + normalResult.length);
        System.out.println("Normal flags: " + normal.flags());
    }
}

在此示例中,我们演示了 MULTILINE 标志如何影响 split 操作。使用 MULTILINE,^ 锚点匹配每行的开头,创建比没有标志时更多的分割。

flags 方法有助于验证每个 Pattern 实例上哪些标志处于活动状态,并解释它们的不同分割行为。

Pattern.matcher 中的标志继承

此示例显示 Matcher 实例从创建它们的 Pattern 继承其标志。flags 方法有助于确认这种继承。

PatternMatcherFlags.java
package com.zetcode;

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

public class PatternMatcherFlags {

    public static void main(String[] args) {
        
        Pattern pattern = Pattern.compile("^[a-z]+$", 
            Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
        
        Matcher matcher = pattern.matcher("Test");
        
        // Verify matcher uses pattern's flags
        System.out.println("Pattern flags: " + pattern.flags());
        System.out.println("Does 'Test' match? " + matcher.matches());
        
        // Change would require new Pattern with different flags
        Pattern noFlags = Pattern.compile("^[a-z]+$");
        Matcher strictMatcher = noFlags.matcher("Test");
        System.out.println("No flags pattern: " + noFlags.flags());
        System.out.println("Does 'Test' match now? " + strictMatcher.matches());
    }
}

此示例演示了 Matcher 实例无法修改其父 Pattern 的标志。flags 方法确认任何标志更改都需要创建一个新的 Pattern 实例。

输出显示了不同的标志设置如何影响匹配行为,以及 flags 方法如何帮助调试这些差异。

来源

Java Pattern.flags 文档

在本文中,我们深入探讨了 Pattern.flags 方法,展示了如何使用它来检查和处理 Java 中的正则表达式标志。

作者

我叫 Jan Bodnar,是一位经验丰富的程序员。自 2007 年以来,我开始撰写编程文章,至今已撰写了 1,400 多篇文章和 8 本电子书。凭借超过 8 年的教学经验,我致力于分享我的知识并帮助他人掌握编程概念。

列出所有Java教程