javascript - 如何安全地用替换术语替换每个搜索,其中前者是后者的一部分,而不会再次替换这样的搜索?

标签 javascript regex string replace match

var string = "Please click on dashboard and then open the dashboard details to verify your details on the data";
var stringArray = ["dashboard" , "dashboard" , "data"]
var replaceArray = ["https://abcd.com/login" , "https://abcd.com/home" , "https://abcd.com/data"]
for(i=0;i<stringArray.length; i++){
    string = string.replace(stringArray[i].trim(), "<a href='"+replaceArray[i].trim()+"'>"+stringArray[i].trim()+"</a>");
}

我有一个字符串和两个数组,如上面所示。我需要用两个数组中提到的相应 anchor 链接标签替换我的字符串。 stringArray 定义要链接的单词,replaceArray 定义应添加的 URL。就像第一次出现的仪表板应与“https://abcd.com/login” anchor 链接,第二次出现的“仪表板”应替换为“https://abcd.com/home”,“数据”应替换与“https://abcd.com/data”。

我尝试找出字符串中的单词并使用replace/replaceAll 替换它,对于单次出现的单词工作正常,但对于多次出现的单词则不起作用。

谁能帮我解决这个问题。

结果:

"Please click on <a href='https://abcd.com/login'><a href='https://abcd.com/home'>dashboard</a></a> and then open the dashboard details to verify your details on the <a href='https://abcd.com/data'>data</a>"

预期输出:

"Please click on <a href='https://abcd.com/login'>dashboard</a> and then open the <a href='https://abcd.com/home'>dashboard</a> details to verify your details on the <a href='https://abcd.com/data'>data</a>"

最佳答案

当使用字符串作为 Javascript 的第一个参数(子字符串)时 replace函数,replace 将仅查找并替换第一次出现的子字符串。这就是为什么“登录”和“主页”链接都嵌套在第一次出现的“仪表板”周围,而其余的“仪表板”则保持不变。使用 regular expression as the first parameter是一种解决方案,但不是唯一的解决方案...

使用indexOf()跟踪数组 strArray 中的单词匹配的最后一个索引,然后 slice - 最后插入后的字符串以从那里继续替换搜索:

var string = "Please click on dashboard and then open the dashboard details to verify your details on the data";
var stringArray = ["dashboard", "dashboard", "data"]
var replaceArray = ["https://abcd.com/login", "https://abcd.com/home", "https://abcd.com/data"]

// keep track of last position of matched string
let ii = 0;

for (i = 0; i < stringArray.length; i++) {
  let str = stringArray[i].trim();
  let repstr = '<a href="' + replaceArray[i].trim() + '">' + str + '</a>';

  // move position to index of matched string
  ii += string.slice(ii).indexOf(str);
  string = 
    // this is the portion of string before and including last replacement
    string.slice(0, ii) 
    // this is the portion after last replacement
    + string.slice(ii).replace(str, repstr);

  // move position to past current replacement
  ii += repstr.length;
}
console.log(string);
// Please click on <a href="https://abcd.com/login">dashboard</a> and then open the <a href="https://abcd.com/home">dashboard</a> details to verify your details on the <a href="https://abcd.com/data">data</a>

此解决方案基准regular expression solution120 倍 ,以及我在下面发布的减少解决方案。


这是一个将单词和链接组合到一个数组中的解决方案,然后使用 reduce迭代数组replace_arr,更新字符串string,并维护匹配索引ii:

let string = "Please click on dashboard and then open the dashboard details to verify your details on the data";
const replace_arr = [["dashboard", "https://abcd.com/login"], ["dashboard", "https://abcd.com/home"], ["data", "https://abcd.com/data"]];

replace_arr.reduce(
  (ii, [str, link]) => {
    let repstr = '<a href="' + link + '">' + str + '</a>';
    ii += string.slice(ii).indexOf(str);
    string = string.slice(0, ii) 
      + string.slice(ii).replace(str, repstr)
    return ii + repstr.length;
  }
  , 0
);

console.log(string);
// Please click on <a href="https://abcd.com/login">dashboard</a> and then open the <a href="https://abcd.com/home">dashboard</a> details to verify your details on the <a href="https://abcd.com/data">data</a>


重构归约方法以获得更好的性能 - 最初将 string 包含在 reduce() 函数中,并在内部进行处理,与访问字符串相比,执行时间几乎减少了一半每次迭代的缩减过程外部:

let string = "Please click on dashboard and then open the dashboard details to verify your details on the data";
const replace_arr = [["dashboard", "https://abcd.com/login"], ["dashboard", "https://abcd.com/home"], ["data", "https://abcd.com/data"]];

[string] = replace_arr.reduce(([ss, ii], [str, link]) => {
  let repstr = '<a href="' + link + '">' + str + '</a>';
  ii += ss.slice(ii).indexOf(str);
  return [ss.slice(0, ii) +
    ss.slice(ii).replace(str, repstr), ii + repstr.length
  ];
}, [string, 0]);

console.log(string);
// Please click on <a href="https://abcd.com/login">dashboard</a> and then open the <a href="https://abcd.com/home">dashboard</a> details to verify your details on the <a href="https://abcd.com/data">data</a>

...最终解决方案的基准测试速度几乎是 regex solution 的两倍。 :)

关于javascript - 如何安全地用替换术语替换每个搜索,其中前者是后者的一部分,而不会再次替换这样的搜索?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72867805/

相关文章:

javascript - 加载内容 AJAX Jquery - 需要如何将数据发送到加载的页面?

javascript - 寻找最近的祖先

javascript - 计算 ng-repeat 使用 Selenium webdriver 生成的选项卡集中的选项卡数量

Java 正则表达式 后向查找

For 循环中的 Python 列表

javascript - 如何四舍五入到只有秒(删除毫秒)

regex - 使用正则表达式从行中提取子字符串并删除具有重复子字符串的行

java - 使用扫描仪从文本文件中挑选出特定信息

java - 在复杂的定界符上有条件地拆分字符串

char* 会导致段错误,但 char[] 不会