[英]Parsing text to object with regex
我正在使用API,該API以以下格式返回文本:
#start
#p 12345 foo
#p 12346 bar
#end
#start
#p 12345 foo2
#p 12346 bar2
#end
我的解析功能:
function parseApiResponse(data) {
var results = [], match, obj;
while (match = CST.REGEX.POST.exec(/(#start)|(#end)|#p\s+(\S+)\s+(\S+)/ig)) {
if (match[1]) { // #start
obj = {};
} else if (match[2]) { // #end
results.push(obj);
obj = null; // prevent accidental reuse
// if input is malformed
} else { // #p something something
obj[match[3]] = match[4];
}
}
return results;
}
這會給我一個看起來像這樣的對象列表:
[{ '12345': 'foo', '12346': 'bar'}, /* etc... */]
但是,如果一行的格式如下
#start
#p 12345
#p 12346 bar
#end
該行實際上是#p 12345\\n
而我的match[4]
將包含下一行的#p
。
如何調整樣式以適應這種情況?
假設每行有一個#end
#start
, #end
或#p
元素,則可以使正則表達式意識到這一點,並添加一個附加的非捕獲組以指示一行中的最后一個\\s+(\\S+)
是可選的:
/(#start)|(#end)|#p\\s+(\\S+)(?:\\s+(\\S+))?$/igm
(?: )
:)表示“將其作為一個整體進行處理,但不要捕獲其匹配的模式”(因此它不會在match
創建元素)。 ?
該組后面的意思是“該組是可選的,可能與該模式中的任何內容都不匹配”。 其后的$
與m
標志一起匹配行尾。
您還可以通過使用*而不是+量詞來避免(?: )
:)欺騙,這意味着“匹配零次或多次”:將\\s+(\\S+)
更改為\\s*(\\S*)
。 這樣做的副作用是,數字和其后的數據之間的空格現在是可選的。
我將重寫正則表達式並重構代碼,如下所示:
while (match = CST.REGEX.POST.exec(/^#(start|end|p)(?:\s+(\d+)(?:[^\S\r\n]+([^\r\n]+))?)?$/igm)) {
switch (match[1]) {
case 'start':
obj = {};
break;
case 'end':
results.push(obj);
obj = null;
break;
case 'p':
obj[match[2]] = match[3];
break;
}
}
我喜歡在一個捕獲組中捕獲start
, end
或p
,因此可以在switch
語句中使用它。 我在這里使用的正則表達式的版本更具區分性(期望#p
后面的標記為數字)和更多的寬容(允許#p
行上的最后一個標記包含任何非換行符空白,例如#p 1138 this is only a test
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.