ZetCode

Java Matcher.regionEnd 方法

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

Matcher.regionEnd 方法是 Java 正则表达式 API 的一部分。它返回此匹配器当前区域的结束索引(不包括)。该区域定义了匹配器操作的范围。

当您想将模式匹配限制到输入序列的特定部分时,区域非常有用。该区域从 regionStart 开始,延伸到 regionEnd。默认情况下,该区域覆盖整个输入。

Matcher.regionEnd 基础

regionEnd 方法返回当前匹配区域的结束索引。这是将被搜索的最后一个字符之后的索引。该方法通常与 regionStartregion 一起使用。

更改区域会影响所有后续匹配操作。索引从零开始,并且结束索引不包括在内。这意味着匹配在到达结束索引之前停止。

regionEnd 基本示例

此示例演示如何使用 regionEnd 获取当前区域边界。我们将创建一个匹配器并检查其默认区域设置。

RegionEndBasic.java
package com.zetcode;

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

public class RegionEndBasic {
    
    public static void main(String[] args) {

        String input = "The quick brown fox jumps over the lazy dog";
        Pattern pattern = Pattern.compile("fox");
        Matcher matcher = pattern.matcher(input);

        // Get default region end (entire input length)
        int end = matcher.regionEnd();
        System.out.println("Default region end: " + end);
        System.out.println("Input length: " + input.length());

        // Find matches within default region
        while (matcher.find()) {
            System.out.println("Found at: " + matcher.start());
        }
    }
}

在此示例中,我们创建一个匹配器,其默认区域覆盖整个输入字符串。regionEnd 方法返回与输入长度相同的值。匹配器在完整字符串中查找所有 "fox" 的出现。

设置自定义区域

在这里,我们将设置一个自定义区域,并使用 regionEnd 来验证新的边界。匹配器将仅在指定的区域内搜索。

RegionEndCustom.java
package com.zetcode;

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

public class RegionEndCustom {
    
    public static void main(String[] args) {
        String input = "Java 8, Java 11, Java 17";
        Pattern pattern = Pattern.compile("Java \\d+");
        Matcher matcher = pattern.matcher(input);

        // Set custom region (first 10 characters)
        matcher.region(0, 10);
        System.out.println("Region start: " + matcher.regionStart());
        System.out.println("Region end: " + matcher.regionEnd());

        // Find matches within custom region
        while (matcher.find()) {
            System.out.println("Found: " + matcher.group());
        }
    }
}

此示例将搜索限制为输入的前 10 个字符。匹配器仅找到 "Java 8",因为 "Java 11" 从位置 8 开始,但超出我们 10 的区域结束位置。regionEnd 确认了我们的边界。

带有多个区域的 RegionEnd

此示例显示了更改区域如何影响匹配行为。我们将使用 regionEnd 来验证每个区域的边界。

RegionEndMultiple.java
package com.zetcode;

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

public class RegionEndMultiple {
    
    public static void main(String[] args) {
        String input = "apple banana cherry date elderberry";
        Pattern pattern = Pattern.compile("[a-z]+");
        Matcher matcher = pattern.matcher(input);

        // First region: first 15 characters
        matcher.region(0, 15);
        System.out.println("Region 1 end: " + matcher.regionEnd());
        System.out.println("Matches in region 1:");
        while (matcher.find()) {
            System.out.println(matcher.group());
        }

        // Second region: characters 10-25
        matcher.region(10, 25);
        System.out.println("\nRegion 2 end: " + matcher.regionEnd());
        System.out.println("Matches in region 2:");
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
    }
}

我们在此示例中演示了两个不同的区域。第一个区域捕获 "apple" 和 "banana"。第二个区域从 "banana" 的中间开始,并捕获 "cherry" 和 "date"。regionEnd 帮助验证每个区域的边界。

带有锚点的 RegionEnd

区域边界会影响像 ^ 和 $ 这样的锚点的行为。此示例显示了区域和锚点之间的交互,并使用 regionEnd 来确认匹配区域。

RegionEndAnchors.java
package com.zetcode;

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

public class RegionEndAnchors {

