
本文介绍如何使用正则表达式精准提取两个相同单词(作为起止标记)之间的子字符串,避免误匹配子串(如“is”不匹配“this”),并提供可直接运行的 java 8+ 示例代码与关键注意事项。
在实际字符串处理中,常需提取位于两个相同完整单词之间的内容(例如 "this is an example to extract sentence between is" 中,以单词 "is" 为前后边界,提取中间的 "an example to extract sentence between")。注意:这里的 "is" 必须是独立单词(word boundary),不能是其他单词的子串(如 "this" 或 "ising" 应被忽略)。
直接使用 indexOf() 手动查找起止位置容易出错——正如提问中所示,它会将第一个 "is"(在 "this" 中)误判为起点,或无法保证两次匹配均为完整单词。更可靠的方式是采用基于单词边界的正则表达式,利用 (?
以下是推荐的 Java 实现(兼容 Java 8+,无需额外依赖):
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class SubstringBetweenSameWord {
public static void main(String[] args) {
String originalString = "this is an example to extract sentence between is";
String delimiter = "is";
// 构建动态正则:要求前后均为完整单词 \b{delimiter}\b
String regex = "(?<=\\b" + Pattern.quote(delimiter) + "\\b)(.*?)(?=\\b" + Pattern.quote(delimiter) + "\\b)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(originalString);
if (matcher.find()) {
System.out.println(matcher.group(1).trim()); // 输出:an example to extract sentence between
} else {
System.out.println("未找到有效的成对边界词");
}
}
}✅ 关键要点说明:
- 使用 Pattern.quote(delimiter) 防止分隔符含正则元字符(如 "a.b")导致编译失败;
- \\b 表示单词边界,确保 "is" 不会从 "this" 或 "island" 中误匹配;
- .*? 采用非贪婪匹配,避免跨多组边界时过度捕获;
- trim() 清除可能的首尾空格,提升结果可用性;
- 若字符串中存在多个 "is",该正则默认匹配第一对有效闭合区间(即首个起始 "is" 与之后最近的结束 "is");如需全部匹配,可循环调用 matcher.find()。
⚠️ 注意事项:
- Apache Commons Lang 的 StringUtils.substringBetween() 仅支持不同的 start/end 字符串(如 substringBetween(str, "start", "end")),不适用于本场景;
- 纯 indexOf() 方案需手动校验单词边界(如结合空格/标点判断),逻辑复杂且易出错,不建议用于生产环境;
- 若分隔符可能出现在句首或句尾(如 "is hello world is"),当前逻辑仍适用;但若仅有单个 "is",则 matcher.find() 返回 false,应做好空值处理。
综上,正则表达式是解决“相同单词边界间提取”问题最简洁、健壮且符合语义的方式,兼顾准确性与可维护性。










