You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

正则表达式无法替换双引号内末尾竖线的问题修正请求

处理带引号的竖线分隔字符串分割问题

问题背景

有一条以竖线|作为分隔符的文件记录字符串:

1234567890|ABCDE|""|"01|02|03|"|453625|New Account|05736372828|NA|||AT|899

核心需求:双引号"包裹范围内的|不能被当作分隔符,需作为单一文本内容保留(例如"01|02|03|"要作为一个整体字段)。

原尝试方案是先将引号内的|替换为逗号,,再用|分割字符串,但正则表达式未覆盖所有情况,导致"01|02|03|"中03后的|未被替换。

原代码及问题

原Java代码:

public static void main(String[] args) {
    String orig = "1234567890|ABCDE|\\\"\\\"|\\\"01|02|03|\\\"|453625|New Account|05736372828|NA|||AT|899";
    String regex = "(?<=\\\")([^\\\"]+?)\\|([^\\\"]+?)(?=\\\")";  
    String old = orig;
    String result = orig.replaceAll(orig, "$1,$2");  
    while (!result.equalsIgnoreCase(old)){  
        old = result;  
        result = result.replaceAll(regex, "$1,$2");  
    }
    System.out.println(result);
}

输出结果:

1234567890|ABCDE|""|"01,02,03|"|453625|New Account|05736372828|NA|||AT|899

问题根源:原正则(?<=\\")([^\\"]+?)\\|([^\\"]+?)(?=\\")要求|前后必须有非引号字符,而最后一个|直接紧邻右引号,无法满足([^\\"]+?)的匹配条件,因此被遗漏。


解决方案

方案1:修正替换正则

调整正则表达式,匹配引号内所有的|,无论其前后是否有内容:

public static void main(String[] args) {
    String orig = "1234567890|ABCDE|\\\"\\\"|\\\"01|02|03|\\\"|453625|New Account|05736372828|NA|||AT|899";
    // 匹配引号内的任意|
    String regex = "(?<=\")[^\"]*?\\|(?=[^\"]*\")";
    String result = orig.replaceAll(regex, m -> m.group().replace("|", ","));
    System.out.println(result);
}

输出结果:

1234567890|ABCDE|""|"01,02,03,"|453625|New Account|05736372828|NA|||AT|899

正则逻辑:

  • (?<=\"):正向后顾,确保当前位置前是左引号
  • [^\"]*?:非贪婪匹配任意非引号字符(覆盖空内容场景)
  • \\|:匹配目标竖线
  • (?=[^\"]*\"):正向预查,确保当前位置后有任意非引号字符+右引号(保证在引号范围内)

替换完成后,即可用|正常分割字符串。

方案2:直接分割(更高效)

跳过替换步骤,直接用正则匹配不在引号内的竖线作为分隔符:

import java.util.Arrays;
import java.util.regex.Pattern;

public static void main(String[] args) {
    String orig = "1234567890|ABCDE|\\\"\\\"|\\\"01|02|03|\\\"|453625|New Account|05736372828|NA|||AT|899";
    // 匹配不在引号内的竖线
    String splitRegex = "\\|(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)";
    String[] parts = orig.split(splitRegex);
    System.out.println(Arrays.toString(parts));
}

输出结果:

[1234567890, ABCDE, "", "01|02|03|", 453625, New Account, 05736372828, NA, , , AT, 899]

正则逻辑:

  • \\|:匹配竖线
  • (?=(?:[^\"]*\"[^\"]*\")*[^\"]*$):正向预查,确保竖线后面的引号总数为偶数(即该竖线不在引号包裹范围内)

此方案一步到位,无需额外替换操作,效率更高。


内容的提问来源于stack exchange,提问作者Aniket V

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 08:25:03