Java Csv-data String space 拆分错误
Java Csv-data String space split error
我在使用命令时遇到了一些问题。
我有一个 csv 类型的文件,如下所示:
Merkmals-Nr.;Interne Teile-Nr.;Bereich;Fertigungsschritt;...
读取文件后想读取一行,然后在“;”之后拆分该行通过使用此代码行。
List<String> datenListe = Arrays.asList(data.split(";"));
然后我做一个system.println
印刷品的外观:
Merkmals-Nr.
Interne Teile-Nr.
贝赖希
Fertigungsschritt
...
印刷品的实际外观:
Merkmals-Nr.
互联网
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at java.util.Arrays$ArrayList.get(Arrays.java:2866)
at CsvEinlesen.main(CsvEinlesen.java:23)
我发现问题是由 "Interne Teile-Nr." 中的 space 引起的,但我不知道如何解决 space 中的问题。
这是完整的代码:
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");
}
}
}
如果您仍像普通数组一样遍历数组,是否真的有必要将数组转换为 List<String>
?还有你为什么把 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 ...
试一试,看看错误是否消失。
我今天正在处理类似的任务(从 CSV 中读取数据,但使用“,”分隔符)。 如果您有兴趣保持字段的顺序,并且您知道有多少 "columns",您可能想尝试使用正则表达式的解决方案。
这样做的原因:
- 当使用 .split() 方法拆分时,对于行 value1;;;value2;;
你会得到一个像这样的数组:arr[0]: value1, arr[1]: value2。这有可能
不是真的好,因为你可能想知道那有什么价值
表示,如果您知道它在
CSV,但您会以这种方式丢失该信息。
- 使用正则表达式,就像我将在示例中展示的那样,您将能够
尊重 CSV 值的顺序,您可以添加结果
随心所欲,字符串数组、ArrayList、List 等
(因为你要求 ArrayList 我将使用它来制作示例)
- 您可能会学习在正则表达式中使用组来获取更具体的信息,并且
也可以根据您的需要构建更具体的 reg exps
缺点:
- 也许这不是一种有效的方式,在时间的意义上
- 你可以选择自己拆分
“.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;
}
}
您可以通过 TutorialsPoint.
中的示例了解有关正则表达式的更多信息
注意: 你应该把它作为一个单独的 class,就像一个 util/handler这里的方法是为了示例。祝你好运!
我在使用命令时遇到了一些问题。
我有一个 csv 类型的文件,如下所示:
Merkmals-Nr.;Interne Teile-Nr.;Bereich;Fertigungsschritt;...
读取文件后想读取一行,然后在“;”之后拆分该行通过使用此代码行。
List<String> datenListe = Arrays.asList(data.split(";"));
然后我做一个system.println
印刷品的外观:
Merkmals-Nr.
Interne Teile-Nr.
贝赖希
Fertigungsschritt
...
印刷品的实际外观:
Merkmals-Nr.
互联网
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at java.util.Arrays$ArrayList.get(Arrays.java:2866)
at CsvEinlesen.main(CsvEinlesen.java:23)
我发现问题是由 "Interne Teile-Nr." 中的 space 引起的,但我不知道如何解决 space 中的问题。
这是完整的代码:
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");
}
}
}
如果您仍像普通数组一样遍历数组,是否真的有必要将数组转换为 List<String>
?还有你为什么把 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 ...
试一试,看看错误是否消失。
我今天正在处理类似的任务(从 CSV 中读取数据,但使用“,”分隔符)。 如果您有兴趣保持字段的顺序,并且您知道有多少 "columns",您可能想尝试使用正则表达式的解决方案。
这样做的原因:
- 当使用 .split() 方法拆分时,对于行 value1;;;value2;; 你会得到一个像这样的数组:arr[0]: value1, arr[1]: value2。这有可能 不是真的好,因为你可能想知道那有什么价值 表示,如果您知道它在 CSV,但您会以这种方式丢失该信息。
- 使用正则表达式,就像我将在示例中展示的那样,您将能够 尊重 CSV 值的顺序,您可以添加结果 随心所欲,字符串数组、ArrayList、List 等 (因为你要求 ArrayList 我将使用它来制作示例)
- 您可能会学习在正则表达式中使用组来获取更具体的信息,并且 也可以根据您的需要构建更具体的 reg exps
缺点:
- 也许这不是一种有效的方式,在时间的意义上
- 你可以选择自己拆分 “.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;
}
}
您可以通过 TutorialsPoint.
中的示例了解有关正则表达式的更多信息注意: 你应该把它作为一个单独的 class,就像一个 util/handler这里的方法是为了示例。祝你好运!