用原始方法解析複雜字串,json一定要用JsonMapper麼?
經常採集資料,肯定會碰到解析字串,包括整個頁面的html,或者json以及一些不標準的json格式。。。
以前用json序列化,有時候需要實體類,有的時候沒有,比較麻煩,聽說可以用JsonMapper,解析為字典格式。不過沒用過,習慣了用最原始的方法來解析字串,所以這裡分享幾個解析的案例。也許會有點作用。
解析字串最常用的應該是Splite和Replace了。分割,然後替換一些引號之類的。最後組合。特別是採集的時候,經常會把html頁面中某一段要提取出來,可能很多人用正則表示式,可是不會啊,也不願意去學。那隻好用這些原始的方法了,時間久了,也積累一些經驗或者函式。看看幾個例子。
1.不規則非json字串
先看看這個例子,字串是連在一起,沒有換行的,為了方便觀察,換行了,程式是原始在一起的:
[11101630,1532,14,'0','0',3,'2015,4,23,16,05,48','4',1,2,0,0], [11101631,1532,14,'0','0',3,'2015,4,23,16,09,48','0',,,0,0], [11101632,1532,14,'0','0',3,'2015,4,23,16,03,10','1',2,2,0,0]
先來分析一下這個字串的特點,才能找到思路哦:
1.每一組資料都是在[]括號對中,每一組資料用,號分割,所以最終要形成一個數組來訪問哦。
2.每一組的資料基本都是用 , 號分割,字串型別還有單引號 ;
3.第7個數組是一個整體,也使用,號分割,整體是字串有引號;
4.第2組資料有空值,直接用,號分割,所以splite的時候不能去掉空值,否則陣列長度不一樣,定位就亂了。
既然分析都完了,那思路呢?
1.組直接分割使用 ], 標記,然後每一組要Repalce掉 [ 和 ] 。主要是最前和最後;
2.組內分割,使用 ,號標記分割,出來之前要把單引號給 替換掉 ;不然也是作為字串,引號也包括進去了;
3.至於那個 陣列 的處理,不能過於想複雜,分割之後,直接在最後增加1個元素,將固定位置7-12的組合起來;這樣也許方便點;
4.由於空值有佔位,所以每一組的長度是固定的。所以處理的時候直接根據自己想要的位置來組合。
下面看看程式碼了,C#版本,相對與一行程式碼,仔細看,Linq很是一個神器,真的是神奇。。。說多了都是淚,為啥就沒早點學呢:
String str = @"[11101630,1532,14,'0','0',3,'2015,4,23,16,05,48','4',1,2,0,0],[11101631,1532,14,'0','0',3,'2015,4,23,16,09,48','0',,,0,0],[11101632,1532,14,'0','0',3,'2015,4,23,16,03,10','1',2,2,0,0]"; var result = str.Split(new string[] { "]," }, StringSplitOptions.None) //先整體分割組 .Select(n => n.Replace("[", "") //以下是組內分割,並去掉其他干擾字元 .Replace("]", "") .Replace("\'", "") .Split(',').ToList()) .Select(n => //對中間一個整體單獨提取,進行組合,單獨增加一個元素 { n.Add(String.Format("{0},{1},{2},{3},{4},{5}", n[6], n[7], n[8], n[9], n[10], n[11]));return n; }).ToList();
看看結果怎麼樣:
2.鍵值對字串分割函式
由於json資料格式都是鍵值對字串,所以這裡特意分享一個經常用到的分割函式,不用Json元件,那就用簡單的方法做一個。這個函式來源於Newlife.Core,是X元件的重要部分。原始碼部分不過多解釋,就是按規則將鍵值對直接分割保持在字典中,使用方法大家可以自己實驗一下,或者參考下面的案例,都有用到這個方法。程式碼如下,為了方便使用,寫成了擴充套件方法:
public static class StringHelper { /// <summary>拆分字串成為名值字典</summary> /// <param name="str">要分割字串的</param> /// <param name="nameValueSeparator">鍵值對的分隔符</param> /// <param name="separators">分割字元</param> /// <returns>鍵值對字典</returns> public static IDictionary<String, String> SplitAsDictionary(this String str, String nameValueSeparator = "=", params String[] separators) { var dic = new Dictionary<String, String>(); if (String.IsNullOrWhiteSpace(str)) return dic; if (String.IsNullOrEmpty(nameValueSeparator)) nameValueSeparator = "="; if (separators == null || separators.Length < 1) separators = new String[] { ",", ";" }; String[] ss = str.Split(separators, StringSplitOptions.RemoveEmptyEntries); if (ss == null || ss.Length < 1) return null; foreach (var item in ss) { Int32 p = item.IndexOf(nameValueSeparator); // 在前後都不行 if (p <= 0 || p >= item.Length - 1) continue; String key = item.Substring(0, p).Trim(); dic[key] = item.Substring(p + nameValueSeparator.Length).Trim(); } return dic; } }
上面預設的鍵值對分割符號為 = 號,根據實際情況進行修改,json格式裡面一般是:冒號比較多。
3.複雜Json格式的字串
上面的例子比較簡單,這次看一個稍微複雜點的,雖然可能用JsonMapper可以很輕易做到,但試一下最原始的方法吧。還是按照上面的思路,先分析字串的特點:字串是連在一起,沒有換行的,為了方便觀察,換行了,程式是原始在一起的:
{1074:['墨聯','墨聯','MEX D1','#098000','98'], 2100:['美乙','美乙','USL D2','#E89B10','98'], 1024:['阿甲','阿甲','ARG','#00CCFF','98'], 1052:['哥倫甲','哥倫甲','COLCMA','#888500','98'], 1028:['K聯賽','K聯賽','KORL','#F75000','98'], 1297:['球會友誼','球會友誼','CF','#5691D8','98'], 2085:['奧女甲','奧女甲','AFB','#D86220','97']}
還是先分析特點,這個格式應該是json類似的了,比較規則:
-
組與之間是使用 , 號分割;前後有{}括號對;觀察前後可以使用 ], 字串將組分開;
-
鍵 是整數,鍵值是通過 : 號分割;
-
值是一個數組,有5個元素,通過 , 號分割
-
都有單引號,需要過濾掉;其他沒有特殊情況;
程式碼解決過程:
string text = @"{1074:['墨聯','墨聯','MEX D1','#098000','98'],2100:['美乙','美乙','USL D2','#E89B10','98'],1024:['阿甲','阿甲','ARG','#00CCFF','98'],1052:['哥倫甲','哥倫甲','COLCMA','#888500','98'],1028:['K聯賽','K聯賽','KORL','#F75000','98'],1297:['球會友誼','球會友誼','CF','#5691D8','98'],2085:['奧女甲','奧女甲','AFB','#D86220','97']}"; var dic = text.Replace("\'", "").Split(new String[]{"],"}, StringSplitOptions.None) //先組分割 .Select(n => n.Replace("{", "").Replace("}", "") //將組裡面的干擾字元過濾掉 .Replace("[", "").Replace("]", "") .SplitAsDictionary(":", "\"") //鍵值對處理,冒號分隔符 .ToDictionary(t => t.Key, t => t.Value.Split(',')//值再次進行分割,形成陣列 )).ToArray();
看看結果如何:
4.標準的json格式
在實際的採集過,可能會碰到直接url,返回的就是json格式,比較標準。這裡舉個例子,如下面這個頁面連結:
點選開後,是這個樣子:
這個應該夠複雜了,我們分析一下,篇幅較大,原始碼對照連結:
-
每一大組資料,是用,號分割;整體也是前後大括號對{},有4個大類,鍵分佈是:IndBodans,IndEvenGoals,IndGoalss,IndHalfFulls。
-
每一組的子類中,包括的都是同一個型別的資料,每一個子資料組都有N多個小的鍵值對,如MatchId,CorpId等等,使用},可以分割
分析完成之後如何解決,思路是類似的,先整體分割,使用},進行,然後每一個之類作為鍵,對值再次進行分割。。。形成字典列表。其中的引號也是需要過濾的,至於數值型別,實際用到那個的時候,都是根據key去找,再進行Convert轉換就可以了。看看原始碼:
var dicList = doc.Split("{\"IndBodans\":[", "],\"IndEvenGoals\":[", //大類分割 "],\"IndGoalss\":[", "],\"IndHalfFulls\":[", "]}") .Select(n => n.Replace("\"", "").Split("},{")//對每個大類處理,先過濾,再分割為子類 .Select(k => k.Replace("{", "").Replace("}", "")//對子類過濾 .SplitAsDictionary(":", ","))//提取子類的鍵值對 .ToArray() ).ToList();//列表
看看解析的結果如何:
注意,有元素是空值的,可以不用管。至於那幾個鍵值對陣列,最終屬於哪一個大類?雖然沒有直接標記出來,但是這個問題隨便加一個判斷就可以了,因為每一個類別的鍵名稱是不一樣的,看看是否包括對應的鍵就可以確定類別。
5.總結
雖然過程很簡單,也許有更簡單的辦好,直接和實體類對映,json反序列化更方便,但有時候沒有實體類,也挺麻煩。特別是這種變態複雜的,jsonmap直接處理不知道行不行。總之本文的目的是儘可能使用簡單原始的方法來解決問題,也是一個思路。雖然有時候我很懶,喜歡用開源元件,但有的時候一旦用上原始的了,也不喜歡改了。
字串分析處理的過程雖然繁瑣,但基本都是比較簡單的,細緻一點,都不是事。
最後把這個測試的原始碼發上來,大家別忘了點贊哦。。。
相關推薦
用原始方法解析複雜字串,json一定要用JsonMapper麼?
經常採集資料,肯定會碰到解析字串,包括整個頁面的html,或者json以及一些不標準的json格式。。。 以前用json序列化,有時候需要實體類,有的時候沒有,比較麻煩,聽說可以用JsonMapper,解析為字典格式。不過沒用過,習慣了用最原始的方法來解析字串,所以這裡分享幾個解析的案例。也
用原始方法解析復雜字符串,json一定要用JsonMapper麽?
之間 正則表達式 isn ces plain cli shu 如何解決 clist 轉自數據之巔原文用原始方法解析復雜字符串,json一定要用JsonMapper麽? 閱讀目錄 1.不規則非json字符串 2.鍵值對字符串分割函數 3.復雜Json格式
js 將json字串轉換為json物件的方法解析(簡單處理JSON語法格式校驗問題)
js 將json字串轉換為json物件的方法解析 將json字串轉換為json物件的方法。在資料傳輸過程中,json是以文字,即字串的形式傳遞的,而JS操作的是JSON物件,所以,JSON物件和JSON字串之間的相互轉換是關鍵 例如: JSON字串: var str1 = ‘{
Java用POI讀取解析Excel時,遇到科學計數法的解決方法
在匯入excel2003或者2007的時候難免會遇到某些單元格雖然是文字數字,但是使用java的poi來解析時會出現科學計算形式,下面我們看怎麼去掉這種格式,以文字來顯示: 1、導包 <!-- https://mvnrepository.com/artifact/org.apa
JQ實現將字串的銘文轉換成密文存放,並顯示密文,密文形成方法是:輸入的字母用後4個字母替換,如字母A用其後第4個字元E代替,字母a用e代替。
檔案結構 程式碼部分 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-
angular6解析模板字串,$compile服務在angular6中的實現方法
angular6解析動態字串模板 依賴: Compiler服務 viewContanierRef服務 步驟: 建立指令,並通過指令接受字串 接受字串,並通過此字串動態建立元件及模組 compiler服務解析元件和模組 通過將解析出來的元件新增到dom容器中
微信小程式大坑:encode後的JSON字串,JSON.parse解析失敗
今天,遇到微信 JSON 解析的一個大坑。 網上找了好久,沒有人記錄過相同坑,所以寫下來吧。 跨頁面跳轉,想傳遞一個物件。於是先將物件,用 infoStr=JSON.stringify(object
JSON陣列,json字串,JSON物件,陣列的區別與基本操作整理
JSON陣列,json字串,JSON物件,陣列的區別與基本操作整理 json字串 var objString = '{"a":"1","b":"2","c":"3"}'; json物件 var object
統計一行文字的單詞個數 (15 分) 本題目要求編寫程式統計一行字元中單詞的個數。所謂“單詞”是指連續不含空格的字串,各單詞之間用空格分隔,空格數可以是多個。 輸入格式: 輸入給出一行字元。 輸出格式: 在一行中輸出單詞個數。 輸入樣例: Let's go to room 209. 輸出樣例
MD,一開始就想著怎麼 用空格和結尾前判斷字母 來計算寫的頭的爆了, 反過來判斷空格後面是否有 =‘ ’就尼瑪容易多了 #include<stdio.h> #include<stdlib.h> #include<string.h> int
用指標方法編寫一個程式,輸入3個整數,將它們按由小到大的順序輸出
#include <stdio.h> void swap(int *pa,int *pb) { int temp; temp = *pa; *pa = *pb; *pb = temp; } void main() { int
java使用org.json解析josn字串與json檔案
準備org.json.jar 一、最近做專案需要操作json,趁著次機會就好好總結一下。本次使用的是org.json提供的jar包,下載地址為mvnrepository(jar包倉庫,開發所需的jar包都可以在上面下載)。 二、在eclipse上匯入外部jar檔案,方法:
java dom4j解析複雜xml成json
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import org.dom4j.Document; import org.dom4j.Elemen
java關於使用subList方法擷取的字串,放入redis快取的相關問題及解決方法
在前幾天做專案的時候,會對其他專案通過阿里雲發來的訊息中的某個List型別的欄位進行擷取,並將擷取後的結果存入redis中。但是在專案執行起來的時候,獲取redis中該欄位的內容會出現錯誤,錯誤提示如下: (error) WRONGTYPE Operation a
Android利用Gson庫解析複雜結構的JSON資料
最近在應用Face++進行人臉識別開發時,經常需要解析Face++返回的結構複雜的JSON資料,於是便決定應用Google開發的Gson庫來減輕工作量。 首先給大家看一個比較複雜的JSON資料: {"face":[{"attribute":{"age":{"
json字串,json物件,java物件互相轉換
1.把JSON字串轉換為JAVA 物件 JSONObject jsonobject = JSONObject.fromObject(jsonStr); User user= (User)JSONObject.toBean(object,User.class);2. 把java物件轉換成json物件,並轉化
用markdown.js解析markdown時,設定圖片大小
markdown設定圖片大小 打算在網頁上顯示.md文件,發現可以用markdown.js實現,具體看這篇文章: 實現網頁客戶端實時自動解析Markdown為HTML內容 可是發現不能調整圖片大小,好像markdown本身就沒有考慮這個問題。要麼找
用explain來解析sql語句,然後建立正確的索引
用explain mysql中來解析sql語句是一個非常好用的工具,它可以檢視你的sql語句的執行是直接全部掃描,還是經過索引優化的。用它來分析sql語句也可以避免一些無用的索引。下面來看一個例子: 用sql來查詢表中是否有匹配的a或者b(一共180w條記錄)第一版: 一條
後端java解析複雜巢狀json
其實不是很複雜 百度翻譯傳過來的json資料:{"from":"zh","to":"en","trans_result":[{"src":"高度600米","dst":"Height 600 meters"}]} 現在要取出dst對應的值:Height 600 meter
儘量用簡單方法處理複雜問題
在大學裡,用複雜的邏輯去解決問題。會讓老師覺得這個學生很聰明,很有能力。 而在公司這樣做,只會得到各種鄙視。 下面說說採用複雜邏輯解決問題的弊處: 1.可控性差。 當你的演算法複雜了,很多邊界問題和異常情況是很難考慮周到的,最後你會被各種段錯誤、踩記憶體、異常結果搞的焦頭
關於在JSP頁面中為什麽一定要用${pageContext.request.contextPath}來獲取項目路徑,而不能用${request.contextPath}?
html 輸出 獲取項目路徑 session PE ade ror ESS val 這裏的疑問在於pageContext和request都是JSP中的內置對象之一,為什麽不直接用${request.contextPath}來獲取項目路徑?出現