Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.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_Split - Fatal编程技术网

Java:拆分分号分隔的字符串,但忽略引号中的转义+分号

Java:拆分分号分隔的字符串,但忽略引号中的转义+分号,java,split,Java,Split,我想拆分我的查询,但没有得到完全符合我要求的答案 我的字符串如下所示: 选择1;选择\\2;选择3\\;从's3://mybucket/mydata'凭证'aws\u access\u key\u id=access\u key\\'复制客户;aws_secret_access_key=secret_key\\;主密钥=主密钥' 期望输出: 选择1 选择\\2 选择3\\ 从's3://mybucket/mydata'凭证'aws\u access\u key\u id=access\u key

我想拆分我的查询,但没有得到完全符合我要求的答案

我的字符串如下所示:

选择1;选择\\2;选择3\\;从's3://mybucket/mydata'凭证'aws\u access\u key\u id=access\u key\\'复制客户;aws_secret_access_key=secret_key\\;主密钥=主密钥'

期望输出:

选择1

选择\\2

选择3\\

从's3://mybucket/mydata'凭证'aws\u access\u key\u id=access\u key\\'复制客户;aws_secret_access_key=secret_key\\;主密钥=主密钥'

我找到了逃犯的解决办法。但它不符合我的要求

?? 如何忽略引号中的转义+分号


帮帮我。

我想这是一个解决办法:

String line = "select 1;select \\2; select 3\\;copy customer from 's3://mybucket/mydata' credentials 'aws_access_key_id=access_key\\;aws_secret_access_key=secret_key\\;master_symmetric_key=master_key'";
line = line.replace("\\","\\\\");//To avoid missing \
String[] tokens = line.split(";(?=([^']*'[^']*')*[^']*$)");//To split on semmicolons, but not those inside quotes
for(String t : tokens) {
    System.out.println("> "+t);
}
你可以在这里测试 您可以使用external.jar 比如commons-lang-2.6.jar

String str = "select 1;select \\2; select 3\\;copy customer from 's3://mybucket/mydata' credentials 'aws_access_key_id=access_key\\;"
            + "aws_secret_access_key=secret_key\\;"
            + "master_symmetric_key=master_key'";
    str = StringEscapeUtils.escapeJavaScript(str); // method from external jar
    String st[] = str.split(";");
    for(int i=0;i<st.length;i++)
    System.out.println(st[i]);

希望它能帮助你…

我尝试了另一种解决方案,这次没有正则表达式。我用我能想到的尽可能多的wierd字符串检查了这一点,它按照我的预期工作,希望这次也能像你预期的那样工作,请检查一下

       String s ="select 1;r;select \\2; select 3\\;copy customer from 's3://mybucket/mydata' credentials 'aws_access_key_id=<access-key-id>\\;aws_secret_access_key=<secret-access-key>\\;master_symmetric_ke‌​y=<master-key>'";
               //"select 1;r;select \\2; select 3\\;copy customer from 'r;s3://mybucket/mydata;r' credentials 'a_key;b_key;c_key\\;r' 'aws_access_key_id=access_key\\;aws_secret_access_key=secret_key\\;master_symmetric_key=master_key'";
       s = s.replace("\\","\\\\");
       List<String> tokens = new ArrayList<String>();               
       int i = 0;    
       int j = 0;
       String backup = s;
       while (i < s.length()){
        char c  = s.charAt(i);      
          if(c==';'){
            String previous = s.substring(0,i);
            int quotesBefore = StringUtils.countMatches(backup.substring(0,j), "'");
            if(i<2 || quotesBefore==0 || (i>1 && (quotesBefore & 1) == 0 || ((quotesBefore & 1) != 0) && !(s.charAt(i-1)=='\\' && s.charAt(i-2)=='\\'))){//Even quotes before OR (odd quotes AND not \\ right before)                 
                tokens.add(previous);
                if(i>0)s=s.substring(i+1);
                i=0;
            }
          }
          i++;j++;
        }
        tokens.add(s);
        for(String t : tokens) {
            System.out.println("> "+t);
        }
基本步骤:

不连续字符串字符

对于每一个,检查它是否是分号

如果这是真的,那么获取前面的字符,计算引号并添加 只有当这些字符是奇数或偶数时,才会将其添加到列表中 数字,但分号不能用转义\\
我使用了下面的解决方案,用于带有引号和转义\字符的通用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 = "select 1;select \\\\2; select 3\\\\;copy customer from 's3://mybucket/mydata' credentials 'aws_access_key_id=access_key\\\\;aws_secret_access_key=secret_key\\\\;master_symmetric_key=master_key'";
    List<String> queries = split(str, ';');
    System.out.println("Size: "+queries.size());
    for (String query : queries) {
        System.out.println(query);
    }
}

您还拥有一个\\;在复制客户之前。这与access_key\\;之间没有区别;。无论你使用什么,计算机都无法区分这两种类型;。谢谢你的帮助。但如果引号中只有分号,我不想忽略它。“复制凭证”a_密钥;b_键;c_键';所需输出:复制凭据“a\U密钥\nb\U密钥\nc\U密钥”\n\n:谢谢!!但是从's3://mybucket/mydata'凭证'aws\u access\u key\u id=\'复制客户;aws_secret_access_key=\\;主对称密钥=';它不起作用。T.T.搞定了!看看吧@김동현, 已经有一段时间了,所以你可能忘记接受答案了!很高兴我帮了忙。
Size: 4
select 1;
select \\2;
 select 3\\;
copy customer from 's3://mybucket/mydata' credentials 'aws_access_key_id=access_key\\;aws_secret_access_key=secret_key\\;master_symmetric_key=master_key'