簡體   English   中英

使用正則表達式將文本解析為對象

[英]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;
  }
}

我喜歡在一個捕獲組中捕獲startendp ,因此可以在switch語句中使用它。 我在這里使用的正則表達式的版本更具區分性(期望#p后面的標記為數字)和更多的寬容(允許#p行上的最后一個標記包含任何非換行符空白,例如#p 1138 this is only a test )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM