Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在逗号处拆分字符串,但避免转义逗号和反斜杠_Java_Regex_String_Escaping - Fatal编程技术网

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"