3
var content = "This is dummy <a href='#'>content</a> for my <a href='#'>Search String</a> and here is another Search String without an anchor tag",
    searchString = "Search String";

Using regular expressions in javascript/jquery, how can I determine if the FIRST searchString in content string is wrapped in an anchor tag or not? I only need a boolean true/false to determine if this is directly wrapped by

Greg
  • 1,045
  • 4
  • 14
  • 30
  • 1
    Beware of the perils of [parsing HTML with regular expressions](http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags). What have you tried so far? – Matt Oct 22 '13 at 16:12

1 Answers1

5

The most reliable way is to parse the HTML and search recursively for the first occurence of the text. Then, check whether the/a parent of that text node is an anchor.

Here is a generic function I've written:

/**
  * Searches for the first occurence of str in any text node contained in the given DOM
  * @param {jQuery} dom A jQuery object containing your DOM nodes
  * @param {String} str The string you want to search for.
  * @returns {Object} Returns either null or the text node if str was found.
  */
function searchFirstTextOccurrence(dom, str) {
    var foundNode = null;

    dom.contents().each(function (idx, node) {
        if (node.nodeType == Node.TEXT_NODE) {
            if (node.textContent.indexOf(str) !== -1) {
                foundNode = node;
                // break out of each()
                return false;
            }
        } else if (node.nodeType == Node.ELEMENT_NODE) {
            var foundInnerNode = searchFirstTextOccurrence($(node), str);
            if (foundInnerNode) {
                foundNode = foundInnerNode;
                // break out of each()
                return false;
            }
        }
    });
    return foundNode;
}

Your use case:

→ jsFiddle

var content = "This is<div> dummy <a href='#'>content</a> for my <a href='#'>Search String</a> and</div> here is another Searchx String without an anchor tag";
var searchString = "Search String";

var dom = $("<div>" + content + "</div>");
var firstOccurence = searchFirstTextOccurrence(dom, searchString);
if ($(firstOccurence).closest("a").length > 0) {
    console.log("Yep");
} else {
    console.log("No");
}
ComFreek
  • 29,044
  • 18
  • 104
  • 156
  • Check this case: http://jsfiddle.net/acdcjunior/xnVVp/ the function still may need a little tweaking. – acdcjunior Oct 22 '13 at 16:53
  • Looks like this could potentially work, i don't get the reason behind you using the double div's. Seems to work with just single. @acdcjunior also did point out a flaw if it is already wrapped in a
    – Greg Oct 22 '13 at 17:33
  • @Greg That was because `:contains` wouldn't have matched `Search String` if it wasn't contained in any anchor, for example: `
    Search String
    ` would fail, but `
    Search String
    ` wouldn't. Anyway, please take a look at the update. I gave up on :contains and switched to a recursive solution.
    – ComFreek Oct 22 '13 at 18:51
  • @ComFreek there was still a problem with `Search String`. But I think using `closest()` may solve it. Check it out: http://jsfiddle.net/acdcjunior/xnVVp/6/ (does it make sense?) – acdcjunior Oct 22 '13 at 19:43
  • 1
    Yeah, glad it helped. I think that's it now. Nice answer! I'd upvote it, but I already did :) – acdcjunior Oct 22 '13 at 20:40