【问题标题】:String Tokenizer : split string by comma and ignore comma in double quotesString Tokenizer:用逗号分割字符串并忽略双引号中的逗号
【发布时间】:2013-10-14 23:32:39
【问题描述】:

我有一个像下面这样的字符串 -

value1, value2, value3, value4, "value5, 1234", value6, value7, "value8", value9, "value10, 123.23"

如果我对上面的字符串进行标记,我会得到逗号分隔的标记。但我想说的是字符串标记器在进行拆分时忽略双引号后的逗号。怎么说呢?

提前致谢

杀食

【问题讨论】:

  • 使用 CSV 解析器?正则表达式会有点复杂。否则,请发布您尝试过的内容。
  • CSV 解析器还可以让您统一处理带引号/不带引号的值。

标签: java regex string


【解决方案1】:

使用像 OpenCSV 这样的 CSV 解析器来自动处理引用元素中的逗号、跨越多行的值等。您也可以使用该库将文本序列化为 CSV。

String str = "value1, value2, value3, value4, \"value5, 1234\", " +
        "value6, value7, \"value8\", value9, \"value10, 123.23\"";

CSVReader reader = new CSVReader(new StringReader(str));

String [] tokens;
while ((tokens = reader.readNext()) != null) {
    System.out.println(tokens[0]); // value1
    System.out.println(tokens[4]); // value5, 1234
    System.out.println(tokens[9]); // value10, 123.23
}

【讨论】:

    【解决方案2】:

    您只需要一行和正确的正则表达式:

    String[] values = input.replaceAll("^\"", "").split("\"?(,|$)(?=(([^\"]*\"){2})*[^\"]*$) *\"?");
    

    这也为您整齐地修剪了双引号,包括最后的引号!

    注意:当引用 first 术语时,有趣的边缘情况需要一个额外的步骤,即使用 replaceAll() 修剪前导引号。

    这是一些测试代码:

    String input= "\"value1, value2\", value3, value4, \"value5, 1234\", " +
        "value6, value7, \"value8\", value9, \"value10, 123.23\"";
    String[] values = input.replaceAll("^\"", "").split("\"?(,|$)(?=(([^\"]*\"){2})*[^\"]*$) *\"?");
    for (String s : values)
    System.out.println(s);
    

    输出:

    value1, value2
    value3
    value4
    value5, 1234
    value6
    value7
    value8
    value9
    value10, 123.23
    

    【讨论】:

      【解决方案3】:

      我对正则表达式过敏;为什么不按照某人的建议进行双重拆分?

          String str = "value1, value2, value3, value4, \"value5, 1234\", value6, value7, \"value8\", value9, \"value10, 123.23\"";
          boolean quoted = false;
          for(String q : str.split("\"")) {
              if(quoted)
                  System.out.println(q.trim());
              else
                  for(String s : q.split(","))
                      if(!s.trim().isEmpty())
                          System.out.println(s.trim());
              quoted = !quoted;
          }
      

      【讨论】:

        【解决方案4】:

        您可以使用多种方法:

        1. 编写用于搜索昏迷的代码并保持状态天气特定昏迷在引号或注释中。
        2. 用双引号标记,然后用逗号标记结果数组中的字符串(确保标记索引为 0、2、4 等的字符串,因为它们不在原始字符串中的双引号中)

        【讨论】:

          【解决方案5】:

          在没有任何第三方库依赖的情况下,以下代码也可以根据给定的要求解析字段:

          import java.util.*;
          
          public class CSVSpliter {
          
            public static void main (String [] args) {
              String inputStr = "value1, value2, value3, value4, \"value5, 1234\", value6, value7, \"value8\", value9, \"value10, 123.23\"";
          
              StringBuffer sb = new StringBuffer (inputStr);
              List<String> splitStringList = new ArrayList<String> ();
              boolean insideDoubleQuotes = false;
              StringBuffer field = new StringBuffer ();
          
              for (int i=0; i < sb.length(); i++) {
                  if (sb.charAt (i) == '"' && !insideDoubleQuotes) {
                      insideDoubleQuotes = true;
                  } else if (sb.charAt(i) == '"' && insideDoubleQuotes) {
                      insideDoubleQuotes = false;
                      splitStringList.add (field.toString().trim());
                      field.setLength(0);
                  } else if (sb.charAt(i) == ',' && !insideDoubleQuotes) {
                      // ignore the comma after double quotes.
                      if (field.length() > 0) {
                          splitStringList.add (field.toString().trim());
                      }
                      // clear the field for next word
                      field.setLength(0);
                  } else {
                      field.append (sb.charAt(i));
                  }
              }
              for (String str: splitStringList) {
                  System.out.println ("Split fields: "+str);
              }
          }
          

          }

          这将给出以下输出:

          拆分字段:value1

          拆分字段:value2

          拆分字段:value3

          拆分字段:value4

          拆分字段:value5、1234

          拆分字段:value6

          拆分字段:value7

          拆分字段:value8

          拆分字段:value9

          拆分字段:value10、123.23

          【讨论】:

            【解决方案6】:
            String delimiter = ",";
            
            String v = "value1, value2, value3, value4, \"value5, 1234\", value6, value7, \"value8\", value9, \"value10, 123.23\"";
            
            String[] a = v.split(delimiter + "(?=(?:(?:[^\"]*+\"){2})*+[^\"]*+$)");
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2020-04-05
              • 2013-04-02
              • 2012-07-12
              • 1970-01-01
              • 2012-05-23
              • 2017-04-07
              • 2017-11-25
              • 1970-01-01
              相关资源
              最近更新 更多