本發(fā)明涉及一種面向通用文本格式的解析工具,屬于計算機(jī)軟件技術(shù)領(lǐng)域。
背景技術(shù):
通用文本格式規(guī)范為:通用文本由任意數(shù)目的記錄組成,記錄間以自定義的換行符分隔;每條記錄由字段組成,字段間以自定義的字段間分隔符分隔;可自定義字段間包圍符;字段中包含有換行符,該字段必須用字段包圍符括起來;字段中包含有字段間分隔符,該字段必須用字段包圍符括起來;字段中包含有字段包圍符,該字段必須用字段包圍符括起來;字段中的字段包圍符用兩個字段包圍符表示。通用文本格式的解析工具實(shí)現(xiàn)對遵循格式規(guī)范的文本字段解析。目前的文本解析工具主要針對逗號分隔值(comma-separatedvalue,csv)文件,行分隔符采用系統(tǒng)默認(rèn)的換行符,字段間分隔符采用逗號或制表符,字段包圍符采用雙引號,文本解析工具解析出文件中的每條記錄以及每條記錄中的各個字段。
目前的文本解析工具主要針對逗號分隔值文件,可自定義字段間分隔符和字段包圍符,但行分隔符采用系統(tǒng)默認(rèn)的換行符,不能自定義換行符;字段間分隔符和字段包圍符可自定義為特定的字符,但不能定義為特定的字符串或字節(jié)數(shù)組。
技術(shù)實(shí)現(xiàn)要素:
本發(fā)明的目的在于提供一種面向通用文本格式的解析方法及工具,實(shí)現(xiàn)對遵循格式規(guī)范的文本的字段解析。本發(fā)明能夠解析指定編碼格式的文件或流,允許自定義行分隔符、字段間分隔符和字段包圍符為特定的字符、字節(jié)、字符串或字節(jié)數(shù)組;這些自定義的信息由用戶自定義輸入,保存在解析工具內(nèi)部。
本發(fā)明的技術(shù)方案為:
一種面向通用文本格式的解析方法,其步驟為:
1)對于一待解析數(shù)據(jù)a,首先將其對應(yīng)的各種自定義符號導(dǎo)入解析工具中,然后采用指定的文件編碼格式讀取該待解析數(shù)據(jù)a;其中該待解析數(shù)據(jù)a為一文件或數(shù)據(jù)流,所述自定義符號包括行分隔符、字段包圍符和字段間分隔符;
2)解析工具將解析數(shù)據(jù)a中的自定義符號統(tǒng)一轉(zhuǎn)換文字符串類型;
3)解析工具逐個分析所讀取的字符,如果該字符及其后面n個字符組成的字符串與行分隔符一致,則根據(jù)行分隔符將待解析數(shù)據(jù)a分割成行數(shù)據(jù),其中n為行分隔符的長度減一;
4)解析工具分析得到的行數(shù)據(jù),根據(jù)字段包圍符解析出行數(shù)據(jù)中所有的記錄;
5)解析工具逐個分析得到的每個記錄,根據(jù)字段間分隔符解析出每條記錄中所有的字段。
進(jìn)一步的,根據(jù)字段包圍符解析出行數(shù)據(jù)中所有的記錄的方法為:
21)設(shè)置一記錄結(jié)束標(biāo)識并將其值初始化為false,將每行數(shù)據(jù)中的兩個連續(xù)字段包圍符解析為字段內(nèi)的一個包圍符,將一個字段包圍符解析為字段的一個包圍符,然后向前掃描字符;若該字段的包圍符為當(dāng)前行的最后一個字符或字符串,且記錄結(jié)束標(biāo)識值為true,則該記錄解析完成,將記錄結(jié)束標(biāo)識置為false;若該字段的包圍符為當(dāng)前行的最后一個字符或字符串,且記錄結(jié)束標(biāo)識為false,則判斷該包圍符是否為記錄中一字段開頭的包圍符,若是字段開頭的包圍符,則將記錄結(jié)束標(biāo)識置為true,接著分析下一行的數(shù)據(jù);如果該字段的包圍符是該行的最后一個字符或字符串,記錄結(jié)束標(biāo)識符是false,且該包圍符不是記錄中某個字段開頭的包圍符則拋出出錯的行數(shù)、偏移量以及錯誤類型,將記錄結(jié)束標(biāo)識置為false;
22)若該字段的包圍符不是該行的最后一個字符或字符串,且記錄結(jié)束標(biāo)識為true,則拋出出錯的行數(shù)、偏移量以及錯誤類型,否則將記錄結(jié)束標(biāo)識置為false;若該字段的包圍符不是該行的最后一個字符或字符串,且記錄結(jié)束標(biāo)識為false,則判斷該包圍符是否為記錄中一字段開頭的包圍符,若是字段開頭的包圍符,則將記錄結(jié)束標(biāo)識置為true,接著向前分析該行的字符;如果該字段的包圍符不是該行的最后一個字符或字符串,記錄結(jié)束標(biāo)識符是false,該包圍符不是記錄中某字段開頭的包圍符,則拋出出錯的行數(shù)、偏移量以及錯誤類型,將記錄結(jié)束標(biāo)識置為false。
進(jìn)一步的,根據(jù)字段間分隔符解析出每條記錄中所有的字段的方法為:
31)設(shè)置一字段結(jié)束標(biāo)識并初始化其值為false,若讀取到字段包圍符,則向前掃描字符,若向前掃描時已達(dá)到記錄結(jié)尾,且字段結(jié)束標(biāo)識值為true,則該字段解析完成,該條記錄也解析完成;否則,拋出出錯的行數(shù)、偏移量以及錯誤類型;
32)若讀取到字段包圍符,向前掃描時尚未達(dá)到記錄結(jié)尾,則繼續(xù)向前掃描:
a)若掃描到字段包圍符且字段結(jié)束標(biāo)識為true,則將兩個連續(xù)的字段包圍符解析為字段內(nèi)的包圍符;否則,判斷該包圍符是否為字段開頭的包圍符,若是則將字段結(jié)束標(biāo)識置為true,繼續(xù)解析;如果向前掃描到包圍符,字段結(jié)束標(biāo)識為false,該包圍符不是字段開頭的包圍符時,拋出出錯的行數(shù)、偏移量以及錯誤類型;
b)若向前掃描到字段分隔符,且字段結(jié)束標(biāo)識為true,則該包圍符為字段的包圍符,該分隔符為字段間的分隔符,該字段解析完成,將字段結(jié)束標(biāo)識重置為false;否則,該分隔符為字段內(nèi)分隔符,接著判斷該包圍符是否為一字段開頭的包圍符,若是則繼續(xù)解析,否則拋出出錯的行數(shù)、偏移量以及錯誤類型;
c)若向前掃描到行分隔符,且字段結(jié)束標(biāo)識為true,則解析出字段內(nèi)的行分隔符;否則,該條記錄不符合文本格式規(guī)范,拋出出錯的行數(shù)、偏移量以及錯誤類型。若向前掃描行分隔符、包圍符、字段間分隔符之外的其他字符,則解析出該字符,繼續(xù)解析;
33)若讀取到行分隔符,且字段結(jié)束標(biāo)識為true,則解析出字段內(nèi)的行分隔符;否則,拋出出錯的行數(shù)、偏移量以及錯誤類型;
34)若讀取到字段間分隔符,且字段結(jié)束標(biāo)識為true,則該字段間分隔符為字段內(nèi)的分隔符;否則,該分隔符為字段間的分隔符,解析出記錄的一個字段;
35)若讀取到自定義的行分隔符、字段包圍符和字段間分隔符之外的其他字符,則該字符為字段內(nèi)容的一部分。
進(jìn)一步的,所述行分隔符為字符、字節(jié)、字符串或字節(jié)數(shù)組。
進(jìn)一步的,所述字段包圍符為字段包圍字符、字節(jié)、字符串或字節(jié)數(shù)組。
進(jìn)一步的,所述字段間分隔符為字符、字節(jié)、字符串或字節(jié)數(shù)組。
一種面向通用文本格式的解析工具,其特征在于,包括文件解析器、行解析器、記錄解析器、字段解析器和異常處理器;其中,
文件解析器,用于根據(jù)指定的字符編碼格式,讀取指定文件路徑的文件或數(shù)據(jù)流;
行解析器,用于分析文件解析器讀取的字符,根據(jù)自定義的行分隔符分割文件,解析出文件的每行數(shù)據(jù);
記錄解析器,用于逐個分析行解析器分割出的每行數(shù)據(jù)中的字符,根據(jù)自定義的字段包圍符和設(shè)置的記錄結(jié)束標(biāo)識,解析出每行包含的所有記錄數(shù)據(jù);
字段解析器,用于針對記錄解析器解析出的每條記錄,逐個掃描每條記錄中的字符,根據(jù)自定義的字段間分隔符和設(shè)置的字段結(jié)束標(biāo)識,解析出每條記錄中所有的字段;
異常處理器,用于對文件解析過程中出現(xiàn)的問題做異常處理,詳細(xì)記錄出錯信息。
本發(fā)明提供了一種面向通用文本格式的解析工具,主要包括文件解析器、行解析器、記錄解析器、字段解析器和異常處理器。文件解析器根據(jù)指定的字符編碼格式,讀取指定文件路徑的文件或指定文件流;行解析器逐個分析文件解析器讀取文件的字符,根據(jù)自定義的行分隔符分割文件,解析出文件的每行數(shù)據(jù),其中行分隔符可定義為字符、字節(jié)、字符串或字節(jié)數(shù)組;記錄解析器逐個分析行解析器分割出的每行數(shù)據(jù)中的字符,根據(jù)自定義的字段包圍符,通過設(shè)置的記錄結(jié)束標(biāo)識,解析出行數(shù)據(jù)中的每條記錄,其中字段包圍符可定義為字段包圍字符、字節(jié)、字符串或字節(jié)數(shù)組;字段解析器針對記錄解析器解析出的每條記錄,逐個掃描每條記錄中的字符,根據(jù)自定義的字段間分隔符,通過設(shè)置字段結(jié)束標(biāo)識,解析出每條記錄中所有的字段,其中字段間分隔符可以為字符、字節(jié)、字符串或字節(jié)數(shù)組;異常處理器對不符合文本格式規(guī)范的文件解析過程中出現(xiàn)的問題做異常處理,詳細(xì)記錄出錯信息。
與現(xiàn)有技術(shù)相比,本發(fā)明具有如下優(yōu)勢:
1、能夠讀取指定編碼格式的文件或流;
2、可自定義行分隔符、字段包圍符、字段間分隔符為字符、字節(jié)、字符串或字節(jié)數(shù)組;
3、根據(jù)自定義的行分隔符、字段包圍符和字段間分隔符解析中文件或流中每條記錄的所有字段;
4、對不符合文本格式規(guī)范的記錄做異常處理,詳細(xì)記錄出錯位置和錯誤類型;
5、保證多線程安全。
附圖說明
圖1是記錄解析流程圖;
圖2是字段解析流程圖。
具體實(shí)施方式
下面結(jié)合附圖和具體實(shí)施例對本發(fā)明做進(jìn)一步詳細(xì)的說明,但不以任何方式限制本發(fā)明的范圍。
實(shí)例1一種面向通用文本格式的解析方法
1)采用指定的文件編碼格式讀取文件或流;
2)若自定義的即行分隔符、字段包圍符和字段間分隔符為字符、字節(jié)或字節(jié)數(shù)組,則將其轉(zhuǎn)換為字符串;
3)逐個分析所讀取文件或流中的字符,如果該字符及其后面n個字符組成的字符串為一個行分隔符,則根據(jù)行分隔符將文件分割成一行一行的行數(shù)據(jù),其中n為換行符長度減一;
4)分析每行的數(shù)據(jù),解析出所有的記錄,如圖1所示。
初始化記錄結(jié)束標(biāo)識為false,將每行數(shù)據(jù)中的兩個連續(xù)字段包圍符解析為字段內(nèi)的一個包圍符,將一個字段包圍符解析為字段的一個包圍符。在解析出字段的一個包圍符時,向前掃描字符。
若該字段的包圍符為該行的最后一個字符(串),接著判斷記錄結(jié)束標(biāo)識,若記錄結(jié)束標(biāo)識為true,則該記錄解析完成,將記錄結(jié)束標(biāo)識置為false;若該字段的包圍符為當(dāng)前行的最后一個字符或字符串,且記錄結(jié)束標(biāo)識為false,則判斷該包圍符是否為記錄中某個字段開頭的包圍符,若是字段開頭的包圍符,則該條記錄尚未解析完成,將記錄結(jié)束標(biāo)識置為true,接著分析下一行的數(shù)據(jù);如果該字段的包圍符是該行的最后一個字符(串),記錄結(jié)束標(biāo)識符是false,且該包圍符不是記錄中某個字段開頭的包圍符,則該條記錄不符合文本格式規(guī)范,拋出出錯的行數(shù)、偏移量以及錯誤類型,將記錄結(jié)束標(biāo)識置為false。
若該字段的包圍符不是該行的最后一個字符(串),接著判斷記錄結(jié)束標(biāo)識,若記錄結(jié)束標(biāo)識為true,則該條記錄不符合文本格式規(guī)范,拋出出錯的行數(shù)、偏移量以及錯誤類型,否則將記錄結(jié)束標(biāo)識置為false;若該字段的包圍符不是該行的最后一個字符或字符串,且記錄結(jié)束標(biāo)識為false,則判斷該包圍符是否為記錄中某字段開頭的包圍符,若是字段開頭的包圍符,則該條記錄尚未解析完成,將記錄結(jié)束標(biāo)識置為true,接著向前分析該行的字符;如果該字段的包圍符不是該行的最后一個字符(串),記錄結(jié)束標(biāo)識符是false,該包圍符不是記錄中某字段開頭的包圍符,則該條記錄不符合文本格式規(guī)范,拋出出錯的行數(shù)、偏移量以及錯誤類型,將記錄結(jié)束標(biāo)識置為false。
5)分析每條記錄的數(shù)據(jù),解析出每條記錄的所有字段,如圖2所示。
初始化字段結(jié)束標(biāo)識為false。若讀取到字段包圍符,則向前掃描字符,若向前掃描時已達(dá)到記錄結(jié)尾,則判斷字段結(jié)束標(biāo)識,若字段結(jié)束標(biāo)識為true,則該字段解析完成,該條記錄也解析完成;否則,該條記錄不符合文本格式規(guī)范,拋出出錯的行數(shù)、偏移量以及錯誤類型。
若讀取到字段包圍符,向前掃描時尚未達(dá)到記錄結(jié)尾。若向前掃描到包圍符,接著判斷字段結(jié)束標(biāo)識,若字段結(jié)束標(biāo)識為true,則按照文本格式規(guī)范將兩個連續(xù)的包圍符解析為字段內(nèi)的包圍符;否則,接著判斷該包圍符是否為字段開頭的包圍符,若是則將字段結(jié)束標(biāo)識置為true,繼續(xù)解析;如果向前掃描到包圍符,字段結(jié)束標(biāo)識為false,該包圍符不是字段開頭的包圍符時,該條記錄不符合文本格式規(guī)范,拋出出錯的行數(shù)、偏移量以及錯誤類型。若向前掃描到字段分隔符,接著判斷字段結(jié)束標(biāo)識,若字段結(jié)束標(biāo)識為true,則該包圍符為字段的包圍符,該分隔符為字段間的分隔符,該字段解析完成,將字段結(jié)束標(biāo)識重置為false;否則,該分隔符為字段內(nèi)分隔符,接著判斷該包圍符是否為某字段開頭的包圍符,若是則繼續(xù)解析,否則該條記錄不符合文本格式規(guī)范,拋出出錯的行數(shù)、偏移量以及錯誤類型。若向前掃描到行分隔符,判斷字段結(jié)束標(biāo)識,若字段結(jié)束標(biāo)識為true,則解析出字段內(nèi)的行分隔符;否則,該條記錄不符合文本格式規(guī)范,拋出出錯的行數(shù)、偏移量以及錯誤類型。若向前掃描行分隔符、包圍符、字段間分隔符之外的其他字符,則解析出該字符,繼續(xù)解析。
若讀取到行分隔符,判斷字段結(jié)束標(biāo)識,若字段結(jié)束標(biāo)識為true,則解析出字段內(nèi)的行分隔符;否則,該條記錄不符合文本格式規(guī)范,拋出出錯的行數(shù)、偏移量以及錯誤類型。
若讀取到字段間分隔符,判斷字段結(jié)束標(biāo)識,若字段結(jié)束標(biāo)識為true,則該字段間分隔符為字段內(nèi)的分隔符;否則,該分隔符為字段間的分隔符,解析出記錄的一個字段。
若讀取到自定義的行分隔符、包圍符和分隔符之外的其他字符,該字符為字段內(nèi)容的一部分。