簡體   English   中英

模仿否定的向后看以匹配 JavaScript 正則表達式中沒有緊跟在特定字符之前的模式

[英]Mimicking negative lookbehind to match a pattern not immediately preceded with a specific character in JavaScript regex

我在 Javascript 中有這個正則表達式:

0x[A-F0-9]{2}\g

我想修改它以便在前一個字符不是\時獲得匹配。 像這樣的東西:

  • 0x60 -> 真
  • \0x60 -> 假

我想出了類似的東西,但它不能正常工作:

[^\\]0x[A-F0-9]{2}\g

它匹配除\之外的所有內容,我的意思是:

  • a0x50 -> true,包括“a”
  • _0x50 -> true,包括“_”
  • ...
  • \0x50 -> 假

正則表達式示例: regex101 ,后跟Plnkr

有可能實現嗎? 謝謝。

JavaScript不支持lookbehinds,正如您已經建議的那樣,以下內容將消耗一個額外的字符( 0x之前的字符):

/[^\\]0x[A-F0-9]{2}/g

你可以做一些丑陋的黑客,比如:

'\\0x25 0x60'.match(/([^\\]|^)0x[A-F0-9]{2}/g).map(function(val) {
  return val.slice(1);
});
['0x60']

這將消耗前導字符,但通過對匹配數組的迭代將其刪除。

然而,這使得像0x600x60這樣的輸入給出['0x60']而不是['0x60', '0x60']

要點是匹配你通常會在一個可選的捕獲組中放入一個否定的lookbehind的模式,然后檢查該組是否匹配。 如果是,則不需要匹配,否則,使用它。

如果您需要匹配和收集子字符串,請使用

 var re = /(\\?)0x[A-F0-9]{2}/gi; var str = '\\0x50 0x60 asdasda0x60'; var res = []; while ((m = re.exec(str)) !== null) { if (!m[1]) { res.push(m[0]); } } document.body.innerHTML = "TEST: " + str + "<br/>"; document.body.innerHTML += "RES: " + JSON.stringify(res,0,4) + "<br/>";

如果您只需要替換那些在0x..之前沒有\的字符串,請在replace方法中使用回調來檢查組 1 是否匹配。 如果是,則替換為整個匹配項,如果不是,則只需替換為您需要的模式。

 var re = /(\\?)0x[A-F0-9]{2}/gi; var str = '\\0x50 0x60 asdasda0x60'; var res = str.replace(re, function(m, group1){ return group1 ? m : "NEW_VAL"; }); document.body.innerHTML = "TEST: " + str + "<br/>"; document.body.innerHTML += "RES: " + res + "<br/>";

你可以同時匹配壞的和好的。
這將使其與所有優點保持一致,因此您不會錯過任何東西。

(?:\\0x[A-F0-9]{2}|(0x[A-F0-9]{2}))

在這種情況下,只有好的出現在捕獲組 1 中。

 (?:
      \\ 0x [A-F0-9]{2}     # Bad
   |  
      ( 0x [A-F0-9]{2} )    # (1), Good
 )

這將做到:

(?:[^\\]|^)0x[A-F0-9]{2}

 var myregexp = /(?:[^\\]|^)0x[A-F0-9]{2}/mg; var subject = '0x60 \0x99 0x60 \0x99 0x60 0x60'; var match = myregexp.exec(subject); while (match != null) { for (var i = 0; i < match.length; i++) { document.body.innerHTML += match[i]+ "<br/>"; } match = myregexp.exec(subject); }


正則表達式解釋:

(?:[^\\]|^)0x[A-F0-9]{2}

Match the regular expression below «(?:[^\\]|^)»
   Match this alternative (attempting the next alternative only if this one fails) «[^\\]»
      Match any character that is NOT the backslash character «[^\\]»
   Or match this alternative (the entire group fails if this one fails to match) «^»
      Assert position at the beginning of a line (at beginning of the string or after a line break character) (line feed, line feed, line separator, paragraph separator) «^»
Match the character string “0x” literally (case insensitive) «0x»
Match a single character present in the list below «[A-F0-9]{2}»
   Exactly 2 times «{2}»
   A character in the range between “A” and “F” (case insensitive) «A-F»
   A character in the range between “0” and “9” «0-9»

如果您使用的是 Node,或者願意打開瀏覽器標志(從這里開始),那么您很幸運:

Lookbehind 斷言目前處於 TC39 規范過程的早期階段。 然而,因為它們是 RegExp 語法的明顯擴展,我們決定優先考慮它們的實現。 您已經可以通過使用 --harmony 運行 V8 4.9 或更高版本來試驗后向斷言,或者通過在 Chrome 49 及更高版本中啟用實驗性 JavaScript 功能(使用 about:flags)。

現在當然只是

/(?<!\\)0x[A-F0-9]{2}/g

在這個答案中還有其他模擬后視的方法。 我最喜歡的是反轉字符串並使用前瞻。

 var re = /[A-F0-9]{2}x0(?!\\)/g; var str = "0x60 \0x33"; function reverse(s) { return s.split('').reverse().join(''); } document.write(reverse(str).match(re).map(reverse));

暫無
暫無

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

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