3

I've made a working regexp, but i think it's not the best use-case:

el = '<div style="color:red">123</div>';
el.replace(/(<div.*>)(\d+)(<\/div>)/g, '$1<b>$2</b>$3');
// expecting result: <div style="color:red"><b>123</b></div>

After googling i've found that (?: ... ) in regexps - means ignoring group match, thus:

el.replace(/(?:<div.*>)(\d+)(?:<\/div>)/g, '<b>$1</b>');
// returns <b>123</b>

but i need an expecting result from 1st example.

Is there a way to exclude 'em? just to write replace(/.../, '<b>$1</b>')?

This is just a little case for understanding how to exclude groups in regexp. And i know, what we can't parse HTML with regexp :)

ekad
  • 14,436
  • 26
  • 44
  • 46
mjey
  • 183
  • 2
  • 9

2 Answers2

3

So you want to get the same result while only using the replacement <b>$1</b>?

In your case just replace(/\d+/, '<b>$&</b>') would suffice.

But if you want to make sure there are div tags around the number, you could use lookarounds and \K like in the following expression. Except that JS does not support lookbehind nor \K, so you're out of luck, you have to use a capturing group for that in JS.

<div[^>]*>\K\d+(?=</div>)
Qtax
  • 33,241
  • 9
  • 83
  • 121
  • Oops, i've mispelled. `el.replace(/(?:)(\d+)(?:<\/div>)/g, '$1');` returns just `123` – mjey Apr 01 '12 at 10:09
  • Yes, the aim is to match digits around specified tag. That's sad js doesn't support `\K` – mjey Apr 01 '12 at 10:39
  • Hmm, this `'
    123
    555
    '.replace(/(?!)(\d+)(?=<\/div>)/g, '$1')` is working (result: `"
    123
    555
    "`). But i dont understand why it's working, since `(?!` means negative lookahead. `(?<=` doesn't work.
    – mjey Apr 01 '12 at 10:57
  • @mjey it's working because `\d+` is working. Try it on the string `123`. *Negative* lookahead means whatever is ahead should **not** match the expression. – Qtax Apr 01 '12 at 11:11
  • Okay, understood. But as you can see, positive lookahead works (chrome 18) :) – mjey Apr 01 '12 at 11:15
0

There nothing wrong with a replacement value of '$1<b>$2</b>$3'. I would just change your regex to this:

el = '<div style="color:red">123</div>';
el.replace(/(<div[^>]*>)(\d+)(<\/div>)/g, '$1<b>$2</b>$3');

Changing how it matches the first div keeps the full match on the div tags, but makes sure it matches the minimum possible before the closing > of the first div tag rather than the maximum possible.

With your regex, you would not get what you wanted with this input string:

el = '<div style="color:red">123</div><div style="color:red">456</div>';

The problem with using something like:

el.replace(/\d+/, '<b>$&</b>')

is that doesn't work properly with things like this:

el = '<div style="margin-left: 10px">123</div>'

because it picks up the numbers inside the div tag.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • *"it matches the minimum possible before the closing >"* that may not work as you think. In `
    x
    123
    ` `$1` would capture `
    x
    `, as in OPs original expression.
    – Qtax Apr 01 '12 at 10:27
  • @Qtax - I've modified my regex to make it more foolproof in that regard. – jfriend00 Apr 01 '12 at 10:36