如何在正则表达式中替换后立即匹配第一个字符?

时间:2018-10-08 09:30:34

标签: regex

更新的问题

我想用'\ r \ n'替换所有的'\ n',除了那些 '\ r \ n'已经存在,所以我想到了这个: '\n\n\r\n1\n'.replace(/((\r\n)+|^|[^\r])\n((?!\r)|(?=\r\n))/g, '$1\r\n')

但是它产生: '\r\n\n\r\n1\r\n'

如果我使用'\n\n\r\n1\n'.replace(/((\r\n)+|^|[^\r]|)\n((?!\r)|(?=\r\n))/g, '$1\r\n'),它将忽略所有先决条件并产生:"\r\n\r\n\r\r\n1\r\n"

如何实现?非常感谢。

顺便说一句,它已经在Chrome 68中进行了测试。


原始问题(针对上下文):

我认为当正则表达式引擎继续测试时,替换的字符将被视为字符串的一部分。所以我得到了这个。

'1111'.replace(/(^|[^2])1/g, '$12') "2121"

但是现在我对以下声明感到困惑,我希望使用“ 2222”代替。

'1111'.replace(/(^|[^3])1/g, '$12') "2121"

替换后的字符似乎以某种方式被忽略。即使使用“。”也无法捕获它。

'1111'.replace(/(^|.)1/g, '$12') "2121"

如何替换示例中的每个“ 1”?

我知道'1111'.replace(/1/g ,2)确实可以,但是这是一个简化的示例,我想用一些先决条件来替换目标,如上面所示。

BTW,已在Chrome 68中进行了测试。

1 个答案:

答案 0 :(得分:2)

((\r\n)+|^|[^\r])\n((?!\r)|(?=\r\n))模式匹配:

  • ((\r\n)+|^|[^\r])-第1组:一个或多个CRLF序列((\r\n)+或(|)字符串(|)或任何字符(CR除外)的开头([^\r]
  • \n-换行符LF
  • ((?!\r)|(?=\r\n))-不跟随CR或不跟随CRLF。

因此,当应用于\n\n\r\n1\n时,会发生以下情况:

  • 在字符串的开头,^被捕获到组1中,\n被匹配并且(?!\r)返回true,因此存在匹配项(第一个{{1} }匹配)。由于\n为空字符串,因此将其替换为\r\n。结果为$1
  • 从第二个\r\n中搜索下一个匹配项(\n有待使用)。 \n\r\n1\n\n捕获到组1中,[^\r]\r不匹配=>失败。放回\n,正则表达式索引前进到下一个位置。在这里,结果中有\n
  • \r\n\n有待消费。 \r\n1\n不匹配,因此按原样添加到结果\r中。 \r\n\n\r有待消费。
  • \n1\n被捕获到具有\n的组1中,[^\r]无法与1匹配,找不到匹配项,\n被附加到结果中,\n
  • \r\n\n\r\n有待消费。 1\n1匹配,[^\r]\n匹配,并且\n返回true =>匹配,因此此(?!\r)为替换为1\n(因为1\r\n包含$1)。

您可以先匹配1序列,然后再匹配\r\n字符,并用\n替换两者:

\r\n

这样,CLRF和LF的尾部被标准化为CRLF。

详细信息

  • console.log( JSON.stringify('\n\n\r\n1\n'.replace(/\r\n|\n/g, '\r\n')) );-CRLF结尾
  • \r\n-或
  • |-LF结尾。