korbes
korbes

Reputation: 1363

Regular expression to match last number in a string

I need to extract the last number that is inside a string. I'm trying to do this with regex and negative lookaheads, but it's not working. This is the regex that I have:

\d+(?!\d+)

And these are some strings, just to give you an idea, and what the regex should match:

ARRAY[123]         matches 123 
ARRAY[123].ITEM[4] matches 4
B:1000             matches 1000
B:1000.10          matches 10

And so on. The regex matches the numbers, but all of them. I don't get why the negative lookahead is not working. Any one care to explain?

Upvotes: 56

Views: 107383

Answers (4)

Elysiumplain
Elysiumplain

Reputation: 721

I still had issues with managing the capture groups (for example, if using Inline Modifiers (?imsxXU)).

This worked for my purposes -

.*(?:\D|^)\d*(\D)

Upvotes: 0

sawa
sawa

Reputation: 168259

I took it this way: you need to make sure the match is close enough to the end of the string; close enough in the sense that only non-digits may intervene. What I suggest is the following:

/(\d+)\D*\z/
  1. \z at the end means that that is the end of the string.
  2. \D* before that means that an arbitrary number of non-digits can intervene between the match and the end of the string.
  3. (\d+) is the matching part. It is in parenthesis so that you can pick it up, as was pointed out by Cameron.

Upvotes: 11

codaddict
codaddict

Reputation: 455430

Your regex \d+(?!\d+) says

match any number if it is not immediately followed by a number.

which is incorrect. A number is last if it is not followed (following it anywhere, not just immediately) by any other number.

When translated to regex we have:

(\d+)(?!.*\d)

Rubular Link

Upvotes: 137

Cameron
Cameron

Reputation: 98886

You can use

.*(?:\D|^)(\d+)

to get the last number; this is because the matcher will gobble up all the characters with .*, then backtrack to the first non-digit character or the start of the string, then match the final group of digits.

Your negative lookahead isn't working because on the string "1 3", for example, the 1 is matched by the \d+, then the space matches the negative lookahead (since it's not a sequence of one or more digits). The 3 is never even looked at.

Note that your example regex doesn't have any groups in it, so I'm not sure how you were extracting the number.

Upvotes: 11

Related Questions