正则表达式无法替换双引号内末尾竖线的问题修正请求
处理带引号的竖线分隔字符串分割问题
问题背景
有一条以竖线|作为分隔符的文件记录字符串:
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
相关产品推荐
相关产品推荐

