亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何解析任意長度的文件?

如何解析任意長度的文件?

Go
慕工程0101907 2021-04-10 19:19:26
我有一個文本文件,我想用這樣的記錄來解析:===================name: John DoeEducation: High School DiplomaEducation: Bachelor's DegreeEducation: Sun Java Certified ProgrammerAge: 29===================name: Bob BearEducation: High School DiplomaAge: 18===================name: Jane DoeEducation: High School DiplomaEducation: Bachelor's DegreeEducation: Master's DegreeEducation: AWS Certified Solution Architect ProfessionalAge: 25如您所見,fields此類文本文件中的是固定的,但其中一些重復了任意多次。記錄由固定長度的====定界符分隔。我將如何為此類問題編寫解析邏輯?我想使用switch它來讀取行的開頭,但是處理多個重復字段的邏輯使我感到困惑。
查看完整描述

2 回答

?
白豬掌柜的

TA貢獻1893條經驗 獲得超10個贊

編輯:添加為什么我只是發布一個程序作為答案的說明。


我正在提出一個非常簡單的實現,以解析您在問題中給出的文本。您接受了數學答案,這是可以的。不過,我想在他的回答中添加一些反論點?;旧?,該答案中的偽代碼是我的答案中的代碼的不可編譯版本,因此我們同意該解決方案。


我不同意的是過度設計的談話。我每天都要處理思想過度的人編寫的代碼。我敦促您不要考慮模式,內存和時間限制,否則將來誰可能想要這些。


訪客模式?那只是在解析編程語言時非常有用的東西,不要試圖從這個問題構造一個用例。訪客模式用于遍歷其中包含不同類型事物的樹。在這里,我們列出了所有相同的東西,而不是一棵樹。


內存和時間限制?您正在解析5 GB的文本嗎?那么這可能是一個真正的問題。但是,即使您這樣做,也要始終先寫最簡單的東西。足夠了。在我的整個職業生涯中,我只需要每年使用一次簡單數組之外的其他東西或應用復雜算法。仍然到處都可以看到無緣無故地使用復雜數據結構和算法的代碼。這使更改變得復雜,容易出錯,有時最終會使速度變慢!不要使用可觀察的列表抽象,只要它的內容發生更改,它就會通知所有觀察者-但是,讓我們添加一個更新鎖定和解鎖,以便我們可以控制何時不通知所有人...否!不要沿著那條路線走。用一片。做你的邏輯。使所有內容從上到下都易于閱讀。我不想從A跳到B再跳到C,追逐接口,跟隨吸氣劑最終找到的不是具體的數據類型,而是另一個接口。那不是要走的路。


這就是為什么我的代碼不導出任何內容的原因,它是一個獨立的,可運行的示例,是針對您的具體問題的具體解決方案。您可以閱讀它,很容易理解。它沒有被大量評論,因為它不需要被評論。這三個評論不是說明會發生什么,而是說明為什么會發生。其他所有內容都可以從代碼本身中看出。我故意留下有關潛在錯誤的注釋。您知道自己擁有哪種數據,那里沒有行會觸發此錯誤。不要編寫代碼來處理不可能發生的事情。如果將來有人在冒號后添加一行沒有文本的行(請記住,沒有人會這樣做,不用擔心),這將引發恐慌,將您指向此行,然后添加另外的if或某物,你完成了。


我要延伸的主要觀點是:只寫解決當前問題所需的內容。除此之外的所有內容都使您的程序難以閱讀和更改,它將未經測試且不必要。


話雖如此,這是我的原始答案:


https://play.golang.org/p/T6c51jSM5nr


package main


import (

    "fmt"

    "strconv"

    "strings"

)


func main() {

    type item struct {

        name       string

        educations []string

        age        int

    }

    var items []item


    var current item

    finishItem := func() {

        if current.name != "" { // handle the first ever separator

            items = append(items, current)

        }

        current = item{}

    }


    lines := strings.Split(code, "\n")

    for _, line := range lines {

        if line == separator {

            finishItem()

        } else {

            colon := strings.Index(line, ":")

            if colon != -1 {

                id := line[:colon]

                value := line[colon+2:] // note potential bug if text has nothing after ':'

                switch id {

                case "name":

                    current.name = value

                case "Education":

                    current.educations = append(current.educations, value)

                case "Age":

                    age, err := strconv.Atoi(value)

                    if err == nil {

                        current.age = age

                    }

                }

            }

        }

    }

    finishItem() // in case there was no separator at the end


    for _, item := range items {

        fmt.Printf("%s, %d years old, has educations:\n", item.name, item.age)

        for _, e := range item.educations {

            fmt.Printf("\t%s\n", e)

        }

    }

}


const separator = "==================="


const code = `===================

name: John Doe

Education: High School Diploma

Education: Bachelor's Degree

Education: Sun Java Certified Programmer

Age: 29

===================

name: Bob Bear

Education: High School Diploma

Age: 18

===================

name: Jane Doe

Education: High School Diploma

Education: Bachelor's Degree

Education: Master's Degree

Education: AWS Certified Solution Architect Professional

Age: 25`


查看完整回答
反對 回復 2021-04-19
  • 2 回答
  • 0 關注
  • 243 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號