    public static void main(String[] args) {

        String input = "start\nmiddle\nend";
        Pattern pattern = Pattern.compile("^end$", Pattern.MULTILINE);
        Matcher matcher = pattern.matcher(input);

        // Full input region
        System.out.println("Full region end: " + matcher.regionEnd());
        System.out.println("Matches in full region:");
        while (matcher.find()) {
            System.out.println("Found at: " + matcher.start());
        }

        // Restricted region (excludes last line)
        matcher.region(0, input.indexOf("\nend"));
        System.out.println("\nRestricted region end: " + matcher.regionEnd());
        System.out.println("Matches in restricted region:");
        while (matcher.find()) {
            System.out.println("Found at: " + matcher.start());
        }
    }
}

使用完整区域,匹配器在输入的末尾找到 "end"。当我们限制区域以排除最后一行时,锚点不再匹配。regionEnd 帮助我们理解为什么匹配在第二种情况下失败。

带有 Reset 的 RegionEnd

reset 方法会影响匹配器的区域。此示例显示了 reset 如何将区域边界更改回默认值。

RegionEndReset.java
package com.zetcode;

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

public class RegionEndReset {
    
    public static void main(String[] args) {
        String input = "one two three four five";
        Pattern pattern = Pattern.compile("\\w+");
        Matcher matcher = pattern.matcher(input);

        // Set custom region
        matcher.region(4, 12);
        System.out.println("Custom region end: " + matcher.regionEnd());

        // Reset matcher
        matcher.reset();
        System.out.println("After reset, region end: " + matcher.regionEnd());

        // Verify matches in default region
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
    }
}

设置自定义区域后,reset 将匹配器恢复到其原始状态,该区域覆盖整个输入。regionEnd 值会相应更改,并且后续匹配会扫描完整的输入字符串。

带有透明边界的 RegionEnd

此高级示例演示了 useTransparentBounds 如何影响区域边界处的匹配。我们将使用 regionEnd 来跟踪区域大小。

RegionEndTransparent.java
package com.zetcode;

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

public class RegionEndTransparent {
    
    public static void main(String[] args) {
        String input = "abcdefghijklmnop";
        Pattern pattern = Pattern.compile("defghijk");
        Matcher matcher = pattern.matcher(input);

        // Set region that excludes part of the pattern
        matcher.region(2, 9);
        System.out.println("Region end: " + matcher.regionEnd());

        // Try matching with opaque bounds (default)
        System.out.println("With opaque bounds: " + matcher.matches());

        // Enable transparent bounds
        matcher.useTransparentBounds(true);
        System.out.println("With transparent bounds: " + matcher.matches());
    }
}

使用不透明边界(默认),匹配器失败,因为模式超出区域结束。使用透明边界,先行/后顾可以看到超出区域。regionEnd 帮助我们理解行为发生变化的边界。

RegionEnd 性能考虑

此示例显示了使用区域如何通过限制搜索区域来提高性能。我们将使用 regionEnd 来验证我们限制的搜索。

RegionEndPerformance.java
package com.zetcode;

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

public class RegionEndPerformance {

    public static void main(String[] args) {
        
        // Large input with target near start
        StringBuilder sb = new StringBuilder();
        sb.append("target");
        sb.append("x".repeat(100000));

        String input = sb.toString();

        Pattern pattern = Pattern.compile("target");
        Matcher matcher = pattern.matcher(input);

        // Limit search to first 100 characters
        matcher.region(0, 100);
        System.out.println("Restricted region end: " + matcher.regionEnd());

        long startTime = System.nanoTime();
        boolean found = matcher.find();
        long duration = System.nanoTime() - startTime;

        System.out.println("Found: " + found);
        System.out.println("Search time (ns): " + duration);
    }
}

通过将区域限制为前 100 个字符,我们避免了扫描整个大字符串。regionEnd 确认了我们的搜索边界。当您知道匹配位置时,此技术可以显著提高性能。

来源

Java Matcher.regionEnd 文档

在本教程中,我们探讨了 Matcher.regionEnd 方法及其在正则表达式区域操作中的作用。理解区域对于 Java 中高效且有针对性的模式匹配至关重要。

作者

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

列出所有Java教程