簡體   English   中英

使用捕獲組查找和替換 json 字符串中所有出現的短語

[英]Find and Replace all occurrences of a phrase in a json string using capturing groups

我有一個字符串化的 JSON,如下所示:

...

"message":null,"elementId:["xyz1","l9ie","xyz1"]}}]}], "startIndex":"1", 
"transitionTime":"3","sourceId":"xyz1","isLocked":false,"autoplay":false
,"mutevideo":false,"loopvideo":false,"soundonhover":false,"videoCntrlVisibility":0,
...,"elementId:["dgff","xyz1","jkh90"]}}]}]

......它繼續。

我需要處理的部分是elementId鍵的值。 (第一行的第二個鍵,最后一個鍵)。

此鍵出現在 JSON 字符串的多個位置。 這個鍵的值是一個包含 4 個字符的 id 的數組。

我需要用新的 ID 替換這些 ID 之一。

這個想法的核心是這樣的:

var elemId = 'xyz1' // for instance
var regex = new RegExp(elemId, 'g');
var newString = jsonString.replace(regex, newRandomId);
jsonString = newString;

這種方法有幾個問題。 正則表達式將匹配 JSON 中任何位置的 id。 我需要一個只在 elementId 數組中匹配它的正則表達式; 沒有其他地方。

我正在嘗試使用捕獲組來匹配我需要的事件,但我無法完全破解它。 我有:

/.*elementId":\[".*(xyz1).*"\]}}]/

但這與數組中第一次出現的 'xyz1 不匹配。

所以,首先,我需要一個正則表達式,它可以匹配 elementId 中的所有“xyz1”; 但別處 elementId 結束后的方括號和大括號序列不會更改字符串中的任何位置,如果有幫助的話。

其次,即使我有一個有效的捕獲組, string.replace也不會按預期運行。 它不是只替換捕獲組內的匹配項,而是替換整個匹配項。

所以,我的第二個要求是只替換捕獲的組,而不是整個匹配。

需要的是一段 js 代碼,它將在需要的地方替換我的 'xyz1's 並返回以下字符串(假設 newRandomId 是 'abcd'):

"message":null,"elementId:["abcd","l9ie","abcd"]}}]}], "startIndex":"1", 
"transitionTime":"3","sourceId":"xyz1","isLocked":false,"autoplay":false
,"mutevideo":false,"loopvideo":false,"soundonhover":false,"videoCntrlVisibility":0,
...,"elementId:["dgff","abcd","jkh9"]}}]}]

請注意,“sourceId”的值不受影響。

編輯:我必須使用 JSON。 我無法解析它並使用該對象,因為我不知道舊 ID 可能在對象中的所有位置並且多次循環遍歷它(對於多個元素)會很耗時

假設您不能只解析和更改 JS 對象,您可以使用 2 個正則表達式:一個用於提取數組,另一個用於更改內部所需的 id:

var output = input.replace(/("elementId"\s*:\s*\[)((?:".{4}",?)*)(\])/g, function(_,start,content,end){
  return start + content.replace(/"xyz1"/g, '"rand"') + end;
});

參數_startcontentend是正則表達式的結果( 文檔在這里):

  • _是整個匹配的字符串(從"elementId:\\[ ] )。我選擇這個名字是因為它是你不使用的參數的舊約定
  • start是第一組 ( "elementId:\\[ )
  • content是第二個捕獲的組,即數組的內部部分
  • end id 第三組, ]

使用組而不是對返回字符串中的startend部分進行硬編碼有兩個目的

  • 避免重復(DRY 原則)
  • 使可變字符串成為可能(例如,在我的正則表達式中,我接受:之后的可選空格)

 var input = document.getElementById("input").innerHTML.trim(); var output = input.replace(/("elementId":\\s*\\[)((?:".{4}",?)*)(\\])/g, function(_,start,content,end){ return start + content.replace(/"xyz1"/g, '"rand"') + end; }); document.getElementById("output").innerHTML = output;
 Input: <pre id=input> "message":null,"elementId":["xyz1","l9ie","xyz1"]}}]}], "startIndex":"1", "transitionTime":"3","sourceId":"xyz1","isLocked":false,"autoplay":false ,"mutevideo":false,"loopvideo":false,"soundonhover":false,"videoCntrlVisibility":0, ...,"elementId":["dgff","xyz1","jkh9"]}}]}] </pre> Output: <pre id=output> </pre>

筆記:

  • 如果它們不是在一個數組中重復搜索到的 id,那么在一個正則表達式中完成整個操作會很容易。 但是目前的結構可以很容易地處理多個 id 來一次替換。
  • 我使用非捕獲組(?:...)來整理傳遞給外部替換回調的參數

暫無
暫無

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

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