我正在尝试从文本文件中读取内容并将其分为三个单独的类别。 ID,地址和重量。但是,每当我尝试访问地址和权重时,都会出错。有人看到问题了吗?
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.*;
class Project1
{
public static void main(String[] args)throws Exception
{
List<String> list = new ArrayList<String>();
List<String> packages = new ArrayList<String>();
List<String> addresses = new ArrayList<String>();
List<String> weights = new ArrayList<String>();
//Provide the file path
File file = new File(args[0]);
//Reads the file
BufferedReader br = new BufferedReader(new FileReader(file));
String str;
while((str = br.readLine()) != null)
{
if(str.trim().length() > 0)
{
//System.out.println(str);
//Splits the string by commas and trims whitespace
String[] result = str.trim().split("\\s*,\\s*", 3);
packages.add(result[0]);
//ERROR: Doesn't know what result[1] or result[2] is.
//addresses.add(result[1]);
//weights.add(result[2]);
System.out.println(result[0]);
//System.out.println(result[1]);
//System.out.println(result[2]);
}
}
for(int i = 0; i < packages.size(); i++)
{
System.out.println(packages.get(i));
}
}
}
这是文本文件(格式是有意的):
,123-ABC-4567,15 W. 15th St.,50.1
456-BgT-79876,百老汇22号,24
QAZ-456-QWER,东20街100号,50
Q2Z-457-QWER,东20街200号,49
678-FGH-9845 ,, 45 5th Ave ,, 12.2,
678-FGH-9846,45第五大街12.2
123-A BC-9999、46 Foo Bar,220.0
347-poy-3465,101 B'way,24
,15 15 West 15th,123-FBC-4567
678-FGH-8465 45第五大街12.2
答案 0 :(得分:1)
看到数据中的模式,其中有些行以不需要的逗号开头,有些行以多个逗号作为定界符,而有些行甚至没有任何逗号定界符,而以空格作为定界符,则必须使用一个正则表达式处理所有这些行为。您可以使用此正则表达式来为您的数据完成所有操作并适当捕获。
([\w- ]+?)[ ,]+([\w .']+)[ ,]+([\d.]+)
以下是上述正则表达式的说明
([\w- ]+?)
-捕获由单词字符连字符和空格组成的ID
数据,并将其放置在group1中[ ,]+
-这是分隔符,可以是一个或多个空格或逗号([\w .']+)
-这将捕获address
数据,该数据由文字,空格和.
组成,并将其放置在group2中[ ,]+
-同样是如上所述的定界符([\d.]+)
-捕获由数字和weight
组成的.
数据,并将其放置在group3中这是您可以使用的经过修改的Java代码。我已经删除了一些变量声明,可以根据需要将其返回。该代码在捕获您要使用Matcher
对象的方式之后,将打印所有信息。
Pattern p = Pattern.compile("([\\w- ]+?)[ ,]+([\\w .']+)[ ,]+([\\d.]+)");
// Reads the file
try (BufferedReader br = new BufferedReader(new FileReader("data1.txt"))) {
String str;
while ((str = br.readLine()) != null) {
Matcher m = p.matcher(str);
if (m.matches()) {
System.out.println(String.format("Id: %s, Address: %s, Weight: %s",
new Object[] { m.group(1), m.group(2), m.group(3) }));
}
}
}
打印
Id: 456-BgT-79876, Address: 22 Broadway, Weight: 24
Id: QAZ-456-QWER, Address: 100 East 20th Street, Weight: 50
Id: Q2Z-457-QWER, Address: 200 East 20th Street, Weight: 49
Id: 678-FGH-9845, Address: 45 5th Ave, Weight: 12.2
Id: 678-FGH-9846, Address: 45 5th Ave, Weight: 12.2
Id: 123-A BC-9999, Address: 46 Foo Bar, Weight: 220.0
Id: 347-poy-3465, Address: 101 B'way, Weight: 24
Id: 678-FGH-8465, Address: 45 5th Ave, Weight: 12.2
让我知道这是否适合您,以及您是否还有任何疑问。
答案 1 :(得分:0)
最后一行仅包含一个令牌。因此split将仅返回具有一个元素的数组。
一个最小的复制示例:
import java.io.*;
class Project1 {
public static void main(String[] args) throws Exception {
//Provide the file path
File file = new File(args[0]);
//Reads the file
BufferedReader br = new BufferedReader(new FileReader(file));
String str;
while ((str = br.readLine()) != null) {
if (str.trim().length() > 0) {
String[] result = str.trim().split("\\s*,\\s*", 3);
System.out.println(result[1]);
}
}
}
}
使用此输入文件:
678-FGH-8465 45 5th Ave 12.2
输出看起来像这样:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at Project1.main(a.java:22)
Process finished with exit code 1
因此,您将必须决定在这种情况下程序应该做什么。您可能会忽略这些行,打印错误或仅将第一个标记添加到您的列表中。
答案 2 :(得分:0)
您可以在代码中添加以下代码
if (result.length > 0) {
packages.add(result[0]);
}
if (result.length > 1) {
addresses.add(result[1]);
}
if (result.length > 2) {
weights.add(result[2]);
}