【问题标题】:Split string on comma and ignore comma in double quotes [duplicate]在逗号上拆分字符串并忽略双引号中的逗号[重复]
【发布时间】:2016-03-19 08:58:18
【问题描述】:

我正在使用 Java 进行编码,并且有一个方法可以返回如下所示的字符串:

0, 2, 23131312,"This, is a message", 1212312

我希望字符串像这样吐出:

["0", "2", "23131312", "This, is a message", "1212312"]

当我在逗号上使用拆分字符串方法时,它也会拆分“这是一条消息”,这是我不想要的。如果可能的话,我希望它忽略那个特定的逗号并去掉双引号。

我查找了一些答案,CSV 似乎是解决问题的方法。但是,我没有正确理解它。

【问题讨论】:

  • 去掉方括号并使用 CSV 解析器。否则你必须处理转义的双引号,例如......或者简单地将其解析为JSON array
  • 您应该使用 CSV 库来解析初始字符串,然后将结果字段作为字符串输出,并自己提供引号。

标签: java string csv split


【解决方案1】:

我认为您可以从这里使用正则表达式,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)Splitting on comma outside quotes

您可以在这里测试模式:http://regexr.com/3cddl

Java 代码示例:

public static void main(String[] args) {
    String txt = "0, 2, 23131312,\"This, is a message\", 1212312";

    System.out.println(Arrays.toString(txt.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)")));

}

【讨论】:

  • 这完成了工作。谢谢大家!
【解决方案2】:

一种更简单的方法是将主字符串转换为 json 对象数组,它会自动处理实际元素并为您提供一个对象数组。

【讨论】:

    【解决方案3】:

    另一种方法是遍历字符串,保存索引,当您点击“”时,执行 String.substring 并插入到数组中,然后更新索引。当您点击双引号 (") 时,您会查找另一个双引号,并将子字符串插入数组并更新索引。

    【讨论】:

      【解决方案4】:

      我将在没有任何库帮助的情况下对基于从头编程算法的解决方案发表评论。我不是说这比使用库更好。

      首先,这个问题的怪癖比乍看之下要多。我的意思是:

      • 必须删除逗号周围的空格。
      • 可能存在语法错误,例如0,1,"string"notcomma,hi
      • 我想知道如何转义字符串中的双引号,我猜双引号会加倍(例如"This, is a ""message""")。这些也应该被正确解析。

      如果(看起来)未引用的值始终是数字(或者,至少是无空格),我会寻求一种扫描字符串的解决方案:

      class StringScanner
      {
          private final String s;
          private int currentPosition;
      
          public StringScanner (String s)
          {
              this.s = s;
              this.currentPosition = 0;
              skipWhitespace ();
          }
      
          private void skipWhitespace ()
          {
              while (currentPosition < s.length() && s.charAt (currentPosition) == ' ')
                  currentPosition++;
          }
      
          private String nextNumber ()
          {
              final int start = currentPosition;
      
              while (currentPosition < s.length() && s.charAt (currentPosition) != ' ')
                  currentPosition++;
      
              return s.substring (start, currentPosition);
          }
      
          private String nextString ()
          {
              if (s.charAt (currentPosition) != '\"')
                  throw new Error ("You should NEVER see this error, no matter what the input string is");
      
              currentPosition++;
              final int start = currentPosition;
      
              // Modify the following loop to test for escaped quotes if necessary
              while (currentPosition < s.length() && s.charAt (currentPosition) != '\"')
                  currentPosition++;
      
              if (currentPosition >= s.length || s.charAt (currentPosition) != '\"')
                  throw new Error ("Parse error: Unterminated string");
      
              final String r = s.substring (start, currentPosition);
      
              currentPosition++;
      
              return r;
          }
      
          public String nextField ()
          {
              String r;
      
              if (currentPosition >= s.length ())
                  r = null;
              else if (s.charAt (currentPosition) == '\"')
                  r = nextString ();
              else
                  r = nextNumber ();
      
              skipWhitespace ();
      
              if (currentPosition < s.length () && s.charAt (currentPosition) != ',')
                  throw new Error ("Parse error: no comma at end of field");
      
              currentPosition++;
      
              skipWhitespace ();
      
              if (currentPosition >= s.length ())
                  throw new Error ("Parse error: string ends with comma");
      
              return r;
          }
      }
      

      然后,将字符串拆分为:

      String s = "0, 1, \"Message, ok?\", 55";
      
      StringScanner ss = new StringScanner (s);
      
      String field = ss.nextField ();
      
      while (field != null)
      {
          System.out.println ("Field found: \"" + field + "\"");
          field = ss.nextField ();
      }
      

      【讨论】:

        猜你喜欢
        • 2011-12-25
        • 2020-08-03
        • 1970-01-01
        • 2013-10-14
        • 1970-01-01
        • 2018-04-14
        相关资源
        最近更新 更多