繁体   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