ZetCode

Java Matcher.hasTransparentBounds 方法

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

hasTransparentBounds 方法是 Java 的 java.util.regex.Matcher 类的一部分。它检查是否为模式匹配操作启用了透明边界。此设置会影响边界匹配器在区域边界处的行为。

透明边界允许先行、后行和边界匹配器在匹配时查看超出区域边界的内容。当您需要在当前匹配区域之外的上下文时,这很有用。默认值为 false。

基本定义

MatcherPattern 创建,并在字符序列上执行匹配操作。区域定义了要搜索的输入序列的一部分。透明边界会影响区域边缘的边界匹配。

当启用透明边界时,像 ^$\b\B 这样的边界匹配器可以看到当前区域之外的文本。这在某些情况下允许更灵活的匹配。

检查默认透明边界

此示例显示了如何检查默认的透明边界设置。默认情况下,在新的 Matcher 实例中,透明边界是禁用的。

TransparentBoundsDefault.java
package com.zetcode;

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

public class TransparentBoundsDefault {

    public static void main(String[] args) {
        
        Pattern pattern = Pattern.compile("^Java$");
        Matcher matcher = pattern.matcher("Java Programming");
        
        // Check default transparent bounds setting
        boolean hasTransparent = matcher.hasTransparentBounds();
        System.out.println("Default transparent bounds: " + hasTransparent);
        
        // Try to match with default settings
        boolean matches = matcher.matches();
        System.out.println("Matches with default bounds: " + matches);
    }
}

在此示例中,我们创建一个简单的模式,该模式匹配确切的字符串 "Java"。Matcher 是使用输入 "Java Programming" 创建的。默认情况下,透明边界为 false,因此锚点 ^ 和 $ 匹配整个输入,而不仅仅是区域。

启用透明边界

此示例演示了如何使用 useTransparentBounds 方法启用透明边界,然后使用 hasTransparentBounds 检查设置。

EnableTransparentBounds.java
package com.zetcode;

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

public class EnableTransparentBounds {

    public static void main(String[] args) {
        
        Pattern pattern = Pattern.compile("\\bJava\\b");
        Matcher matcher = pattern.matcher("Learning Java Programming");
        
        // Set a region that excludes the word "Java"
        matcher.region(0, 8); // "Learning "
        
        // Enable transparent bounds
        matcher.useTransparentBounds(true);
        
        // Verify transparent bounds are enabled
        System.out.println("Transparent bounds enabled: " + 
            matcher.hasTransparentBounds());
            
        // Attempt to find the word boundary
        boolean found = matcher.find();
        System.out.println("Word boundary found: " + found);
    }
}

在这里,我们设置一个不包含目标词 "Java" 的区域。启用透明边界后,单词边界匹配器 \b 可以看到超出区域的范围。这允许它正确匹配边界,即使 "Java" 在当前区域之外。

透明边界与锚点

此示例显示了透明边界如何影响区域边界处的锚点匹配。锚点(如 ^ 和 $)在使用透明边界时表现不同。

TransparentBoundsAnchors.java
package com.zetcode;

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

public class TransparentBoundsAnchors {

    public static void main(String[] args) {
        
        String input = "Start Middle End";
        Pattern pattern = Pattern.compile("^Middle$");
        Matcher matcher = pattern.matcher(input);
        
        // Set region to "Middle"
        matcher.region(6, 12);
        
        // Without transparent bounds
        System.out.println("Without transparent bounds:");
        boolean matches = matcher.matches();
        System.out.println("Matches: " + matches);
        
        // With transparent bounds
        matcher.useTransparentBounds(true);
        System.out.println("\nWith transparent bounds:");
        matches = matcher.matches();
        System.out.println("Matches: " + matches);
        System.out.println("Has transparent bounds: " + 
            matcher.hasTransparentBounds());
    }
}

没有透明边界时,锚点 ^ 和 $ 匹配区域边界。启用透明边界后,它们将匹配实际的输入边界。这显示了透明边界如何影响区域边缘的锚点匹配行为。

透明边界与环视

此示例演示了透明边界如何影响区域边界处的先行断言和后行断言。当启用透明边界时,这些断言可以看到超出区域的范围。

TransparentBoundsLookaround.java
package com.zetcode;

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

public class TransparentBoundsLookaround {

    public static void main(String[] args) {
        
        String input = "Prefix123Suffix";
        Pattern pattern = Pattern.compile("(?<=Prefix)\\d+(?=Suffix)");
        Matcher matcher = pattern.matcher(input);
        
        // Set region to exclude the prefix and suffix
        matcher.region(6, 9); // "123"
        
        // Without transparent bounds
        System.out.println("Without transparent bounds:");
        boolean found = matcher.find();
        System.out.println("Found: " + found);
        
        // With transparent bounds
        matcher.useTransparentBounds(true);
        System.out.println("\nWith transparent bounds:");
        found = matcher.find();
        System.out.println("Found: " + found);
        System.out.println("Has transparent bounds: " + 
            matcher.hasTransparentBounds());
    }
}

