【问题标题】:How to access each element after a split拆分后如何访问每个元素
【发布时间】:2019-02-07 07:24:36
【问题描述】:

我正在尝试从文本文件中读取并将其分成三个不同的类别。 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 Broadway, 24

QAZ-456-QWER, 100 East 20th Street, 50

Q2Z-457-QWER, 200 East 20th Street, 49

678-FGH-9845 ,, 45 第五大道,, 12.2,

678-FGH-9846,45 第五大道,12.2

123-A BC-9999, 46 Foo Bar, 220.0

347-poy-3465, 101 B'way,24

,123-FBC-4567, 15 West 15th St., 50.1

678-FGH-8465 45 5th Ave 12.2

【问题讨论】:

  • 在文本文件的某些行中,有一个逗号会造成问题。
  • 您在\\s*,\\s* 上拆分,但在最后一行678-FGH-8465 45 5th Ave 12.2 中没有逗号。
  • 您的第一行和倒数第二行有一个额外的逗号,这会造成问题。此外,有些行有两个 ,, 逗号,因此您将再次遇到问题,最后一行似乎没有任何逗号,因此您需要修复多个数据问题,而且在拆分方法中,您不需要指定第二个参数,而是使用更好的正则表达式来获取所有值。
  • 文本文件应该有多个逗号。那么有没有人知道一种方法来访问每个部分?
  • 如果您的数据无法更改并保持原样,您应该使用能够智能捕获数据的良好正则表达式。

标签: java regex arraylist split filereader


【解决方案1】:

查看数据中的模式,其中有些行以不需要的逗号开头,有些行有多个逗号作为分隔符,而一行甚至没有任何逗号分隔符而是空格作为分隔符,您将不得不使用正则表达式处理所有这些行为。您可以使用此正则表达式来处理您的数据并适当地捕获。

([\w- ]+?)[ ,]+([\w .']+)[ ,]+([\d.]+)

这是上面正则表达式的解释,

  • ([\w- ]+?) - 捕获由单词字符连字符和空格组成的 ID 数据并将其放在 group1 中
  • [ ,]+ - 用作分隔符,可以是一个或多个空格或逗号
  • ([\w .']+) - 这会捕获由单词字符、空格和. 组成的address 数据,并将其放在group2 中
  • [ ,]+ - 如上所述的分隔符
  • ([\d.]+) - 这会捕获由数字和 . 组成的 weight 数据并将其放在 group3 中

Demo

这是您可以使用的修改后的 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

让我知道这是否适合您以及您是否有任何疑问。

【讨论】:

    【解决方案2】:

    最后一行只包含一个标记。所以 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
    

    因此,您必须决定在这种情况下您的程序应该做什么。您可能会忽略这些行、打印错误或仅在其中一个列表中添加第一个标记。

    【讨论】:

      【解决方案3】:

      您可以在代码中添加以下代码

                  if (result.length > 0) {
                      packages.add(result[0]);
                  }
                  if (result.length > 1) {
                      addresses.add(result[1]);
                  }
                  if (result.length > 2) {
                      weights.add(result[2]);
                  }
      

      【讨论】:

        猜你喜欢
        • 2019-06-29
        • 2017-06-24
        • 1970-01-01
        • 2015-01-12
        • 2017-09-20
        • 2015-01-11
        • 1970-01-01
        • 2023-03-23
        • 1970-01-01
        相关资源
        最近更新 更多