【问题标题】:skip regex matching if the match is within a particular html tag如果匹配在特定的 html 标记内,则跳过正则表达式匹配
【发布时间】:2015-04-06 20:53:59
【问题描述】:

这是对以下内容的跟进: Javascript regex placeholder prints string instead of its value

我正在尝试构建一个 javascript 函数来查找模式并将其转换为链接。

var re = /Ticket-([0-9]*?(?=-)-[0-9]*)/; 
var str = 'ASD Ticket-492-367 - Make my day.'; 
t = str.replace(re,'<a href="http://myworld/ticket/$1">$&</a>')

我现在遇到了一个问题,如果我的字符串已经包含&lt;a&gt; 标签,它会尝试将额外的标签锁定在它上面,这会使输出变得时髦。正则表达式匹配是否有特定的 jQuery/JS 方式以某种方式跳过放置在特定标签内的内容。就像,以某种方式在内容周围包裹一个&lt;div&gt; 标记,然后将其解析为一个DOM 节点......并以这种方式对其进行操作。我对 JS 很陌生,如果我的想法完全不正确,请道歉

更新:针对用例。假设我收到的文本已经有一个链接,如下所示:

<a href="http://myworld/ticket/4385-21557">Ticket-4385-21557 - abc xyz</a>

这将在匹配的字符串“Ticket-4385-21557”周围包裹另一个标签。这是系统中已有的旧字符串,无法更改。所以这个想法是通过跳过&lt;a&gt;标签内的字符串来解决它

【问题讨论】:

标签: javascript jquery html regex


【解决方案1】:

完整的答案取决于对您正在处理的输入的更多了解,但我认为我肯定可以让您走上正确的道路。

没有固有的方式来说“替换这个东西除非它在另一个东西中。”但是,您可以结合交替和函数替换来解决这个问题。

在你的问题的核心,你实际上在寻找两个不同的东西:&lt;a&gt; 标签,你希望忽略它,以及专门格式化的字符串(我将在这里简化为看起来像 @ 987654323@ 为了保持这个答案简单)。这表明交替。问题是,你如何告诉正则表达式识别选择了哪个交替?最简单的方法是使用函数替换:

var test = '<a href="#">Ticket-37</a> blah blah Ticket-42';
// expected output:
// <a href="#">Ticket-37</a> blah blah <a href="#">Ticket-42</a>
var output = test.replace(/<a\s.*?<\/a>|Ticket-(\d+)/g, function(m, g1) {
    if(/^<a\s/.test(m)) return m;  // ignore existing links
    return '<a href="#">Ticket-' + g1 + '</a>';
});

这里发生的情况是 .replace 调用正在寻找 &lt;a&gt; 标记或看起来像 /Ticket-\d+/ 的东西,它将全部替换。然而,使用&lt;a&gt; 标签,它只是简单地将它们替换为原来的标签;基本上不修改它们(这是一个很好的功能,因为如果您还需要清理它们,您实际上可以在此处重新格式化 &lt;a&gt; 标签)。

Standard caveat 适用于将正则表达式与 HTML 一起使用:您不能保证使用正则表达式正确解析 HTML。 HTML 不是常规语言,因此您能做的最好的事情就是涵盖大多数 合理的情况。它当然有可能构造出会挫败这种方法的 HTML。你有可能在现实中看到吗?取决于你的现实是什么,但可能不是。 “稳健”的解决方案是使用 HTML 解析器并查找文本节点(不是 &lt;a&gt; 节点的直接子节点)并在解析后的树中进行替换。

【讨论】:

  • 感谢您的详细回复。我沿着类似的路线走,但认为可能有一个 jQuery 函数可以巧妙地完成它。感谢您的帮助。
【解决方案2】:

如果您从 DOM 元素中获取 str,您可以使用 .text() 仅获取没有 html 的文本

HTML

<div class="with-anchor"><a href="http://example.com">ASD Ticket-492-367</a> - Make my day.</div>

JS

var str = $("div.with-anchor").text(); // ASD Ticket-492-367 - Make my day.

【讨论】:

  • 这非常有用,但我想知道 OP 是否想要它没有“ASD Ticket-492-367”部分。
  • 我相信我试过但没有得到正确的结果。可能是因为我有其他不能很好地协同工作的包装器。我再试一次。谢谢。
【解决方案3】:

aopen 的正则表达式

/<a.*href=\".*"?">>?/ig  

关闭的正则表达式

/(<\/a>)?<\s?\/a?>?\s>/ig

您可能希望在使用原始正则表达式之前使用它们来解析字符串。 a.e

var t = str.replace(aopen, '');
t = t.replace(aclose, '');
t = t.replace(re, '<a href="blahblah">$&</a>);
document.write(t);

我创建了一个小提琴,但由于某种原因它无法保存。这是我的代码-Javascript:

window.onload = function() {
var re = /Ticket-([0-9]*?(?=-)-[0-9]*)/g; 
var str = document.body.innerHTML; 
var aopen = /<a.*href=\".*"?">>?/ig;
var aclose = /(<\/a>)?<\s?\/a?>?\s>/ig
t = str.replace(aopen, '');
t = t.replace(aclose, '');
t = t.replace(re,'<a href="http://myworld/ticket/$1">$&</a>')
document.write(t);
}

这是我的代码 - HTML:

<!DOCTYPE html>
<html>
<body>
Ticket-445-1235 - Make my day<br>
Ticket-445-1255 - Make his day<br>
Ticket-443-4356 - He's feeling lucky<br>
Ticket-443-5555 - punk<br>
<a href="whatever.txt">Ticket-423-5557 - Sdadf </a> <br>
</body>
</html>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 2012-04-02
  • 1970-01-01
  • 2022-12-11
  • 2011-04-01
相关资源
最近更新 更多