簡體   English   中英

Java - 將文本拆分為數組而沒有明顯的分隔符

[英]Java - Splitting text into array without obvious delimiter

我需要使用循環將每行文本拆分為一個數組。 問題是,鑒於文本文件的格式(我無法更改),沒有明顯的分隔符可供使用:

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沒有逗號。 我也不能用小數點分割數字,因為這些數字是錯誤的。 那么有一個簡單的方法可以做到這一點嗎? 也許是一種通過小數位數分割數字的方法?

看起來每列的大小都是固定的。 因此,在您的情況下,第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

看起來每列的大小都是固定的(字符數)。 正如您所說,由於名稱和城市之間沒有制表符或空格的最后一行,您無法按制表符或空格分割。

我建議讀一行,然后用line.substring(startIndex,endIndex)拆分String。 例如, line.substring(0,18)為名稱(如果我正確計數)。 然后,您可以使用空格作為分隔符在first和lastname中拆分此名稱。

假設字段是固定寬度,這看起來是,你可以做子字符串操作來獲取每個字段,然后相應地解析。 就像是:

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

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

這似乎是一個很好的舊固定位置文件格式。 它在打卡讀卡器時代非常受歡迎。

所以基本上,你逐行閱讀這個文件,然后:

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數組。

當然,請確保您閱讀的每一行都有適當數量的字符等,以避免出現問題。

你為什么不按指數分開? 坐標是棘手的,但如果你在小數點后總是有兩個數字,那么這個例子可以幫助你。

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;
        }
    }

}

逐行讀取,然后在每一行中,子串由相應的限制讀取。 例如:

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(),
    };
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM