
本文介绍如何使用正则表达式从含中英文引号(" 和 ”)的字符串中安全提取引号包围的主体名称,并自动裁剪引号外的前后冗余文本,适用于银行名、机构名等国际化字符串清洗场景。
本文介绍如何使用正则表达式从含中英文引号(`"` 和 `”`)的字符串中安全提取引号包围的主体名称,并自动裁剪引号外的前后冗余文本,适用于银行名、机构名等国际化字符串清洗场景。
在实际业务开发中(如金融数据解析、OCR 后处理或 API 响应清洗),常遇到类似 ( BANK "BTB” AÇIQ SƏHMDAR CƏMİYYƏTİ ) 这类混合了直角双引号(",U+0022)和右向弯引号(”,U+201D)的字符串。用户目标并非简单“删除引号”,而是精准捕获引号内有效名称(如 BTB),同时丢弃引号前后的无关词与后续长尾文本——这要求正则具备识别成对异构引号、锚定结构边界、并保留核心内容的能力。
直接使用 String.replace() 或多次 replaceAll() 无法满足该结构化提取需求;而原始代码中分别匹配两种引号、再用 group(1) 覆盖原字符串的方式存在严重逻辑缺陷:它未限定引号位置,导致匹配到任意子串(如 "BTB” 后的空格或单词),且循环调用 matcher.find() + 赋值会因字符串重赋值导致后续匹配失效。
✅ 正确解法是单次、原子性地匹配整个“前置非引号内容 + 左引号 + 名称 + 右引号 + 后续任意内容”模式,并通过捕获组重组结果:
String input = "BANK \"BTB” AÇIQ SƏHMDAR CƏMİYYƏTİ";
String output = input.replaceAll("^([^\"”]*)[\"”]([^\"”]+)[\"”].*$", "$1$2");
System.out.println(output); // 输出:BANK BTB? 正则详解:
立即学习“Java免费学习笔记(深入)”;
- ^:字符串起始锚点,确保从头匹配;
- ([^\"”]*):第1组,匹配零个或多个非引号字符(即引号前的内容,如 "BANK ");
- [\"”]:匹配任一左引号(" 或 ”);
- ([^\"”]+):第2组,匹配一个或多个非引号字符(即引号内有效名称,如 "BTB");
- [\"”]:匹配对应的右引号(与左引号类型无需严格配对,因业务中常混用);
- .*$:匹配右引号后所有内容(含空格、单词、标点等);
- "$1$2":仅保留第1组(前置文本)与第2组(名称)拼接,实现“去引号 + 截断尾部”。
⚠️ 注意事项:
- 若字符串中无引号,该正则不匹配,output 等于原 input,行为安全;
- 若存在多对引号,此正则仅匹配第一对(符合“提取首个有效名称”的常见需求);如需提取全部,应改用 Pattern.compile(...).matcher(...) 遍历 find();
- 弯引号 ”(U+201D)与直引号 "(U+0022)在正则中需显式列出,Java 字符串中直接写入即可(确保源文件编码为 UTF-8);
- 生产环境建议将正则编译为 static final Pattern 提升性能,并增加空值校验:
public static String extractQuotedName(String input) { if (input == null || input.trim().isEmpty()) return input; return input.replaceAll("^([^\"”]*)[\"”]([^\"”]+)[\"”].*$", "$1$2").trim(); }
该方案兼顾准确性、可读性与国际化兼容性,是处理混用引号字符串的推荐实践。










