【问题标题】:Replacements only in the first line with a regex仅在第一行用正则表达式替换
【发布时间】:2021-02-03 04:23:52
【问题描述】:

有一个多行字符串的变换。

!a! b!

应该变成

.a. b.

!a! b!
c!
!d!

应该变成

.a. b.
c!
!d!

我回头看它:

str(/(?<!\n)([^\n!]*)!+/g, '$1.')

它没有按预期工作:

.a. b.
c.
!d.

拆分字符串并转换第一行似乎很简单。但是有没有一种可靠的方法可以仅在多行字符串的第一行中使用正则表达式进行替换?

也希望能解释一下我的方法到底出了什么问题,所以它失败了。

这个问题不仅限于 JS 正则表达式风格,但我首先对这个感兴趣。

【问题讨论】:

  • 可能使用 2 个捕获组 !([^\s!]+)!([^\S\r\n]+[^\s!])! regex101.com/r/QtwImV/1 并替换为 .$1.$2.
  • 您也可以使用 SKIP FAIL 例如^!?[^\r\n!]*!$(*SKIP)(*FAIL)|! regex101.com/r/eAwZHD/1
  • @Thefourthbird 非常感谢,这两个建议看起来都不错,考虑将它们发布为答案。

标签: javascript regex regex-lookarounds


【解决方案1】:

关于你尝试的模式:

  • (?&lt;!\n) 否定后视,断言直接在左边的不是换行符或!
  • ([^\n!]*) 捕获组 1,匹配除换行符或 ! 之外的任何字符 0+ 次
  • !+ 匹配 1 次以上! (您要删除的内容)

模式会匹配太多,因为它会匹配所有单独的部分。例如,没有规则说匹配此模式 2 次,因此每次该模式匹配时,您都将替换为组 1。

请注意,这部分中的量词是 0+ 倍 ([^\n!]*) 它也会匹配单个 !除非前面有换行符。


如果您可以使用 SKIP FAIL,您可以首先匹配您想要避免的内容,在这种情况下,该行可以选择以感叹号开头并以感叹号结尾,中间没有任何内容。

然后匹配所有其他感叹号并用一个点替换它们。

^!?[^\r\n!]*!$(*SKIP)(*FAIL)|!

查看regex demo


另一种选择是使用 2 个捕获组。

第一组将匹配第一组感叹号之间,第二组将匹配后面的空格,后跟一个字符,而不是!。

然后匹配 !最后所以它不在替换中

 !([^\s!]+)!([^\S\r\n]+[^\s!])!

查看另一个regex demo

在替换中使用带点的 2 个捕获组

.$1.$2.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-06
    • 2017-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多