Java Matcher.hasAnchoringBounds 方法
上次修改时间:2025 年 4 月 20 日
Java 正则表达式包中的 Matcher.hasAnchoringBounds
方法检查匹配器是否正在使用锚定边界。锚定边界会影响 ^
和 $
元字符在匹配时的行为。
当启用锚定边界(默认)时,^
和 $
将在输入文本区域的开头和结尾进行匹配。当禁用时,它们仅在输入的实际开始/结束处匹配,忽略区域边界。
Matcher.hasAnchoringBounds 概述
hasAnchoringBounds
方法返回一个布尔值,指示是否启用了锚定边界。此设置由 useAnchoringBounds
方法控制。默认情况下,锚定边界已启用。
当处理输入文本的子区域时,锚定边界尤其重要。它们决定了模式锚点是否应该尊重当前的区域边界或完整的输入边界。
基本 hasAnchoringBounds 示例
此示例演示了锚定边界的默认行为以及如何使用 hasAnchoringBounds
检查其状态。我们将创建一个简单的匹配器并检查其锚定边界设置。
package com.zetcode; import java.util.regex.Matcher; import java.util.regex.Pattern; public class HasAnchoringBoundsBasic { public static void main(String[] args) { String input = "start middle end"; String regex = "^middle$"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(input); // Check default anchoring bounds status boolean hasBounds = matcher.hasAnchoringBounds(); System.out.println("Default hasAnchoringBounds: " + hasBounds); // Try to match with default bounds boolean matches = matcher.find(); System.out.println("Matches with default bounds: " + matches); } }
在此示例中,我们使用默认的锚定边界设置创建了一个匹配器。hasAnchoringBounds
方法返回 true
,表明锚定边界已启用。该模式匹配失败,因为 ^
和 $
遵循完整的输入边界。
禁用锚定边界
此示例展示了如何使用 useAnchoringBounds(false)
禁用锚定边界,并使用 hasAnchoringBounds
验证更改。我们将看到这如何影响模式匹配。
package com.zetcode; import java.util.regex.Matcher; import java.util.regex.Pattern; public class DisableAnchoringBounds { public static void main(String[] args) { String input = "start middle end"; String regex = "^middle$"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(input); // Disable anchoring bounds matcher.useAnchoringBounds(false); System.out.println("After disabling: " + matcher.hasAnchoringBounds()); // Try to match with disabled bounds boolean matches = matcher.find(); System.out.println("Matches with disabled bounds: " + matches); } }
调用 useAnchoringBounds(false)
后,hasAnchoringBounds
方法返回 false
。该模式仍然不匹配,因为我们正在搜索整个输入。锚点现在引用完整的输入边界。
带有区域的锚定边界
此示例演示了锚定边界如何与区域设置交互。我们将设置输入的子区域,并观察锚定边界如何影响匹配。
package com.zetcode; import java.util.regex.Matcher; import java.util.regex.Pattern; public class AnchoringBoundsWithRegion { public static void main(String[] args) { String input = "start middle end"; String regex = "^middle$"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(input); // Set region to "middle" matcher.region(6, 12); // With anchoring bounds (default) boolean matchesWithBounds = matcher.find(); System.out.println("With anchoring bounds: " + matchesWithBounds); // Without anchoring bounds matcher.useAnchoringBounds(false); boolean matchesWithoutBounds = matcher.find(); System.out.println("Without anchoring bounds: " + matchesWithoutBounds); } }
启用锚定边界(默认)时,^
和 $
在区域边界处匹配,因此该模式匹配。禁用时,锚点引用完整的输入边界,导致匹配失败。
带有多行输入的锚定边界
此示例探讨了锚定边界如何与多行输入和 MULTILINE
标志交互。我们将看到不同的组合如何影响匹配。
package com.zetcode; import java.util.regex.Matcher; import java.util.regex.Pattern; public class AnchoringBoundsMultiline { public static void main(String[] args) { String input = "first line\nsecond line\nthird line"; String regex = "^second$"; // With MULTILINE flag Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE); Matcher matcher = pattern.matcher(input); System.out.println("With MULTILINE and anchoring bounds:"); System.out.println("hasAnchoringBounds: " + matcher.hasAnchoringBounds()); while (matcher.find()) { System.out.println("Found at: " + matcher.start()); } // Without MULTILINE flag matcher = Pattern.compile(regex).matcher(input); matcher.useAnchoringBounds(false); System.out.println("\nWithout MULTILINE, no anchoring bounds:"); while (matcher.find()) { System.out.println("Found at: " + matcher.start()); } } }
使用 MULTILINE
标志时,^
在行终止符之后匹配,而与锚定边界无关。没有 MULTILINE
且禁用锚定边界时,^
仅在输入的绝对开头匹配。
锚定边界对性能的影响
此示例检查锚定边界是否影响匹配性能。我们将比较启用和禁用锚定边界时的匹配时间。
package com.zetcode; import java.util.regex.Matcher; import java.util.regex.Pattern; public class AnchoringBoundsPerformance { public static void main(String[] args) { String input = "sample text ".repeat(100000) + "target"; String regex = "^target$"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(input); // With anchoring bounds (default) long startTime = System.nanoTime(); boolean found = matcher.find(); long duration = System.nanoTime() - startTime; System.out.printf("With anchoring bounds: %d ns, found: %b%n", duration, found); // Without anchoring bounds matcher.useAnchoringBounds(false); startTime = System.nanoTime(); found = matcher.find(); duration = System.nanoTime() - startTime; System.out.printf("Without anchoring bounds: %d ns, found: %b%n", duration, found); } }
锚定边界对性能的影响通常可以忽略不计。这两个版本都以相似的时间完成,因为正则表达式引擎优化了锚点匹配。主要区别在于匹配行为,而不是性能。
带有重置的锚定边界
此示例展示了 reset
方法如何影响锚定边界设置。我们将验证重置匹配器后边界设置是否保留。
package com.zetcode; import java.util.regex.Matcher; import java.util.regex.Pattern; public class AnchoringBoundsReset { public static void main(String[] args) { String input = "test string"; Pattern pattern = Pattern.compile("^test"); Matcher matcher = pattern.matcher(input); // Change anchoring bounds matcher.useAnchoringBounds(false); System.out.println("Before reset: " + matcher.hasAnchoringBounds()); // Reset matcher matcher.reset(); System.out.println("After reset: " + matcher.hasAnchoringBounds()); // Reset with new input matcher.reset("new input"); System.out.println("After reset with new input: " + matcher.hasAnchoringBounds()); } }
reset
方法保留锚定边界设置,无论是否使用新的输入字符串调用。这表明边界设置是匹配器的属性,而不是其当前状态的属性。
来源
Java Matcher.hasAnchoringBounds 文档
在本文中,我们探讨了 Matcher.hasAnchoringBounds
方法及其对 Java 中正则表达式匹配的影响。在使用输入区域或多行文本时,理解锚定边界至关重要。
作者
列出所有Java教程。