簡體   English   中英

嘗試匹配JavaScript字符串上的所有正則表達式

[英]Trying to matchAll a regex on a JavaScript string

我正在嘗試string.matchAll以下所有字符串:

const text = 'textA [aaa](bbb) textB [ccc](ddd) textC'

我要符合以下條件:

  • 1st: "textA [aaa](bbb)"
  • 第二名: " textB [ccc](ddd)"
  • 第三名: " textC"

注意:捕獲組已經存在於regex 那就是我所需要的。

它幾乎可以正常工作,但是到目前為止,我還沒有想到一種匹配字符串最后一部分的方法,它只是" textC" ,並且沒有[*](*)模式。

我究竟做錯了什么?

 const text = 'textA [aaa](bbb) textB [ccc](ddd) textC' const regexp = /(.*?)\\[(.+?)\\]\\((.+?)\\)/g; const array = Array.from(text.matchAll(regexp)); console.log(JSON.stringify(array[0][0])); console.log(JSON.stringify(array[1][0])); console.log(JSON.stringify(array[2][0])); 

更新:

除了以下答案中提供的好的解決方案外,這也是一種選擇:

 const text= 'textA [aaa](bbb) textB [ccc](ddd) textC' const regexp = /(?!$)([^[]*)(?:\\[(.*?)\\]\\((.*?)\\))?/gm; const array = Array.from(text.matchAll(regexp)); console.log(array); 

這是因為沒有第三場比賽。 在前兩個匹配之后,字符串中剩下的唯一內容是“文本C”:

https://regex101.com/r/H9Kn0G/1/

要解決這個問題,使整個第二部分可選的(也注意到初始\\w代替.防止點吃整個字符串,以及“分組只有”用括號包圍的可選部分,這使你的對手組相同):

(\\w+)(?:\\s\\[(.+?)\\]\\((.+?)\\))?

https://regex101.com/r/Smo1y1/2/

解決方案1:通過匹配拆分

您可以通過匹配模式並從先前的索引直到匹配結束獲取子字符串來進行拆分:

 const text = 'textA [aaa](bbb) textB [ccc](ddd) textC' const regexp = /\\[[^\\][]*\\]\\([^()]*\\)/g; let m, idx = 0, result=[]; while(m=regexp.exec(text)) { result.push(text.substring(idx, m.index + m[0].length).trim()); idx = m.index + m[0].length; } if (idx < text.length) { result.push(text.substring(idx, text.length).trim()) } console.log(result); 

注意:

  • \\[[^\\][]*\\]\\([^()]*\\)匹配[ ,除[]以外的任何0+個字符(帶有[^\\][]* ),然后是](然后是0 + ()以外的其他字符(帶有[^()]* ),然后是a ) (請參見regex演示
  • 捕獲組已刪除,但是您可以還原它們,並在需要時分別保存在結果數組中(或保存在另一個數組中)
  • 添加.trim()來消除前導/尾隨空格(如有必要,請刪除)。

解決方案2:匹配可選模式

這個想法是在您擁有的模式之前匹配所有字符,然后匹配您的模式或字符串結尾:

let result = text.match(/(?!$)(.*?)(?:\[(.*?)\]\((.*?)\)|$)/g);

如果字符串可以換行,請替換. 使用[\\s\\S] ,或考慮以下模式:

let result = text.match(/(?!$)([\s\S]*?)(?:\[([^\][]*)\]\(([^()]*)\)|$)/g);

參見regex演示

JS演示:

 const text = 'textA [aaa](bbb) textB [ccc](ddd) textC' const regexp = /(?!$)(.*?)(?:\\[(.*?)\\]\\((.*?)\\)|$)/g; const array = Array.from(text.matchAll(regexp)); console.log(JSON.stringify(array[0][0])); console.log(JSON.stringify(array[1][0])); console.log(JSON.stringify(array[2][0])); 

正則表達式詳細信息

  • (?!$) -不在字符串末尾
  • (.*?) -組1:除換行符以外的任何0+字符都應盡可能少(如果可以換行或添加s修飾符,請更改為[\\s\\S]*? ,因為您的目標是ECMAScript 2018)
  • (?:\\[(.*?)\\]\\((.*?)\\)|$) -兩種選擇之一:
    • \\[(.*?)\\]\\((.*?)\\) - [ ,組2:除換行符以外的任何0+字符都應盡可能少, ]( ,組3:除0以外的任意0+個字符換行符盡量少,a )
    • | - 要么
    • $ -字符串結尾。

那就是我最終使用的:

 const text= 'textA [aaa](bbb) textB [ccc](ddd) textC' const regexp = /(?!$)([^[]*)(?:\\[(.*?)\\]\\((.*?)\\))?/gm; const array = Array.from(text.matchAll(regexp)); console.log(array); 

暫無
暫無

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

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