2012-07-13 70 views
12

文件names.txt中包含許多名字的形式:strings.Split圍棋

"KELLEE","JOSLYN","JASON","INGER","INDIRA","GLINDA","GLENNIS" 

有誰知道如何使這是用逗號分隔各個名稱分割字符串?

KELLEE,JOSLYN,JASON,INGER,INDIRA,GLINDA,GLENNIS 

下面的代碼通過拆分逗號和周圍留下姓名行情,什麼是轉義字符分割出"。它可以在一個Split語句中完成,分開","並留下一個逗號來分隔?

package main 

import "fmt" 
import "io/ioutil" 
import "strings" 

func main() { 
     fData, err := ioutil.ReadFile("names.txt") // read in the external file 
    if err != nil { 
     fmt.Println("Err is ", err)  // print any error 
    } 
    strbuffer := string(fData) // convert read in file to a string 

    arr := strings.Split(strbuffer, ",") 

    fmt.Println(arr) 

} 

順便說一句,這是項目歐拉問題#22 http://projecteuler.net/problem=22

回答

18

傑里米的答案基本上是正確的,並且完全符合你的要求。但是,「names.txt」文件的格式實際上是衆所周知的,稱爲CSV(逗號分隔值)。幸運的是,Go提供了一個encoding/csv包(這是標準庫的一部分),用於輕鬆解碼和編碼這些格式。除了你的+ Jeremy的解決方案之外,如果格式無效,該軟件包還會提供確切的錯誤消息,支持多行記錄並正確引用帶引號的字符串。

的基本用法是這樣的:

package main 

import (
    "encoding/csv" 
    "fmt" 
    "io" 
    "os" 
) 

func main() { 
    file, err := os.Open("names.txt") 
    if err != nil { 
     fmt.Println("Error:", err) 
     return 
    } 
    defer file.Close() 
    reader := csv.NewReader(file) 
    for { 
     record, err := reader.Read() 
     if err == io.EOF { 
      break 
     } else if err != nil { 
      fmt.Println("Error:", err) 
      return 
     } 

     fmt.Println(record) // record has the type []string 
    } 
} 

還有一個ReadAll方法,可能使你的程序更短,假設整個文件嵌入到內存中。

更新: dystroy剛剛指出你的文件只有一行。該CSV讀者很好地工作過,但下面,少通用的解決方案還應該是足夠了:

for { 
    if n, _ := fmt.Fscanf(file, "%q,", &name); n != 1 { 
     break 
    } 
    fmt.Println("name:", name) 
} 
+0

這不是一個真正的csv文件,因爲只有一行:http://projecteuler.net/project/names.txt – 2012-07-13 13:23:43

+0

哦,你是對的。它是一個單行的CSV文件:) – tux21b 2012-07-13 13:31:48

+1

加上一個使用Fscanf :-) – 2012-07-14 00:41:30

9

拆分不會從子刪除字符的一部分。你的分裂是好的,你只需要與strings.Trim事後處理切片(VAL,「\」「)。

for i, val := range arr { 
    arr[i] = strings.Trim(val, "\"") 
} 

現在常用3將有開頭和結尾的」 S刪除。

+2

注意,這將不工作:'「Smithe,P」,「布羅格斯,J。」 ' – Timmmm 2015-01-05 10:37:14