Java - 将文本拆分为数组而没有明显的分隔符

时间:2015-07-13 20:07:35

标签: java arrays regex split

我需要使用循环将每行文本拆分为一个数组。问题是,鉴于文本文件的格式(我无法更改),没有明显的分隔符可供使用:

Adam Rippon      New York, NY    77.58144.6163.6780.94
Brandon Mroz     Broadmoor, CO   70.57138.1266.8471.28
Stephen Carriere Boston, MA      64.42138.8368.2770.56
Grant Hochstein  New York, NY    64.62133.8867.4468.44
Keegan Messing   Alaska, AK      61.15136.3071.0266.28
Timothy Dolensky Atlanta, AL     61.76123.0861.3063.78
Max Aaron        Broadmoor, CO   86.95173.4979.4893.51
Jeremy Abbott    Detroit, MI     99.86174.4193.4280.99
Jason Brown      Skokie Value,IL 87.47182.6193.3489.27
Joshua Farris    Broadmoor, CO   78.37169.6987.1783.52
Richard Dornbush All Year, CA    92.04144.3465.8278.52
Douglas Razzano  Coyotes, AZ     75.18157.2580.6976.56
Ross Miner       Boston, MA      71.94152.8772.5380.34
Sean Rabbit      Glacier, CA     60.58122.7656.9066.86
Lukas Kaugars    Broadmoor, CO   64.57114.7550.4766.28
Philip Warren    All Year, CA    55.80113.2457.0258.22
Daniel Raad      Southwest FL    52.98108.0358.6151.42
Scott Dyer       Brooklyn, OH    55.78100.9744.3357.64
Robert PrzepioskiRochester, NY   47.00100.3449.2651.08

理想情况下,我希望每个名称都在[0](或[1]中的[0]姓氏中的名字),每个位置在[2]中,或者在两个不同的城市和州的索引中,然后每个分数都在他们自己的索引中。每个人有四个单独的数字。比如Adam Rippon的得分分别是77.58,144.61,63.67,80.94

我不能用空格分割,因为有些城市的名字之间有空格(比如纽约会在两个不同的数组元素中分成New和York,而Broadmoor会在一个元素中)。无法用逗号分割城市,因为西南FL没有逗号。我也不能用小数点分割数字,因为这些数字是错误的。 那么有一个简单的方法可以做到这一点吗?也许是一种通过小数位数分割数字的方法?

6 个答案:

答案 0 :(得分:7)

看起来每列的大小都是固定的。所以在你的情况下,第1列长17个字符,第二列长16个字符,最后一个长21个字符。

现在您可以简单地遍历这些行并使用substring()方法。有点像...

String firstColumn = line.substring(0, 17).trim();
String secondColumn = line.substring(17, 33).trim();
String thirdColumn = line.substring(33, line.length).trim();

要提取数字,我们可以使用正则表达式搜索所有带有两位小数的数字。

Pattern pattern = Pattern.compile("(\\d+\\.[0-9]{2})");

Matcher matcher = pattern.matcher(thirdColumn);

while(matcher.find())
{
    System.out.println(matcher.group());
}

所以在这种情况下47.00100.3449.2651.08将输出

47.00
100.34
49.26
51.08

答案 1 :(得分:1)

看起来每列的大小都是固定的(字符数)。正如您所说,由于名称和城市之间没有制表符或空格的最后一行,您无法按制表符或空格分割。

我建议读一行,然后按line.substring(startIndex,endIndex)分割字符串。例如line.substring(0,18)作为名称(如果我计算正确的话)。然后,您可以使用空格作为分隔符在first和lastname中拆分此名称。

答案 2 :(得分:0)

假设字段是固定宽度,这看起来是,你可以做子字符串操作来获取每个字段,然后相应地解析。类似的东西:

String name = line.substring(0,x)
String city_state = line.substring(x, y)
String num1 = line.substring(y,z)

等。其中x,y和z是列分隔符。

