Java 在逗号处拆分字符串,但避免转义逗号和反斜杠
我想在逗号处拆分一个字符串,“”。该字符串包含转义逗号Java 在逗号处拆分字符串,但避免转义逗号和反斜杠,java,regex,string,escaping,Java,Regex,String,Escaping,我想在逗号处拆分一个字符串,“”。该字符串包含转义逗号“\,”和转义反斜杠“\\”。开头和结尾的逗号以及一行中的多个逗号应导致空字符串 所以“,\,\,\,,,”应该变成,,,,,,,,, 请注意,我的示例字符串显示反斜杠为single“\”。Java字符串将使它们加倍 我尝试了几个软件包,但没有成功。我的最后一个想法是编写自己的解析器。 当然,一个专门的图书馆是一个好主意,但以下几点会起作用 公共静态字符串[]拆分值(最终字符串输入){ 最终ArrayList结果=新建ArrayList();
“\,”
和转义反斜杠“\\”
。开头和结尾的逗号以及一行中的多个逗号应导致空字符串
所以“,\,\,\,,,”
应该变成,,,,,,,,,
请注意,我的示例字符串显示反斜杠为single“\”
。Java字符串将使它们加倍
我尝试了几个软件包,但没有成功。我的最后一个想法是编写自己的解析器。
当然,一个专门的图书馆是一个好主意,但以下几点会起作用
公共静态字符串[]拆分值(最终字符串输入){
最终ArrayList结果=新建ArrayList();
//(?:\\\)*匹配任意数量的\-对
// (? 0) {
系统输出打印(“[\”);
系统输出打印(字符串[0]);
for(int i=1;i
在这种情况下,自定义函数听起来更适合我。试试这个:
public String[] splitEscapedString(String s) {
//Character that won't appear in the string.
//If you are reading lines, '\n' should work fine since it will never appear.
String c = "\n";
StringBuilder sb = new StringBuilder();
for(int i = 0;i<s.length();++i){
if(s.charAt(i)=='\\') {
//If the String is well formatted(all '\' are followed by a character),
//this line should not have problem.
sb.append(s.charAt(++i));
}
else {
if(s.charAt(i) == ',') {
sb.append(c);
}
else {
sb.append(s.charAt(i));
}
}
}
return sb.toString().split(c);
}
public String[]splitEscapedString(字符串s){
//不会出现在字符串中的字符。
//如果您正在阅读行,“\n”应该可以正常工作,因为它永远不会出现。
字符串c=“\n”;
StringBuilder sb=新的StringBuilder();
对于(int i=0;i不要使用.split()
,而是查找(未换格的)逗号之间的所有匹配项:
List matchList=new ArrayList();
Pattern regex=Pattern.compile(
(?:#组的开始\n)+
“\\.\\匹配转义字符\n”+
“|#或\n”+
[^\\\,]+\\匹配除逗号/反斜杠以外的一个或多个字符\n+
“)*#可以多次这样做”,
(b)评论);
Matcher regexMatcher=regex.Matcher(subjectString);
while(regexMatcher.find()){
add(regexMatcher.group());
}
结果:
我使用了(++
)以避免由于嵌套的量词而产生过多的回溯。我使用了以下带有引号('and')和转义(\)字符的通用sting拆分器的解决方案
public static List<String> split(String str, final char splitChar) {
List<String> queries = new ArrayList<>();
int length = str.length();
int start = 0, current = 0;
char ch, quoteChar;
while (current < length) {
ch=str.charAt(current);
// Handle escape char by skipping next char
if(ch == '\\') {
current++;
}else if(ch == '\'' || ch=='"'){ // Handle quoted values
quoteChar = ch;
current++;
while(current < length) {
ch = str.charAt(current);
// Handle escape char by skipping next char
if (ch == '\\') {
current++;
} else if (ch == quoteChar) {
break;
}
current++;
}
}else if(ch == splitChar) { // Split sting
queries.add(str.substring(start, current + 1));
start = current + 1;
}
current++;
}
// Add last value
if (start < current) {
queries.add(str.substring(start));
}
return queries;
}
public static void main(String[] args) {
String str = "abc,x\\,yz,'de,f',\"lm,n\"";
List<String> queries = split(str, ',');
System.out.println("Size: "+queries.size());
for (String query : queries) {
System.out.println(query);
}
}
这是来自另一个具有类似要求的问题。它处理多个\
连续出现的情况。但是,正如fge所建议的,您最好使用库,因为我的代码是在不了解CSV格式的角落案例的情况下编写的。感谢您的建议。我将查看它。不过,我希望我的项目t尽可能少地依赖于其他工件(guava和ApacheCommons是可以的)。可能这个问题是唯一需要这个库的问题。所以我不想使用它。
public static List<String> split(String str, final char splitChar) {
List<String> queries = new ArrayList<>();
int length = str.length();
int start = 0, current = 0;
char ch, quoteChar;
while (current < length) {
ch=str.charAt(current);
// Handle escape char by skipping next char
if(ch == '\\') {
current++;
}else if(ch == '\'' || ch=='"'){ // Handle quoted values
quoteChar = ch;
current++;
while(current < length) {
ch = str.charAt(current);
// Handle escape char by skipping next char
if (ch == '\\') {
current++;
} else if (ch == quoteChar) {
break;
}
current++;
}
}else if(ch == splitChar) { // Split sting
queries.add(str.substring(start, current + 1));
start = current + 1;
}
current++;
}
// Add last value
if (start < current) {
queries.add(str.substring(start));
}
return queries;
}
public static void main(String[] args) {
String str = "abc,x\\,yz,'de,f',\"lm,n\"";
List<String> queries = split(str, ',');
System.out.println("Size: "+queries.size());
for (String query : queries) {
System.out.println(query);
}
}
Size: 4
abc,
x\,yz,
'de,f',
"lm,n"