2

I need to get the javascript replace() function to replace every instance of a [b] or [/b] with <b> or </b>. I tried this with the global tag but it doesn't work and comes out oddly:

document.write(str.replace(/[b]/g,'<b>').replace(/[/b]/g,'</b>'));

results in the output being:

[<>]<>la<>la[<>][<>]<>la<>la[<>] 

I also tried changing the first part to:

  document.write(str.replace(/[[b]]/g,'<b>').replace(/[[/b]]/g,'</b>'));

which kind of works, but there's odd ]s everywhere... like so:

[blabla[/[blabla[/

I know there's probably something obvious I'm missing here... But I can't find it... any help and I will love you forever XD

georg
  • 211,518
  • 52
  • 313
  • 390
Elizabeth
  • 173
  • 3
  • 14

2 Answers2

4

[, ] and / are special RegExp characters.

  • [a] means: Match any a character. [abcd] means: Match one character, which is one of a, b, c, d. [a-z] means: Match any letter.
  • / is used to mark the beginning and end of a RegExp.

To use the literal characters, they have to be escaped.

str.replace(/\[b\]/g,'<b>').replace(/\[\/b\]/g,'</b>')

Note that both Regular expressions can be merged, using a backreference:

str.replace(/\[(\/?)b\]/g,'<$1b>')
// Replaces [b] with <b>, [/b] with </b>
Rob W
  • 341,306
  • 83
  • 791
  • 678
  • Thanks for the info on the special chars, duly noted ^-^ I wish I could choose both answers as right! – Elizabeth Feb 13 '12 at 21:27
  • @user1054798 You can accept the answer which was the most helpful (= solved your problem, preferrably with a clear explanation). This answer should be the answer to the core question **as posted in the question post**. Additionally, you can upvote posts which are also really **helpful**, such as bonus tips. – Rob W Feb 13 '12 at 21:32
  • I haven't got the necessary reputation to upvote, but I aim to do so for all questions as soon as I reach it :D I'll just test a little more using all solutions posted, to see which works best for my needs! – Elizabeth Feb 13 '12 at 21:41
  • Yep, did so just now when I saw the rep increase :D Didn't want to double post, some forums consider it a nuisance... – Elizabeth Feb 13 '12 at 21:53
-2

You might be much better off replacing 'em both at once:

 str = "[b]foo[/b] and [b]bar[/b]"
 str.replace(/\[b\](.+?)\[\/b\]/g,'<b>$1</b>') // <b>foo</b> and <b>bar</b>

You can also go one step further and handle multiple formatting codes (b, i, u and s in this example) with one single regular expression:

str = "[b]foo[/b] and [i]bar[/i]"
str.replace(/\[([bius])\](.+?)\[\/\1\]/g,'<$1>$2</$1>')

Expressions like this (with (.+?)) are better than yours because they only handle valid markup and ignore unclosed [tags].

georg
  • 211,518
  • 52
  • 313
  • 390
  • if you are nesting BB code elements of the same type, this will not work. For example if you have lists in lists, it will skip tags. `[li][ul][li][/li][/ul][/li]` will match the first `[li]` with the first `[/li]` leaving the 2nd `[li]` in place and unable to match unless you run the replace twice. – Ben Feb 13 '12 at 21:10
  • @BenjaminUdinktenCate: sure, you cannot parse nested markup using only regular expressions, at least in javascript flavour, which lacks recursive constructs. Still, I consider my solution "good enough" for OP's requirements which are obviously much simpler than your example. – georg Feb 13 '12 at 21:22
  • Thanks! I saw the (.+?) parts somewhere before but couldn't make out what they were for (I thought they were part of what was being changed or something... the code worked perfectly and you saved me a /lot/ of trouble having to do the one for all kinds of bbcode there :D Sorry to further trouble, but could you tell me also how I could have any Enter replaced with
    and things like [quote] replaced with the html equivalent? I figure replacing the bius will just result in it replacing any q, u, o, t or e... And yeah nested are not really a concern atm XD This is much simpler :P
    – Elizabeth Feb 13 '12 at 21:25
  • @user1054798 `.+?` does not match enough. It doesn't include newlines, for example. You have to use `[\S\s]+?`, which matches all characters. As for the BB parser, a **simple RegExp** is **not sufficient**. I have previously written a well-working JavaScript BBCode parser (code taken offline), but (part of) the logic is posted at [this answer](http://stackoverflow.com/a/7527187/938089?how-to-check-that-all-html-tags-are-closed-with-regex). – Rob W Feb 13 '12 at 21:34
  • Would you suggest I use +? instead of .+? and then without brackets? I'll check out the parser, thanks :) – Elizabeth Feb 13 '12 at 21:39
  • @user1054798: Unless you're doing this for learning purposes, do yourself a favour and use a ready-made parser. I cannot recommend you anything specific, but have a look at [this thread](http://stackoverflow.com/questions/1843320/any-good-javascript-bbcode-parser), there are some pointers. – georg Feb 13 '12 at 21:40
  • Learning purposes ultimately, coding is something that fascinates me to take apart and I'd love to be better at it :P But I'll definitely look at the parser, thanks! – Elizabeth Feb 13 '12 at 21:43
  • @user1054798 For learning purposes, I would recommend to think of an (smart) algorithm, then implement it. I mentioned a link containing a (basic) algorithm to parse BB-codes, in my previous comment. – Rob W Feb 13 '12 at 21:48