匹配除第一个字符之外的所有字符实例,无需后视

问题描述

我正在努力解决这个在 Safari 中无法正常工作的简单正则表达式:

(?<=\?.*)\?

它应该匹配每个 ?,除了第一个

我知道 lookbehind is not working on Safari yet,但我需要找到一些解决方法。有什么建议吗?

解决方法

您可以使用交替捕获,直到第一次出现问号。在替换中再次使用该组,使其保持不变。

在交替的第二部分,匹配一个要替换的问号。

const regex = /^([^?]*\?)|\?/g;
const s = "test ? test ? test ?? test /";
console.log(s.replace(regex,(m,g1) => g1 ? g1 : "[REPLACE]"));

,

后视总是有替代方案的。 在这种情况下,您需要做的就是替换一个字符(序列)的所有实例,第一个除外。

.replace 方法接受一个函数作为第二个参数。 该函数接收完整匹配、每个捕获组匹配(如果有)、匹配的偏移量以及其他一些作为参数的内容。 .indexOf 可以报告匹配的第一个偏移量。 或者,.search 也可以报告匹配的第一个偏移量,但适用于正则表达式。

可以在函数内部比较两个偏移量:

const yourString = "Hello? World? What? Who?",yourReplacement = "!",pattern = /\?/g,patternString = "?",firstMatchOffsetIndexOf = yourString.indexOf(patternString),firstMatchOffsetSearch = yourString.search(pattern);

console.log(yourString.replace(pattern,(match,offset) => {
  if(offset !== firstMatchOffsetIndexOf){
    return yourReplacement;
  }
  
  return match;
}));

console.log(yourString.replace(pattern,offset) => {
  if(offset !== firstMatchOffsetSearch){
    return yourReplacement;
  }
  
  return match;
}));

这也适用于字符序列

const yourString = "Hello. Hello. Hello. Hello.",yourReplacement = "Hi",pattern = /Hello/g,firstOffset = yourString.search(pattern);

console.log(yourString.replace(pattern,offset) => {
  if(offset !== firstOffset){
    return yourReplacement;
  }
  
  return match;
}));

,

拆分并加入

var s = "one ? two ? three ? four"
var l = s.split("?")               // Split with ?
var first = l.shift()              // Get first item and remove from l
console.log(first + "?" + l.join("<REPLACED>")) // Build the results