如何更新Java正则表达式以忽略字符串末尾的换行符与双引号
问题原因分析
- 原正则的核心逻辑是通过正向预查判断逗号后方的双引号数量为偶数,以此确认当前逗号不在双引号包裹的区间内,只有满足条件的逗号才会作为分隔符
- 当字符串末尾新增单个双引号+换行后,整个字符串内双引号总数变为奇数,所有逗号后方的双引号数量都判定为奇数,导致没有逗号符合分隔条件,整个字符串不会被拆分
- 原正则中
[^"]默认会匹配换行符,末尾的换行不会中断预查逻辑的匹配
正则修改方案
调整预查的终止条件,允许字符串末尾出现单个未配对的双引号以及后续的空白字符即可,修改后的正则如下:
,(?=(?:[^"]*"[^"]*")*[^"]*(?:"?\s*\z))
修改说明
- 把原正则末尾的
$替换为(?:"?\s*\z):"?匹配末尾可选的单个未配对双引号\s*匹配双引号后方任意数量的空白字符(包含换行)\z严格匹配整个字符串的最终末尾,避免$在多行场景下匹配换行前位置的问题
- 该修改保留了原正则不拆分双引号内部逗号的核心能力,同时兼容末尾存在多余双引号和换行的场景
Java代码示例
import java.util.Arrays; public class TestRegex { public static void main(String args[]){ final String line = "a,b,c,,1,19,d,U,1,0,,0,7\"\n"; // Java字符串中双引号和反斜杠需要转义 final String[] row = line.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*(?:\"?\\s*\\z))", -1); // 仅在输出时移除元素末尾多余的双引号和空白,无需提前修改原字符串 Arrays.stream(row).map(element -> element.replaceAll("\"\\s*$", "")) .forEach(element -> System.out.println("element : "+element)); } }
输出结果
和最初的预期完全一致:
element : a element : b element : c element : element : 1 element : 19 element : d element : U element : 1 element : 0 element : element : 0 element : 7
内容的提问来源于stack exchange,提问作者thepen
相关产品推荐
相关产品推荐

