簡體   English   中英

拉出字符串拆分的多個部分

[英]Pulling multiple parts of a string split

我正在閱讀的文件看起來像這樣

textBox25,textBox21,textBox20,textBox1,textBox9,textBox10,textBox6,textBox5,textBox4,textBox3,textBox12,textBox11
"Smith, Lehron",2019,40,Billable,4.10,"Smith, Lehron",2019,40,% Billable,61.50 %,% Billable & Appt.,61.50 %
"Smith, Lehron",2019,40,Non Bill.,2.57,,,,,,,

我正在嘗試將拆分的多個部分添加到數組中。 目前它從 position 1 中吐出他的名字,但我還需要它在 Billable 4.10 和 Non Bill 2.57 中讀取,這樣就會吐出類似的東西

Smith, Lehron, Billable 4.10, Non Bill 2.57

任何想法或幫助將不勝感激!

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

    Scanner in;
    in = new Scanner (System.in);

    File cisStaffHours = new File("StaffHoursOverviewReport_10102019 (1).txt");
    Scanner s = new Scanner(cisStaffHours);

    PrintWriter outFile;
    outFile = new PrintWriter(new FileWriter("outFile.txt"));

    ArrayList<Tracking> listInfo = new ArrayList<Tracking>();

    while (s.hasNextLine()){

        Tracking c = new Tracking();
        c.name = s.nextLine();

        if(c.name.contains("\"")) {
            c.name=s.nextLine();
            c.name=s.nextLine();
            String[] parts = c.name.split("\"");
            c.name=parts[1];
            listInfo.add(c);
        }
    }

    for(Tracking o: listInfo) {
        outFile.println(o.name);
    }
        outFile.close();
        System.out.println(listInfo);
    }
}

您似乎擁有的是 CSV 格式類型的文本文件,其中有逗號分隔的列數據的特定行。 但是,通常 CSV 文件將以Header行開頭,指示您似乎不需要的列名稱(但並非總是如此),因此我們可以忽略它的那部分。

我認為在這種特殊情況下的理想情況是一種讀取文本文件的方法,並且可以在讀取該文件時從每一行檢索所有或特定的數據列。 然后將檢索到的數據寫入提供的 output 文件。

一個小問題是一些列數據在引號(“...”)內,其中一些還包含相同的分隔符,用於分隔任何給定記錄行中的所有其他列。 這可能會造成問題,因此在檢索數據時必須小心處理這種情況,否則可能會獲取不完整的數據並將其寫入所需的 output 文件並在二維字符串數組中返回。

我在下面提供的代碼示例在一個方法中完成了所有這些。 它是相對基本的,因此如果需要,您可以自行處理任何特定的增強功能。 該方法包含三個參數,兩個是 String 類型,一個是可選的 int args[],它返回一個包含檢索數據的二維字符串數組。 如果您不希望該方法返回任何內容,則可以稍微減少代碼。

這是getFromCSV()方法。 評論很好:

/**
 * This is a very basic parsing type method.<br><br>
 * 
 * Usage: {@code String[][] data = getFromCSV("Data.txt", "DataOutput.txt", 13, 16, 17, 28, 29); }
 * 
 * @param csvFilePath (String) The full path and file name of the Data file.<br>
 * 
 * @param destinationPath (String) The full path and file name of the desired output file. 
 * the retrieved data will be store there.<br>
 * 
 * @param desiredLiteralColumns (Optional - Integer Args or int[] Array) The literal
 * data columns to acquire row data from. The arguments can be provided in any desired
 * order. The returned Array will hold the required data in the order your provided.<br>
 * 
 * @return (2D String Array) Containing columnar data from each data row.
 */
