
本文介绍如何在 java 中精准提取位于**两个相同完整单词边界之间**的子字符串(如从 `"this is an example... is"` 中提取 `"an example to extract sentence between"`),并给出基于 `pattern` 和 `matcher` 的可靠正则方案,兼顾单词完整性与可读性。
要实现“以同一个单词作为起始和结束边界,提取中间内容”的需求,关键在于区分单词边界(word boundary)与子串匹配。原始代码失败的根本原因是:indexOf() 仅做朴素字符串查找,会将 "is" 在 "this" 中误匹配为起始位置,且未保证第二次出现的 "is" 是独立单词——导致 startIndex 和 endIndex 定位错误,最终截取到空或无效结果。
正确解法应使用正则表达式的单词边界断言(\b)配合环视(lookaround),确保只匹配作为独立单词出现的起始和结束标记。以下是推荐实现:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class SubstringExtractor {
public static String extractBetweenSameWord(String text, String word) {
if (text == null || word == null) return null;
// 构建正则:(?<=\bword\b) 向前看,要求左侧是完整单词;(?=\bword\b) 向后看,要求右侧是完整单词
String regex = "(?<=\\b" + Pattern.quote(word) + "\\b)(.*?)(?=\\b" + Pattern.quote(word) + "\\b)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(text);
return matcher.find() ? matcher.group(1).trim() : null;
}
public static void main(String[] args) {
String originalString = "this is an example to extract sentence between is";
String result = extractBetweenSameWord(originalString, "is");
System.out.println(result); // 输出:an example to extract sentence between
}
}✅ 关键设计说明:
- Pattern.quote(word):自动转义 word 中可能存在的正则元字符(如 "." 或 "*"),提升健壮性;
- \\b:单词边界,确保 "is" 不会匹配 "this" 或 "ising";
- (.*?):非贪婪捕获组,精确提取两边界间的最短有效内容;
- trim():去除首尾空白,使结果更符合自然语义。
⚠️ 注意事项:
- 该方法默认只匹配第一次成功闭合的区间(即首个起始词到其后最近的有效结束词)。若文本中存在嵌套或重叠(如 "is a is b is"),需根据业务逻辑调整策略(例如改用 while(matcher.find()) 遍历所有匹配);
- Java 标准库(含 Apache Commons Lang 3.x)无直接支持此类“同词首尾提取”的工具方法,StringUtils.substringBetween() 仅支持不同起止符(如 substringBetween(str, "[", "]")),不适用于本场景;
- 若需忽略大小写,可在 Pattern.compile(regex, Pattern.CASE_INSENSITIVE) 中添加标志。
综上,正则环视 + 单词边界是解决该问题最简洁、准确且可复用的方式,无需引入额外依赖,完全兼容 Java 8+。










