1

我想让以@或#开头的主题标签的正则表达式匹配,而不是包含在html锚标签中。我的表达:(@|#)([a-zA-Z_]+)(?!<\/[a])不起作用,因为在文本中:

<p>@john Olor it amet, consectetuer adipiscing elit. 
Aenean commodofadgfsd 
<a class="autocompletedTag" href="#" data-id="u:2">@john_wayne</a></p>

匹配@johnand @john_wayne,但我不想匹配@john_wayne

我怎样才能做到这一点?

例子

在代码中:

<p>@john @kate <a>@royal_baby</a> #england <a>#russia</a></p>

我想匹配@john,@kate#england,但 @royal_baby匹配and #russia

在这段代码中:

<p>#sale #stack #hello <a>@batman</a> #avengers <a>#iron_man</a></p>

我想匹配#sale, #stack, #helloand #avengers,但 @batman匹配and #iron_man

4

1 回答 1

2

您可以使用以下正则表达式:

/(<a[^>]*>.*?[@#][a-zA-Z_]+.*?<\/a>)|([@#][a-zA-Z_]+)/g

这个想法是匹配这两种情况并使用回调来过滤它们:

input = '<p>@john Olor it amet, consectetuer adipiscing elit.\
Aenean commodofadgfsd \
<a class="autocompletedTag" href="#" data-id="u:2">@john_wayne</a></p>\
<p>@john @kate <a>@royal_baby</a> #england <a>#russia</a></p>\
<p>#sale #stack #hello <a>@batman</a> #avengers <a>#iron_man</a></p>';

matches = new Array(); //empty array
input.replace(/(<a[^>]*>.*?[@#][a-zA-Z_]+.*?<\/a>)|([@#][a-zA-Z_]+)/g, function(all, a, result){
    if(result){ // If the second group exists
        matches.push(result); // then add it to matches
    }
});

document.getElementById('results').innerHTML = matches.join(); // Store results

在线jsfiddle

解释

  • [@#]: 匹配一次@#一次
  • [a-zA-Z_]+: 匹配字母和下划线一次或多次
  • <a: 匹配<a
  • [^>]*>: 匹配除>零次或多次以外的任何内容并>在最后匹配
  • .*?[@#][a-zA-Z_]+.*?: 匹配<a></a>ungreedy之间的内容
  • <\/a>: 匹配结束标签</a>
于 2013-08-14T08:31:16.453 回答