Подтвердить что ты не робот

Strings.Split in Go

Файл names.txt состоит из многих имен в форме:

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

Кто-нибудь знает, как разбить строку так, чтобы это были отдельные имена, разделенные запятыми?

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

Следующий код разбивается на запятую и оставляет кавычки вокруг имени, каков escape-символ для разделения ". Можно ли это сделать в одном заявлении 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)

}

Кстати, это часть проблемы Project Euler # 22. http://projecteuler.net/problem=22

4b9b3361

Ответ 1

Ответ Джереми в основном правильный и делает именно то, что вы просили. Но формат вашего файла names.txt на самом деле хорошо известен и называется CSV (значения, разделенные запятой). К счастью, Go поставляется с пакетом encoding/csv (который является частью стандартной библиотеки) для упрощения декодирования и кодирования таких форматов. В дополнение к вашему решению + Джереми, этот пакет также будет давать точные сообщения об ошибках, если формат недействителен, поддерживает многострочные записи и делает правильную неквалификацию цитируемых строк.

Основное использование выглядит следующим образом:

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

Ответ 2

Сплит не удаляет символы из подстрок. Ваш раскол прекрасен, вам просто нужно обработать срез со строками. Трим (val, "\" ").

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

Теперь у arr будет удалено первое и конечное.