1

I have a string: <li>&File</li>. What I would like to do is analyse the string inside the li element to find the location of the ampersand. Once found, I'd like to wrap the next character inside a span.

The logic behind this is relatively straightforward. Get the string position of &, remove it and then wrap the following character (i.e. string position + 1) in a span.

Could anyone suggest a suitable method in jQuery to wrap a single character of a string? I know it's possible to wrap a block of HTML, but can one work on strings like this, or would it be better to create a custom function?

I should mention that the position of & will not always be at the beginning of the string, either. I was thinking to use Regular Expressions for finding its position, since I only want to parse the first occurance of an ampersand within the string, thus leaving later occurances untouched.

The ampersand is not a HTML entity - it's simply & (and not &amp;).

Any help and insight most gratefully received...

BenM
  • 52,573
  • 26
  • 113
  • 168
  • I think regex is the best approach possible. – samura Nov 14 '11 at 18:28
  • 2
    When parsing the text I would consider using something other than Ampersand to find the letters that need to be modified or wrapped. This is because ampersand is used in HTML and you don't want to make cases for all the special characters. – John Hartsock Nov 14 '11 at 18:29
  • 1
    @samura Was that a [joke](http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454)? – Andrew Nov 14 '11 at 18:30
  • "The ampersand is not a HTML entity - it's simply & (and not `&`)," isn't that invalid? I was under the impression that, as the `&` has significance within html, it was required to be encoded as `&`? – David Thomas Nov 14 '11 at 18:34

6 Answers6

2

Since it's one character, you can just use .replace; no need for special jQuery functions: http://jsfiddle.net/qr3pe/1/.

$("li").each(function() {
    var html = $(this).html(),     // this element's html
        regexp = /&amp;(.)/,       // regexp (.html() returns &amp; even
                                   // if the source is &). `()` to capture.
        match = regexp.exec(html); // get the captured character

    if(!match) return; // no match; abort

    var replaced = html.replace(regexp,
                                "<span>" + match[1] + "</span>");

    $(this).html(replaced); // replace the html
});
pimvdb
  • 151,816
  • 78
  • 307
  • 352
  • You could combine the regexp, match, and replace part into a single command, and also apply it to all matches instead of just the first with: '
  • &hello
  • &world
  • '.replace(/&(.)/g, '$1') – Gerben Nov 14 '11 at 18:36
  • @Gerben: Looking at it, I think `.each` might be a slightly cleaner solution. Thanks, my solution is replacing all `li`s with the first one's html. – pimvdb Nov 14 '11 at 18:39
  • .each is nicer indeed. But using 4 lines of code instead of just one? – Gerben Nov 14 '11 at 18:50
  • 1
    @Gerben: That's just for making place for some comments on each part of the code :) – pimvdb Nov 14 '11 at 18:51