
本文介绍如何使用正则表达式精准提取两个相同单词(作为起止标记)之间的子字符串,避免误匹配子串(如“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";
// 构建动态正则:要求前后均为完整单词 {delimiter}
String regex = "(?<p>✅ <strong>关键要点说明:</strong> </p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill13063" title="Java Development Man"><img
src="https://img.php.cn/upload/skill/001/246/273/6adaf20e695c2374.jpg" alt="Java Development Man" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill13063" title="Java Development Man" class="overflowclass">Java Development Man</a>
<p class="overflowclass">Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。</p>
</div>
<a rel="nofollow" href="/xiazai/skill13063" title="Java Development Man" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
- 使用 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,应做好空值处理。
综上,正则表达式是解决“相同单词边界间提取”问题最简洁、健壮且符合语义的方式,兼顾准确性与可维护性。










