alt
alt

Reputation: 13907

Selecting All Text After A "#" Symbol With Regular Expressions

I've got this bit of jQuery with some javascript and RegEx mixed in:

$(function() {
    var regExp = new RegExp("\\b(" + "hashtag" + ")\\b", "gm");
    var boxLink = "<a class='taglink' onClick='tagBox()'>$1</a>"
    var html = $('body').html();
    $('body').html(html.replace(regExp, boxLink));
});

function tagBox() {
    alert("It works!")
};

Basically it applies $1 to everywhere that the word "hashtag" appears. Tagbox just brings up an alert that says it works. Simple enough. The change I'd like to make is one so that it won't jet select the word "hashtag", but all words with "#" symbols before them.

How can I accomplish this and work it into the script above?

Thanks in advance!

Upvotes: 3

Views: 443

Answers (2)

davidchambers
davidchambers

Reputation: 24806

First of all, $('body').html(html) is a really bad idea. You'll recreate the DOM, and any event listeners previously bound to nodes within the old structure will no longer function. Traversing the DOM node by node is a better idea. Something like this should do the trick:

// Douglas Crockford's WalkTheDOM
function walkTheDOM(node, func) {
  func(node);
  node = node.firstChild;
  while (node) {
    walkTheDOM(node, func);
    node = node.nextSibling;
  }
}

function esc(text) {
  return text.replace(/[&<>"'`]/g, function (chr) {
    return '&#' + chr.charCodeAt(0) + ';'
  })
}

walkTheDOM(document.body, function (node) {
  if (node.nodeType === 3) {
    var html = ''
    // The even indexes contain the hashtags; the odd indexes contain
    // the text that appears between one hashtag and the next.
    // 
    // > 'This post is tagged #javascript and #jquery'.split(/(#\w+)/)
    // ["This post is tagged ", "#javascript", " and ", "#jquery", ""]
    // 
    // Text must be escaped before being inserted via `.html()`.
    $.each(node.textContent.split(/(#\w+)/), function (idx, text) {
      html += idx % 2 ? esc(text) : '<a class="taglink">' + esc(text) + '</a>'
    })
    $(node).parent().html(html)
  }
})

This code is untested, and no doubt has some bugs, but hopefully I've convinced you that this problem is more difficult than it may have appeared at first.

Upvotes: 2

Cheery
Cheery

Reputation: 16214

Try something like this

var regExp = new RegExp("(#\w+)", "gm");

If you want to select a word without #, move it in front of the (

Upvotes: 1

Related Questions