簡體   English   中英

Javascript 正則表達式:無法刪除多行字符串中的前瞻組中的前導空格

[英]Javascript Regex: Unable to remove leading spaces in lookahead group in a multi line string

我正在嘗試正則表達式^(?<=[\s]*namespace[\s]*---+\s+)(.|\s)+(?=\(\s*\d+\s*rows\))/gm從單列表格列表格式字符串中提取行項目。 但是在匹配中添加了前導空格。 前瞻和后瞻組中的\s+運算符沒有幫助。 參考以下:

x = `namespace
-------------------
               itm1
     itm2
  itm3
               itm4
               
(4 rows)
`
console.log(x.match(/^(?<=[\s]*namespace[\s]*---+\s+)(.|\s)+(?=\(\s*\d+\s*rows\))/gm)[0].split(/\s+/))

Output 具有前導和尾隨空格作為單獨的列表元素:

[ '', 'itm1', 'itm2', 'itm3', 'itm4', '' ]

但是使用console.log(x.match(/^(?<=[\s]*namespace[\s]*---+\s+)(.|\s)+(?=\(\s*\d+\s*rows\))/gm)[0].trim().split(/\s+/)) <-- 注意split(..)之前的trim() ,output 是:

[ 'itm1', 'itm2', 'itm3', 'itm4' ]

為什么前瞻組末尾的\s+ (?<=[\s]*namespace[\s]*---+\s+)不刪除由(.|\s)+捕獲的所需匹配組之前的所有空格(.|\s)+

根本原因

正則表達式引擎從左到右解析字符串。

正則表達式在字符串的開頭搜索匹配項,但沒有找到后向模式,它在那里失敗,然后在namespace中的na之間測試下一個 position。 依此類推,直到-------------------之后的換行符。

\n之后的位置,換行符,有一個lookbehind模式匹配, \s+在你的lookbehind末尾找到\s+模式所需的空格。 然后,模式的 rest 也找到匹配項。 因此,您的結果中有 15 個前導空格。

解決方案

使用消費模式。 也就是說,使用捕獲組。 或者,確保您的消費部分以非空白字符開頭。

因此,

 const x = "namespace\n-------------------\n itm1\n itm2\n itm3\n itm4\n \n(4 rows)\n"; console.log( x.match(/(?<=^\s*namespace\s*---+\s+)\S.*?(?=\s*\(\s*\d+\s*rows\))/gms)[0].split(/\s+/) );

或者,使用捕獲組:

 const x = "namespace\n-------------------\n itm1\n itm2\n itm3\n itm4\n \n(4 rows)\n"; console.log( x.match(/^\s*namespace\s*---+\s+(\S.*?)(?=\s*\(\s*\d+\s*rows\))/ms)[1].split(/\s+/) );

注意正則表達式:

  • 我將(.|\s)+替換為. 模式,但添加了s標志,以便. 可以匹配換行符。 請永遠不要使用(.|\s)*(.|\n)*(.|[\r\n])* ,這些是非常低效的正則表達式模式
  • 我在正向前瞻的開頭添加了\s* ,以便可以從匹配中刪除尾隨空格。
  • 我還使用了一個懶惰的點, .*? , 在兩種模式中以匹配兩個字符串之間的最少字符數。

暫無
暫無

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

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