获取不在标记中的匹配字符串

时间:2013-09-03 09:57:05

标签: javascript regex

我想从html字符串中获取字符串hello world,如下所示:

Hello world! hello world! Hello world! <a href="#">hello world</a><p>hello world</p><p><a href="#">hello world</a></p>

但我不想在hello world标记中获取a。例如:

<a href="#">hello world</a>

<p><a href="#">hello world</a></p>

不匹配。

我的代码:

var replacepattern = new RegExp('hello world(?![^<]*>)',"ig");

返回字符串中的所有hello world。有什么想法吗?

修改

我使用(?![^<]*>)以防:<p title="hello world"> hello world</p>。 所以我没有在标签属性中获得hello world

编辑2:

我想要返回字符串:

'<a href="#hello world">Hello world</a>! <a href="#hello world">Hello world</a>! <a href="#hello world">Hello world</a>! <a href="#">Hello world</a><p><a href="#hello world">Hello world</a></p><p><a href="#">Hello world</a></p>'

4 个答案:

答案 0 :(得分:1)

假设您在字符串中输入了HTML:

var str = 'Hello world! hello world! Hello world! <a href="#">hello world</a><p>hello world</p><p><a href="#">hello world</a></p>';

我们不会想出复杂的REGEX模式来匹配它,而是将HTML放在HTML容器中,并使用JavaScript内置到每个浏览器中的强大DOM api来处理它。

var el = document.createElement("div");
el.innerHTML = str;

现在,让我们从我们的元素中获取所有a标记,并自行删除它们

var aTags = el.getElementsByTagName("a");
while(aTags.length > 0){ // while the element still has a tags 
    aTags[0].parentNode.removeChild(aTags[0]); //remove
}

现在,我们可以返回HTML并获取正确的文本内容

el.innerHTML; 

现在是:

"Hello world! hello world! Hello world! <p>hello world</p><p></p>"

现在,如果我们只想要没有标签的文本,我们也可以这样做。

el.textContent;

将评估为:

"Hello world! hello world! Hello world! hello world"

答案 1 :(得分:1)

描述

此表达式将:

  • 允许您仅替换锚标记之外的hello world子字符串
  • 避免困难的边缘情况,这使得HTML中的模式匹配变得困难
  • 不使用原子组,因为它们在Javascript中不被允许

<强>正则表达式

((?:<a(?=\s|>)(?:[^>=|&)]|='(?:[^']|\\')*'|="(?:[^"]|\\")*"|=[^'"][^\s>]*)*>.*?<\/a>|(?!hello\sworld|<a\s).)*)(hello\sworld\s\d+)((?:<a(?=\s|>)(?:[^>=|&)]|='(?:[^']|\\')*'|="(?:[^"]|\\")*"|=[^'"][^\s>]*)*>.*?<\/a>|(?!hello\sworld|<a\s).)*)

Full Explaination

理论值:

  • ((?:<a(?=\s|>)(?:[^>=|&)]|='(?:[^']|\\')*'|="(?:[^"]|\\")*"|=[^'"][^\s>]*)*>.*?<\/a>|(?!hello\sworld|<a\s).)*)捕获锚标记以及非hello world锚标记之外的任何文本。这是第1组
  • (hello\sworld\s\d+)夺取你好世界。这是第2组。由于我在示例文本中添加了数字以帮助显示正在捕获哪些子字符串,因此我还在此部分添加了\s\d+。可以说这超出了原来的范围。 <子>:)
  • ((?:<a(?=\s|>)(?:[^>=|&)]|='(?:[^']|\\')*'|="(?:[^"]|\\")*"|=[^'"][^\s>]*)*>.*?<\/a>|(?!hello\sworld|<a\s).)*)捕获锚标记以及非hello world锚标记之外的任何文本。这是组3.它与组1的模式相同,但是是必需的,否则你可能会在字符串的最后一个匹配中遇到奇怪的结果。

替换为

在下面的示例中,我使用此替换来帮助更明显地发生了什么:

$1_______$3

您可以使用此代码将hello world字符串替换为锚标记:

$1<a href="$2">$2</a>$3

enter image description here

实施例

示例文字

使用onmouseover属性注意锚标记中的困难边缘情况。我还为每个hello world添加了数字,以便我们人类更容易阅读。

<a href="#">hello world 00</a>Hello world 1! hello world 2! Hello world 3! <a onmouseover=' a=1; href="www.NotYourURL.com" ; if (3 <a && href="www.NotYourURL.com" && id="revSAR" && 6 > 3) { funRotate(href) ; } ; ' href="#">hello world 04</a><p>hello world 5</p><p><a href="#">hello world 06</a></p> <a href="#">hello world 07</a>fdafdsa

示例Javascript

<script type="text/javascript">
  var re = /((?:<a(?=\s|>)(?:[^>=|&)]|='(?:[^']|\\')*'|="(?:[^"]|\\")*"|=[^'"][^\s>]*)*>.*?<\/a>|(?!hello\sworld|<a\s).)*)(hello\sworld\s\d+)((?:<a(?=\s|>)(?:[^>=|&)]|='(?:[^']|\\')*'|="(?:[^"]|\\")*"|=[^'"][^\s>]*)*>.*?<\/a>|(?!hello\sworld|<a\s).)*)/;
  var sourcestring = "source string to match with pattern";
  var replacementpattern = "$1<a href="$2">$2</a>$3";
  var result = sourcestring.replace(re, replacementpattern);
  alert("result = " + result);
</script>

替换后的字符串

这只是为了显示正在发生的事情,使用第一个“替换为”

<a href="#">hello world 00</a>_______! _______! _______! <a href="#">hello world 04</a><p>_______</p><p><a href="#">hello world 06</a></p> <a href="#">hello world 07</a>fdafdsa

这是使用第二个“替换为”来显示它实际上是如何工作的

<a href="#">hello world 00</a><a href="Hello world 1">Hello world 1</a>! <a href="hello world 2">hello world 2</a>! <a href="Hello world 3">Hello world 3</a>! <a onmouseover=' a=1; href="www.NotYourURL.com" ; if (3 <a && href="www.NotYourURL.com" && id="revSAR" && 6 > 3) { funRotate(href) ; } ; ' href="#">hello world 04</a><p><a href="hello world 5">hello world 5</a></p><p><a href="#">hello world 06</a></p> <a href="#">hello world 07</a>fdafdsa

答案 2 :(得分:0)

大多数浏览器现在都支持负前瞻功能,您可以尝试以下方法:

(?![^>]*<\/[a-zA-Z]>)(Hello world)

演示:https://regex101.com/r/rDPp0t/2/

答案 3 :(得分:-1)

我认为这会奏效:

var str = 'Hello > world <! Hello > world <! Hello > world <! <a href="#">Hello > world <</a><p>Hello > world <</p><p><a href="#">Hello > world <</a></p>';
var textToReplace = 'Hello > world <'
var re = new RegExp('(?!(^<*(href=)*(>)))' + textToReplace + '(?!(</a>))',"ig");
var result = str.replace(re, '@');
console.log(result);

结果是

@! @! @! <a href="#">Hello > world <</a><p>@</p><p><a href="#">Hello > world <</a></p> 

这是你想要达到的目标吗?

JsFiddle - &gt; http://jsfiddle.net/Che3v/1/