Golang中如何按分隔符拆分列

Golang中如何按分隔符拆分列 大家好,

我有一个压缩的CSV数据,正在使用Go Lambda函数解压。CSV数据的第一列包含多个信息,例如:项目编号_项目_城市_国家。现在我的问题是,是否有类似Python的解决方案,可以通过分隔符拆分这些条目:

df[[ 'ProjectNumber' , 'Project' , 'City' , 'Country' ]] = df[ 'Column1' ]. str .split( '_' ,expand = True )
df

从而得到四个独立的列,而不是一个。如果有人知道如何解决这个问题,我将非常期待。

祝好,并祝您度过愉快的一周。


更多关于Golang中如何按分隔符拆分列的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

早上好 Nobbz,

谢谢,我会看一下。之后会发布结果。

更多关于Golang中如何按分隔符拆分列的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我相当确定,strings 包中会有一些方法可以用来 Split() 字符串。

解析CSV文件时,最好依赖一个懂得如何处理CSV的库。 例如,你怎么能确定分隔符不会作为项目名称的一部分出现在行中呢?

我建议使用默认的csv包 - encoding/csv - pkg.go.dev包。 在你的输入上创建一个读取器,然后使用 reader.Read() 来获取一条记录(该记录将被正确分割)。

func main() {
    fmt.Println("hello world")
}

在Go中处理CSV数据时,可以通过strings.Split()函数按分隔符拆分列。以下是一个完整的示例,演示如何读取CSV文件,拆分指定列,并生成新的CSV数据:

package main

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

func main() {
    // 示例CSV数据
    csvData := `Column1,Column2
12345_ProjectA_Beijing_China,OtherData1
67890_ProjectB_NewYork_USA,OtherData2`
    
    reader := csv.NewReader(strings.NewReader(csvData))
    
    // 读取表头
    header, err := reader.Read()
    if err != nil {
        panic(err)
    }
    
    // 创建新的表头
    newHeader := []string{"ProjectNumber", "Project", "City", "Country", "Column2"}
    
    // 准备输出
    var output [][]string
    output = append(output, newHeader)
    
    // 处理每一行数据
    for {
        record, err := reader.Read()
        if err == io.EOF {
            break
        }
        if err != nil {
            panic(err)
        }
        
        // 拆分第一列(Column1)
        parts := strings.Split(record[0], "_")
        if len(parts) != 4 {
            panic("Invalid data format in Column1")
        }
        
        // 构建新行
        newRow := []string{
            parts[0], // ProjectNumber
            parts[1], // Project
            parts[2], // City
            parts[3], // Country
            record[1], // 保留原始Column2
        }
        
        output = append(output, newRow)
    }
    
    // 输出结果
    writer := csv.NewWriter(strings.NewWriter())
    writer.WriteAll(output)
    writer.Flush()
    
    // 打印结果
    for _, row := range output {
        fmt.Println(strings.Join(row, ", "))
    }
}

如果需要在Lambda函数中处理压缩的CSV文件,可以结合使用compress/gzipencoding/csv

package main

import (
    "compress/gzip"
    "encoding/csv"
    "io"
    "strings"
)

func processCompressedCSV(compressedData io.Reader) ([][]string, error) {
    // 解压数据
    gzReader, err := gzip.NewReader(compressedData)
    if err != nil {
        return nil, err
    }
    defer gzReader.Close()
    
    // 创建CSV读取器
    csvReader := csv.NewReader(gzReader)
    
    // 读取表头
    header, err := csvReader.Read()
    if err != nil {
        return nil, err
    }
    
    // 创建新表头
    newHeader := []string{"ProjectNumber", "Project", "City", "Country"}
    newHeader = append(newHeader, header[1:]...)
    
    result := [][]string{newHeader}
    
    // 处理数据行
    for {
        record, err := csvReader.Read()
        if err == io.EOF {
            break
        }
        if err != nil {
            return nil, err
        }
        
        // 拆分第一列
        parts := strings.Split(record[0], "_")
        if len(parts) < 4 {
            // 根据实际情况处理格式不匹配的情况
            continue
        }
        
        // 构建新行
        newRow := []string{
            parts[0], // ProjectNumber
            parts[1], // Project
            parts[2], // City
            parts[3], // Country
        }
        newRow = append(newRow, record[1:]...)
        
        result = append(result, newRow)
    }
    
    return result, nil
}

对于更复杂的CSV操作,可以使用第三方库如github.com/gocarina/gocsv

package main

import (
    "github.com/gocarina/gocsv"
    "strings"
)

type OriginalRecord struct {
    Column1 string `csv:"Column1"`
    Column2 string `csv:"Column2"`
}

type TransformedRecord struct {
    ProjectNumber string `csv:"ProjectNumber"`
    Project       string `csv:"Project"`
    City          string `csv:"City"`
    Country       string `csv:"Country"`
    Column2       string `csv:"Column2"`
}

func transformCSV(input string) (string, error) {
    var records []OriginalRecord
    if err := gocsv.UnmarshalString(input, &records); err != nil {
        return "", err
    }
    
    var transformed []TransformedRecord
    for _, record := range records {
        parts := strings.Split(record.Column1, "_")
        if len(parts) >= 4 {
            transformed = append(transformed, TransformedRecord{
                ProjectNumber: parts[0],
                Project:       parts[1],
                City:          parts[2],
                Country:       parts[3],
                Column2:       record.Column2,
            })
        }
    }
    
    output, err := gocsv.MarshalString(&transformed)
    if err != nil {
        return "", err
    }
    
    return output, nil
}

这些示例展示了在Go中按分隔符拆分CSV列的不同方法,可以根据具体需求选择适合的方案。

回到顶部