
本文介绍在 java 中通过正则表达式定位并移除以 * 开头、紧随其后的单词之后的英文双引号("),从而实现如 *sample" → *sample 的安全替换,避免误删其他位置的引号。
要解决该问题,关键在于精确匹配“星号 + 字母数字序列 + 双引号”这一结构,并仅移除末尾的引号,而保留其他上下文(如独立的 "test" 不受影响)。错误的思路(如 (?!.*"))使用了错误的否定逻辑,导致匹配范围失控;正确做法是采用捕获组 + 替换引用的方式。
✅ 推荐正则方案
String result = input.replaceAll("(\\*\\w+)\"", "$1");- (\*\w+):匹配一个 * 后接一个或多个字母、数字或下划线(\w 等价于 [a-zA-Z0-9_]),并将整个匹配内容捕获为第 1 组;
- ":字面量匹配一个英文双引号(不被捕获,因此会被替换操作删除);
- "$1":替换为第 1 组捕获的内容,即 *xxx 部分,从而实现“去引号不留痕”。
? 示例验证
String input = "value1: *sample\", test\n" +
"test: \"test\"\n" +
"newtest: *newtest\"";
String output = input.replaceAll("(\\*\\w+)\"", "$1");
System.out.println(output);输出结果:
value1: *sample, test test: "test" newtest: *newtest
完全符合预期:仅 *sample" 和 *newtest" 中的引号被清除,"test" 保持原样。
⚠️ 注意事项
- 若 * 后可能含连字符、点号等非 \w 字符(如 *my-value" 或 *v1.2"),需扩展字符类,例如改用 (\*[\w.-]+);
- Java 中反斜杠需转义,因此正则中写为 \\* 而非 \*;
- 该模式默认贪婪匹配,能正确处理 *abc" 而非误匹配更长的 *abc\"def"(因后续无引号,不满足整体模式);
- 如需支持 Unicode 字母(如中文变量名),可改用 (\*\p{L}\w*)(需确保 Java 版本 ≥ 7 且启用 Unicode 类别)。
综上,replaceAll("(\\*\\w+)\"", "$1") 是简洁、高效、可读性强的标准解法,兼顾准确性与工程实用性。










