仅在第一行用正则表达式替换

Replacements only in the first line with a regex

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

!a! b!

应该变成

.a. b.

!a! b!
c!
!d!

应该变成

.a. b.
c!
!d!

我向后看:

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

它没有按预期工作:

.a. b.
c.
!d.

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

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

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

关于您尝试的模式:

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

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

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


如果你可以使用 SKIP FAIL,你可以先匹配你想要避免的内容,在本例中是一行可选地以感叹号开头并以感叹号结尾的行 none介于两者之间。

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

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

看到一个regex demo


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

第一组将匹配第一组感叹号,第二组将匹配后跟除 ! 以外的字符的空格。

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

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

再看一个regex demo

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

...