答案 3 :(得分:0)

这似乎是一个很好的旧固定位置文件格式。它在打卡读卡器时代非常受欢迎。

所以基本上,你逐行阅读这个文件,然后:

String name = line.substring(0,17).trim();
String location = line.substring(17,33).trim();

String[] scores = new String[4];
scores[0] = line.substring(33,38);
scores[1] = line.substring(38,44);
scores[2] = line.substring(44,49);
scores[3] = line.substring(49,54);

然后,您可以继续按空格分割名称,按,分割位置,将分数转换为数字等等。

如果您想使所有上述内容更加通用,您可以准备索引列表,并根据这些索引创建数组:

int[] fieldIndexes = { 0, 17,33,38,44,49,54 };
String values[] = new String[fieldIndexes.length - 1];

然后在你的阅读循环中(我再次假设你将这行读入line):

for ( int i = 1; i < fieldIndexes.length; i++ ) {

     values[i-1] = line.substring(fieldIndexes[i-1],fieldIndexes[i]).trim();

}

然后继续使用values数组。

当然,请确保您阅读的每一行都有适当数量的字符等,以避免出现问题。

答案 4 :(得分:0)

为什么不按指数分开? 坐标是棘手的,但如果你在小数点后总是有两个数字,那么这个例子可以帮助。

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


public class Split {

    public static void main(String[] args) throws IOException {

        List<Person> lst = new ArrayList<Split.Person>();

        BufferedReader br = new BufferedReader(new FileReader("c:\\test\\file.txt"));

        try {
            String line = null;

            while ((line = br.readLine()) != null) {

                Person p = new Person();

                String[] name = line.substring(0,17).split(" ");
                String[] city = line.substring(17,33).split(" ");

                p.setName(name[0].trim());
                p.setLastname(name[1].trim());
                p.setCity(city[0].replace(",","").trim());
                p.setState(city[1].replace(",","").trim());

                String[] coordinates = new String[4];
                String coor = line.substring(33);

                String first = coor.substring(0, coor.indexOf(".") + 3);

                coor = coor.substring(first.length());

                String second = coor.substring(0, coor.indexOf(".") + 3);

                coor = coor.substring(second.length());

                String third = coor.substring(0, coor.indexOf(".") + 3);

                coor = coor.substring(third.length());

                String fourth = coor.substring(0, coor.indexOf(".") + 3);

                coordinates[0] = first;
                coordinates[1] = second;
                coordinates[2] = third;
                coordinates[3] = fourth;

                p.setCoordinates(coordinates);

                lst.add(p);
            }

        } finally {
            br.close();
        }

        for(Person p : lst){
            System.out.println(p.getName());
            System.out.println(p.getLastname());
            System.out.println(p.getCity());
            System.out.println(p.getState());
            for(String s : p.getCoordinates()){
                System.out.println(s);
            }

            System.out.println();
        }
    }

    public static class Person {

        public Person(){}

        private String name;
        private String lastname;
        private String city;
        private String state;
        private String[] coordinates;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getLastname() {
            return lastname;
        }
        public void setLastname(String lastname) {
            this.lastname = lastname;
        }
        public String getCity() {
            return city;
        }
        public void setCity(String city) {
            this.city = city;
        }
        public String getState() {
            return state;
        }
        public void setState(String state) {
            this.state = state;
        }
        public String[] getCoordinates() {
            return coordinates;
        }
        public void setCoordinates(String[] coordinates) {
            this.coordinates = coordinates;
        }
    }

}

答案 5 :(得分:0)

逐行读取,然后在每一行中,子串由相应的限制读取。 e.g:

private static String[] split(String line) {
    return new String[] {
        line.substring(0, 16).trim(),
        line.substring(17, 32).trim(),
        line.substring(33, 37).trim(),
        line.substring(38, 43).trim(),
        line.substring(44, 48).trim(),
        line.substring(49, 53).trim(),
    };
}