Java Csv数据字符串空间分割错误

Java Csv数据字符串空间分割错误,java,csv,arraylist,split,space,Java,Csv,Arraylist,Split,Space,我的命令有点问题 我有一个csv类型的文件,如下所示: //the rest of your code... while (csvInputStream.hasNext()) { String data = csvInputStream.next(); String[] wordsInLine = data.split(";"); for (int i = 0; i < wordsInLine.le

我的命令有点问题

我有一个csv类型的文件,如下所示:

    //the rest of your code...
    while (csvInputStream.hasNext()) {
            String data = csvInputStream.next();

            String[] wordsInLine = data.split(";");

            for (int i = 0; i < wordsInLine.length; i++) {
              System.out.println(wordsInLine[i]);
            }
          }
   //the rest of your code ...
Merkmals-Nr。;Interne Teile-Nr。;贝雷希;费迪贡斯克里特

在中读取文件后,您希望读取一行,然后使用此代码行拆分“;”之后的行

List<String> datenListe = Arrays.asList(data.split(";"));
我发现问题是由“Interne Teile-Nr”中的空格引起的,但我不知道如何解决空格的问题

这是完整的代码:

import java.io.*;

import java.util.*;


public class CsvEinlesen {
  public static void main(String[] args) {
    String fileName = "0-201-08-4473.csv";
    File file = new File(fileName);

    try {
      Scanner csvInputStream = new Scanner(file);

      while (csvInputStream.hasNext()) {
        String data = csvInputStream.next();

        List<String> datenListe = Arrays.asList(data.split(";"));

        for (int i = 0; i < 32; i++) {
          System.out.println(datenListe.get(i));
        }
      }

      csvInputStream.close();
    } catch (FileNotFoundException e) {
      e.printStackTrace();
      System.out.println("CSV-Datei nicht gefunden");
    }
  }
}
import java.io.*;
导入java.util.*;
公共类CsvEinlesen{
公共静态void main(字符串[]args){
字符串fileName=“0-201-08-4473.csv”;
文件=新文件(文件名);
试一试{
Scanner csvInputStream=新扫描仪(文件);
while(csvInputStream.hasNext()){
String data=csvInputStream.next();
List datenListe=Arrays.asList(data.split(“;”);
对于(int i=0;i<32;i++){
System.out.println(datenListe.get(i));
}
}
csvInputStream.close();
}catch(filenotfounde异常){
e、 printStackTrace();
System.out.println(“CSV日期为零”);
}
}
}

如果您仍然像普通数组一样遍历数组,是否确实需要将数组转换为
列表
?还有,你为什么把
32
作为限制?这是不安全的-正是因为您最终会遇到类似于
ArrayIndexOutOfBoundsException
的错误

对于本例,我的建议是只使用如下数组:

    //the rest of your code...
    while (csvInputStream.hasNext()) {
            String data = csvInputStream.next();

            String[] wordsInLine = data.split(";");

            for (int i = 0; i < wordsInLine.length; i++) {
              System.out.println(wordsInLine[i]);
            }
          }
   //the rest of your code ...
//剩下的代码。。。
while(csvInputStream.hasNext()){
String data=csvInputStream.next();
字符串[]wordsInLine=data.split(“;”);
for(int i=0;i

试一试,看看错误是否消失。

如果仍然像普通数组一样迭代数组,是否真的需要将数组转换为
列表
?还有,你为什么把
32
作为限制?这是不安全的-正是因为您最终会遇到类似于
ArrayIndexOutOfBoundsException
的错误

对于本例,我的建议是只使用如下数组:

    //the rest of your code...
    while (csvInputStream.hasNext()) {
            String data = csvInputStream.next();

            String[] wordsInLine = data.split(";");

            for (int i = 0; i < wordsInLine.length; i++) {
              System.out.println(wordsInLine[i]);
            }
          }
   //the rest of your code ...
//剩下的代码。。。
while(csvInputStream.hasNext()){
String data=csvInputStream.next();
字符串[]wordsInLine=data.split(“;”);
for(int i=0;i

尝试一下,看看错误是否消失。

我今天正在做一个类似的任务(从CSV读取数据,但使用“,”分隔符)。如果您对保持字段的顺序感兴趣,并且您知道将有多少“列”,那么您可能需要尝试使用regexp的解决方案

这样做的原因:

  • 对于行值1;;;使用方法.split()进行拆分时;;;价值2;; 您将得到一个数组,如:arr[0]:value1,arr[1]:value2。这可能 不是很好,因为你可能想知道这个值是多少 表示,如果您知道它在 CSV,但这样会丢失这些信息
  • 使用我将在示例中展示的regexp,您可以 为了尊重CSV值的顺序,您可以添加结果 无论您喜欢什么,字符串数组、ArrayList、List等等 (因为您要求提供ArrayList,所以我将使用它来制作示例)
  • 您可以学习在regexp中使用group来获取更具体的信息,以及 还可以根据您的需要构建更具体的reg EXP
缺点:

  • 从时间的意义上说,也许这不是一种有效的方式
  • 您可以选择使用 “.nextIndexOf(separatingChar)”以跟踪值
  • 也许还有别的,我不知道
然而,我的解决方案是:

public class RegExpSeparator {
    // if you have a convention for your CSV or file, that the first row
    // will contain the header you might count the header items and update the
    // column count so this method will be more generic
    // also to be more generic you can make a final var to store the separator
    // and append it to the stringbuilder in the method splitRow
    public static int columnCount = 7;

    public static void main(String args[]) {
        String testRow1 = "NaMe_wE132;-123.46;CEE Tue 23 Apr 1976 22:23:34;Value;Another_value;bla;blaa";
        String testRow2 = ";;Value1;;;;Value2";

        ArrayList<String> letsTestFirstCase = new ArrayList<String>(splitRow(testRow1));
        for (String item : letsTestFirstCase) {
            System.out.print(item + ";"); // we'll add and ; also at the end
        }
        System.out.println("");
        ArrayList<String> letsTestSecondCase = new ArrayList<String>(splitRow(testRow2));
        for (String item : letsTestSecondCase) {
            System.out.print(item + ";"); // we'll add and ; also at the end
        }
    }       

    private static ArrayList<String> splitRow (String toSplit) {
        StringBuilder buildPattern = new StringBuilder();
        //use this if you know how many columns you'll have, from the start
        for (int i = 0; i<columnCount-1; i++) {
            buildPattern.append("([^;]*);"); // to keep it simple I've assumed the fact that
            // you might have values like "Name_233, 23:45 PM, -123.45" and so on
            // * means 0 or more occurences of any char except for ;
        }
        buildPattern.append("([^;]*)"); //the last column will not be followed by a separator
        // the final regexp will be something like
        // (group1);(group2);...;(groupN)
        // and you might get the values by calling matcher.group(i)
        // where i will have values in the interval [1,N]
        // group(0) will return the WHOLE STRING!!
        String patternToString = buildPattern.toString();
        Pattern pattern = Pattern.compile(patternToString);
        Matcher matcher = pattern.matcher(toSplit);   // get a matcher object

        ArrayList<String> result = new ArrayList<String>();
        if (matcher.find()) {
            for (int i=1; i<=columnCount; i++){
                result.add(matcher.group(i)); // for the columns like ;; it will add the string ""
            }
        } else {
            System.out.println("Could not parse the given row");
        }
        return result;
    }
}
公共类RegExpSeparator{
//如果您对CSV或文件有约定,则第一行
//将包含标题您可以计算标题项并更新
//列计数,因此此方法将更通用
//另外,为了更通用,您可以创建一个最终的var来存储分隔符
//并将其附加到方法splitRow中的stringbuilder
公共静态int columnCount=7;
公共静态void main(字符串参数[]){
String testRow1=“NaMe_wE132;-123.46;CEE Tue 23 Apr 1976 22:23:34;Value;另一个值;bla;blaa”;
字符串testRow2=“;;Value1;;;;Value2”;
ArrayList letsTestFirstCase=新的ArrayList(splitRow(testRow1));
用于(字符串项:letsTestFirstCase){
System.out.print(item+“;”;//我们将在末尾添加和
}
System.out.println(“”);
ArrayList letsTestSecondCase=新的ArrayList(splitRow(testRow2));
for(字符串项:letsTestSecondCase){
System.out.print(item+“;”;//我们将在末尾添加和
}
}       
私有静态ArrayList splitRow(String-toSplit){
StringBuilder buildPattern=新建StringBuilder();
//如果您从一开始就知道将有多少列,请使用此选项

对于(int i=0;i我今天正在做一个类似的任务(从CSV读取数据,但使用“,”分隔符)。如果您对保持字段的顺序感兴趣,并且您知道将有多少“列”,您可能想尝试使用regexp的解决方案

这样做的原因:

  • 当使用方法分割行value1;;;value2;;时;; 您将得到一个类似于:arr[0]:value1,arr[1]:value2的数组 不是很好,因为你可能想知道这个值是多少 表示,如果您知道它在 CSV,但这样会丢失这些信息
  • <