15

If I have an HTML string such as:

<div><p>£20<span class="abc" /><span class="def">56</span></p></div>

And I want the text:

20<span class="abc" /><span class="def">56

How do I define a regular expression to match the target sections multiple times. So far I have:

str.match(/\d*<[^>]*>\d*/)

But this will only return the first number section 20<span class="abc" />

I need this to be flexible to match multiple tag / numeric sections while trimming anything leading or trailing the first / last digit in the string.

vhs
  • 9,316
  • 3
  • 66
  • 70
gbro3n
  • 6,729
  • 9
  • 59
  • 100

3 Answers3

9

Adding /g isn't enough if you wish to match multiple occurrences of a substring. If that's the case, reluctant quantifiers may be used as described herein.

Given the string:

<div><p>£20<span class="abc" /><span class="def">56</span></p></div>

You will arrive at the text you wanted using:

\d+.*>\d+

But given the same string repeated two times:

<div><p>£20<span class="abc" /><span class="def">56</span></p></div><div><p>£20<span class="abc" /><span class="def">56</span></p></div>

You will not find the target selection multiple times. You'll only find it once due to the greedy nature of .*. To make .* non-greedy, or reluctant, simply add a ? after the * and you will arrive at:

\d+.*?>\d+

Which will find both occurrences of the substring you asked for as shown here.

vhs
  • 9,316
  • 3
  • 66
  • 70
7

To match multiple times use to need use the global option

str.match(/your_expression_here/g)
                                ^
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
James Kyburz
  • 13,775
  • 1
  • 32
  • 33
1

Just allow the group to be repeated: (?:...)+ means "Match ... 1 or more times:

str.match(/\d+(?:<[^>]*>)+\d+/)

As per Alan Moore's suggestion, I've also changed the \d* into \d+, making the numbers required instead of optional.

Tim Pietzcker
  • 328,213
  • 58
  • 503
  • 561