如何用JavaScript正则表达式替换href中的所有内容

How can I replace everything inside an href with JavaScript regex?

本文关键字:href 何用 JavaScript 正则表达式 替换      更新时间:2023-09-26

我的文本类似于:

<a href="http://example.com/test this now">Stuff</a>
More stuff
<a href="http://example.com/more?stuff goes here">more</a>

我想用一个只对URL部分进行URL编码的函数来替换href中的内容。

我该怎么做?

更新以下是我尝试过的:

postdata.comment.content = postdata.comment.content.replace(/href='"(.+?)'"/g, function(match, p1) {
    return encodeURI(p1);
});

没有达到我的期望。

预期结果为:

<a href="http%3A%2F%2Fexample.com%2Ftest%20this%20now">Stuff</a>
More stuff
<a href="http%3A%2F%2Fexample.com%2Fmore%3Fstuff%20goes%20here">more</a>

正则表达式匹配完整的属性href="....",但是,替换仅由编码的URL完成,并使用encodeURIComponent()对完整的URL进行编码。

var string = '<a href="http://example.com/test this now">Stuff</a>';
string = string.replace(/href="(.*?)"/, function(m, $1) {
    return 'href="' + encodeURIComponent($1) + '"';
    //      ^^^^^^                     ^
});

var str = `<a href="http://example.com/test this now">Stuff</a>
More stuff
<a href="http://example.com/more?stuff goes here">more</a>`;
str = str.replace(/href="(.*?)"/g, (m, $1) => 'href="' + encodeURIComponent($1) + '"');
console.log(str);
document.body.textContent = str;

对于编码,可以使用encodeURIComponent:

var links = document.querySelectorAll('a');
for(var i=0; i<links.length; ++i)
  links[i].href = encodeURIComponent(links[i].href);
<a href="http://example.com/test this now">Stuff</a>
More stuff
<a href="http://example.com/more?stuff goes here">more</a>

如果您只有一个HTML字符串而不是DOM元素,那么请使用不使用正则表达式。请改用DOM解析器来解析字符串。

var codeString = '<a href="http://example.com/test this now">Stuff</a>'nMore stuff'n<a href="http://example.com/more?stuff goes here">more</a>';
var doc = new DOMParser().parseFromString(codeString, "text/html");
var links = doc.querySelectorAll('a');
for(var i=0; i<links.length; ++i)
  links[i].href = encodeURIComponent(links[i].href);
document.querySelector('code').textContent = doc.body.innerHTML;
<pre><code></code></pre>

请注意,如果您对URL进行完全编码,它将被视为相对URL。

免责声明:不要使用regex解析HTML
(原因太多,无法在此列出。)

但是,如果你坚持,这可能会奏效。

查找/(<['w:]+(?:[^>"']|"[^"]*"|'[^']*')*?'shref's*='s*)(?:(['"])(['S's]*?)'2)((?:"['S's]*?"|'['S's]*?'|[^>]*?)+>)/

替换$1$2+someEncoding($3)+$2$4

扩展

 (                             # (1 start)
      < ['w:]+ 
      (?: [^>"'] | " [^"]* " | ' [^']* ' )*?
      's 
      href 's* = 's* 
 )                             # (1 end)
 (?:
      ( ['"] )                      # (2)
      (                             # (3 start)
           ['S's]*? 
      )                             # (3 end)
      '2 
 )
 (                             # (4 start)
      (?: " ['S's]*? " | ' ['S's]*? ' | [^>]*? )+
      >
 )                             # (4 end)

这是在哪里运行的?如果您有DOM,那么在document.links或document.querySelectorAll("a")上使用DOM循环比在HTML上使用regex要好得多。此外,您可能不想对所有内容进行编码,只想对搜索部分进行编码

var allLinks = document.querySelectorAll("a");
for (var i=0;i<allLinks.length;i++) {
   var search = allLinks[i].search;
   if (search) {
     allLinks[i].search="?"+search.substring(1).replace(/stuff/,encodeURIComponent("something"));
   }
}

如果你真的想有编码的hrefs,然后

for (var i=0;i<allLinks.length;i++) {
   var href = allLinks[i].href;
   if (href) {
     allLinks[i].href=href.replace(/stuff/,encodeURIComponent("something"));
   }
}

您期望的字符串"http%3A%2F%2Fexample.com%2Ftest%20this%20now"对应于此操作encodeURIComponent("http://example.com/test this now"),但不与encodeURI函数对应:

var str = '<a href="http://example.com/test this now">Stuff</a>More stuff<a href="http://example.com/more?stuff goes here">more</a>';
str = str.replace(/href='"(.+?)'"/g, function (m, p1) {
    return encodeURIComponent(p1);
});
console.log(str);
// <a http%3A%2F%2Fexample.com%2Ftest%20this%20now>Stuff</a>More stuff<a http%3A%2F%2Fexample.com%2Fmore%3Fstuff%20goes%20here>more</a>