后行断言 (?<=Prefix) 和先行断言 (?=Suffix) 在没有透明边界的情况下失败,因为它们无法看到超出区域的范围。当启用透明边界时,它们可以看到周围的文本,并且匹配成功。

与不透明边界结合使用

此示例显示了如何将透明边界与不透明边界结合使用,以用于不同的匹配场景。不透明边界阻止环视看到超出区域的范围。

TransparentVsOpaqueBounds.java
package com.zetcode;

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

public class TransparentVsOpaqueBounds {

    public static void main(String[] args) {
        
        String input = "Before123After";
        Pattern pattern = Pattern.compile("\\d+(?=After)");
        Matcher matcher = pattern.matcher(input);
        
        // Set region to exclude "After"
        matcher.region(0, 9); // "Before123"
        
        // First with transparent bounds
        matcher.useTransparentBounds(true);
        System.out.println("With transparent bounds:");
        boolean found = matcher.find();
        System.out.println("Found: " + found);
        System.out.println("Has transparent bounds: " + 
            matcher.hasTransparentBounds());
        
        // Then with opaque bounds
        matcher.useTransparentBounds(false);
        System.out.println("\nWith opaque bounds:");
        found = matcher.find();
        System.out.println("Found: " + found);
        System.out.println("Has transparent bounds: " + 
            matcher.hasTransparentBounds());
    }
}

使用透明边界时,先行断言 (?=After) 可以看到超出区域的范围,并且匹配成功。使用不透明边界(透明边界为 false)时,先行断言失败,因为它看不到区域之外的 "After" 文本。

区域边界与单词边界

此示例演示了透明边界如何影响区域边界处的单词边界匹配。单词边界的行为取决于此设置。

TransparentBoundsWordBoundaries.java
package com.zetcode;

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

public class TransparentBoundsWordBoundaries {

    public static void main(String[] args) {
        
        String input = "Java Programming";
        Pattern pattern = Pattern.compile("\\bProgramming\\b");
        Matcher matcher = pattern.matcher(input);
        
        // Set region to exclude the word "Programming"
        matcher.region(0, 5); // "Java "
        
        // With transparent bounds
        matcher.useTransparentBounds(true);
        System.out.println("With transparent bounds:");
        boolean found = matcher.find();
        System.out.println("Found: " + found);
        System.out.println("Has transparent bounds: " + 
            matcher.hasTransparentBounds());
        
        // Without transparent bounds
        matcher.useTransparentBounds(false);
        System.out.println("\nWithout transparent bounds:");
        found = matcher.find();
        System.out.println("Found: " + found);
    }
}

启用透明边界后,单词边界 \b 可以看到 "Programming" 在区域之外,但仍然是一个有效的单词。没有透明边界时,Matcher 找不到单词边界,因为它无法看到超出区域的范围。

实际用例

此示例展示了在处理文本块时,透明边界在跨块边界保持上下文感知的一种实用用例。

TransparentBoundsPractical.java
package com.zetcode;

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

public class TransparentBoundsPractical {

    public static void main(String[] args) {
        
        String largeText = "First paragraph.\n\nSecond paragraph.\n\nThird.";
        Pattern pattern = Pattern.compile("(?m)^\\w+");
        Matcher matcher = pattern.matcher(largeText);
        
        // Process text in chunks
        int chunkSize = 20;
        for (int i = 0; i < largeText.length(); i += chunkSize) {
            int end = Math.min(i + chunkSize, largeText.length());
            matcher.region(i, end);
            matcher.useTransparentBounds(true);
            
            System.out.println("\nProcessing region: " + i + "-" + end);
            while (matcher.find()) {
                System.out.println("Found word at start of line: " + 
                    matcher.group());
            }
            
            System.out.println("Has transparent bounds: " + 
                matcher.hasTransparentBounds());
        }
    }
}

此示例将大文本分成块进行处理,同时使用透明边界来正确处理区域边界处的行首锚点 (^)。这确保了即使这些行跨越块边界,我们也能正确找到行首的单词。

来源

Java Matcher.hasTransparentBounds 文档

在本教程中,我们探讨了 hasTransparentBounds 方法及其对模式匹配的影响。理解此功能对于高级正则表达式操作至关重要,在这种情况下,区域边界和上下文感知至关重要。

作者

我叫 Jan Bodnar,是一位经验丰富的程序员,在该领域拥有多年经验。我从 2007 年开始撰写编程文章,此后撰写了 1,400 多篇文章和八本电子书。凭借超过八年的教学经验,我致力于分享我的知识并帮助他人掌握编程概念。

列出所有Java教程