public static String[][] getFromCSV(String csvFilePath, String destinationPath, 
                                    int... desiredLiteralColumns) {
    String ls = System.lineSeparator();   // The Line-Separator used for current OS.
    /* Does the destination Path exist? 
       If not create it before file is created. */
    File destPath = new File(destinationPath);
    if (!destinationPath.trim().equals("") && destPath.getParentFile() == null) {
        String fPath = destPath.getAbsolutePath().substring(0, destPath.getAbsolutePath().lastIndexOf("\\"));
        new File(fPath).mkdirs();
    }
    else {
        destPath.getParentFile().mkdirs();
    }

    ArrayList<String[]> list = new ArrayList<>();
    ArrayList<String> lineData = new ArrayList<>();
    File cisStaffHours = new File(csvFilePath);
    // 'Try With Resources' is used here to auto-close the reader.
    try (Scanner reader = new Scanner(cisStaffHours)) {
        String fileLine = "";
        // 'Try With Resources' is used here to auto-close the writer.
        try (PrintWriter writer = new PrintWriter(new FileWriter(destPath))) {
            while (reader.hasNextLine()) {
                /* Read lines one at a time. Trim each read in 
                  line of leading or trailing white-spaces (if any).  */
                fileLine = reader.nextLine().trim(); 
                // Skip blank lines (if any).
                if (fileLine.equals("")) {
                    continue;
                }
                /* Split the line based on a comma (,) delimiter)...
                   (DO NOT split on commas within quotation marks!).
                   The regular expression used with the split() method
                   ignores any number of white-spaces before or after
                   the delimiter.                    */
                String[] lineParts = fileLine.split("\\s{0,},\\s{0,}(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", -1);

                //Do we only want specific columns only?
                if (desiredLiteralColumns.length > 0) {
                    // Yes...
                    lineData.clear(); // Clear the ArrayList in case it already contains something.
                    // Retrieve the desired columns an place them into a String ArrayList...
                    for (int dc : desiredLiteralColumns) {
                        for (int lp = 0; lp < lineParts.length; lp++) {
                            if (dc == (lp + 1)) {
                                lineData.add(lineParts[lp]);
                                break;
                            }
                        }
                    }
                    /* Convert the 'lineData' ArrayList to a 1D String Array
                       and then add that String Array to the 'list' ArrayList. */
                    list.add(lineData.toArray(new String[0]));

                    // Build and Write the acquired data to the desired output file.
                    String dataString = lineData.get(0).replace("\"", "") + ", " + 
                    lineData.get(1) + " " + lineData.get(2) + " , " + 
                    lineData.get(3).replace(".", " ") + lineData.get(4);
                    writer.println(dataString);
                    writer.flush();
                }
                else {
                    // No, we want all columns. Add all columnar data to the ArrayList...
                    list.add(lineParts);
                    // Build and Write the acquired data to the desired output file.
                    String dataString = lineData.get(0).replace("\"", "") + ", " + 
                    lineData.get(1) + " " + lineData.get(2) + " , " + 
                    lineData.get(3).replace(".", " ") + lineData.get(4);
                    writer.println(dataString);
                    writer.flush();
                }
            }
        }
        // Catch and display any exceptions,
        catch (IOException ex) {
            System.out.println("getFromCSV() Method Error!" + ls + ex.getMessage());
        }
    }
    catch (FileNotFoundException ex) {
        System.out.println("getFromCSV() Method Error!" + ls + ex.getMessage());
    }

    /* Convert list to a 2D String Array and then 
       return the 2D Array...         */
    String[][] array = new String[list.size()][];
    for (int i = 0; i < list.size(); i++) {
        array[i] = list.get(i);
    }
    return array;
}

如您所見,該方法需要三個參數:

csvFilePath 參數:

此處必須提供一個字符串參數,指示要讀取的文本文件在本地文件系統中的位置。 如果文本文件位於 Class-Path 中,那么只需文件名就足夠了。 如果不是,則需要完整的路徑和文件名。

destinationPath 參數:

此處必須提供一個字符串參數,指示 output 文本文件將在本地文件系統中創建和寫入的位置。 如果 output 文件位於應用程序的項目文件夾中,則只需文件名即可。 如果不是,則需要其所需位置的完整路徑和文件名。 確保您的操作系統中存在權限以實現此目的。 如果提供的目標路徑在本地文件系統中尚不存在,則會自動創建它,再次確保您的操作系統中存在權限以實現此目的。

所需的LiteralColumns 參數:

可以在此處提供 integer 數組 ( int[ ] ) 或一系列逗號分隔的 integer arguments ,它們表示從每個數據行中檢索數據所需的文字列。 文字”是指位於列索引 0 的數據實際上是第 1 列。列索引 7 中的數據實際上是第 8 列。它是您要提供的文字值。 這是一個簡單的例子:

如果我在文件中有一個數據行,如下所示:

"Doe, John", 62, "6558 Cook Road, Atlanta, Georgia", 30336, $78,564.77

我們要檢索第一列(人名)、第三列(地址)和第四列(郵政編碼)中的數據,然后我們可以將以下內容提供給getFromCSV()方法:

String[][] myData = getFromCSV("My_CSV_File.csv", "MY_Output_File.txt", 1, 3, 5);

                                O R

int[] columns = {1, 3, 5};
String[][] myData = getFromCSV("C:\\MyDataFile\\My_CSV_File.csv",
                               "C:\\MyOuputFiles\\MY_Output_File.txt", 
                               columns);

然后當代碼運行時 output 文件和返回的二維字符串數組將包含:

"Doe, John", "6558 Cook Road, Atlanta, Georgia", 30336

如果沒有 arguments 提供給可選的desiredLiteralColumns參數,則檢索所有列數據,因此:

String[][] myData = getFromCSV("My_CSV_File.csv", "MY_Output_File.txt");

將以下內容放入 output 文件中,返回的二維字符串數組將包含相同的內容。

"Doe, John", 62, "6558 Cook Road, Atlanta, Georgia", 30336, $78,564.77

我相信您在帖子中作為示例提供的數據行中存在分隔符定位問題。 我認為您缺少一些逗號。 仔細看看。 一旦你這樣做了......要准確地構建你需要的東西,你會做這樣的事情:

String[][] data = getFromCSV("StaffHoursOverviewReport_10102019 (1).txt",
                             "outFile.txt", 
                             13, 16, 17, 28, 29);
for (int i = 0; i < data.length; i++) {
    String dataString = data[i][0].replace("\"", "") + ", " + 
                        data[i][1] + " " + data[i][2] + " , " + 
                        data[i][3].replace(".", " ") + data[i][4];
    System.out.println(dataString);
}

應該輸出到控制台 window 並放置在您想要的 output 文件中:

Smith, Lehron, Billable 4.10 , Non Bill 2.57

這與您為所需 output 提供的示例完全相同 經測試!

暫無
暫無

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

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