JS Regex匹配不是<a></a>的HTML标记中的字符串

时间:2015-03-16 16:32:11

标签: javascript regex

我正在使用jQuery来突出文章中的缩写,并且正在努力学习我的正则表达式。

我正在尝试匹配HTML标记中的单词(而不是像<img src="abbr" />这样的属性中的特定文本),而不是另一个单词的一部分,而且还不在<a>标记内。< / p>

然后我将用<abbr>标签和指向词汇表的链接包装它。

我已经得到了一点点,我目前的正则表达式看起来像这样:

(\>[^\>]*\W)abbr(\W[^\>=]*\<)

哪里&#34; abbr&#34;是I&#39; m试图匹配的缩写。这种方式有效,但如果abbr是一行的第一个单词,或者它是否在<a>标记内,则无效。

&#34; abbr&#34;的这些实例我想要匹配:

<p>Lorem abbr ipsum</p>
<p>abbr lorem abbr</p>
<ul>
  <li>abbr abbr</li>
  <li>abbr</li>
</ul>

虽然我不想匹配其中任何一个:

<p><a href="abbr.html">abbr</a></p>
<img src="abbr.jpg" />
<p>Lormabbripsum</p>

为此,我选择了文章中的所有HTML,目的是进行字符串替换。我的JS看起来像这样

$.getJSON("glossaryjson", function (data) {
    var str = $('.article-body').html();

    var i;
    for (i = 0; i < data.length; i++) {

        var regex = new RegExp("(\>[^\p>]*\\W)" + data[i].name + "(\\W[^\>=]*\<)");

        str = str.replace(regex, '$1<abbr title="' + data[i].desc + '"><a href="/glossary?f=' + data[i].letter + '">' + data[i].name + '</a></abbr>$2');
            }

    $('.article-body').html(str);
});

2 个答案:

答案 0 :(得分:0)

如果你可以使用jQuery,你可以找到符合你想要的元素(不是<a>元素而不是父元素),然后只使用你的正则表达式匹配的文本。例如......

$(':not(a, :has(*))').filter(function(i,e){return !!e.innerHTML.match(/\babbr\b/)})

否则,你只需要类似的东西......

function filterAbbr() {
    var all = document.getElementsByTagName('*');
    var filter = [];
    for(var i=0; i<all.length; i++) {
        if(!all[i].children.length && all[i].tagName != 'A') {
            filter.push(all[i]);
        }
    }
    all = [];
    for(var i=0; i<filter.length; i++) {
        if(filter[i].innerHTML.match(/\babbr\b/)) {
            all.push(filter[i]);
        }
    }
    return all;
}

答案 1 :(得分:0)

我们可以使用单词边界'\ b'来阻止它在单词中间找到abbreciations。然而,它并不完美。假设您正在寻找I.A.它会在C.I.A中找到匹配。因为句号是单词边界的一部分。

此外,我们可以使用正向前瞻(LA)和负向前瞻(NLA)来向前看并根据内容做出决定。

我不认为正则表达式是理想的,因为单词边界问题,并且因为当在html文档中投射如此宽的网时,事情会变得毛茸茸(如果你是非理想的html)

\babbr\b(?=(?![^>]*<\/a>)[^>]*)

\b             # Token: \b
                 # word boundary
abbr           # Literal abbr
\b             # Token: \b
                 # word boundary
(?=            # Opens LA
 (?!           # Opens NLA
  [^>]*        # Negated Character class (excludes the characters within)
                 # None of: >
                 # * repeats zero or more times
  <\/a>        # Literal </a>
 )             # Closes NLA
 [^>]*         # Negated Character class (excludes the characters within)
                 # None of: >
                 # * repeats zero or more times
                 # Literal <
)              # Closes LA