Domanda

I need to match the last integer in a string and capture possible elements before and after the last integer, assuming that the string can be composed of a single integer or a combination of text and/or integers. Let say that $str can be:

  • '123' -> '' - 123 - ''
  • 'abc 123' -> 'abc ' - 123
  • 'abc 123 def' -> 'abc ' - 123 - ' def'
  • 'abc 123 def 456' -> 'abc 123 def ' - 456
  • etc.

I expected that the following piece of code in php would do the job:

$str = 'abc 123 def 456 ghi';
preg_match('/(.*)(\d+)(\D*)$/', $str, $matches);
echo 'Matches = ' . implode(' : ', $matches);

But the (\d+) is picking up only one digit:

 Matches = abc 123 def 456 ghi : abc 123 def 45 : 6 :  ghi

While I was expecting:

 Matches = abc 123 def 456 ghi : abc 123 def  : 456 :  ghi

I get the same behavior in Javascript. The (.*) is that greedy to impinge on (\d+)?

Thanks in advance!

È stato utile?

Soluzione

You can completely avoid the .* as the "\D*$" at the end of the pattern would make sure it is the last number.

It is also recommended that you don't add unnecessary parenthesis and only get what you really need. That is to say that you could do the following to only get the last number:

preg_match('/(\d+)\D*$/', $str, $matches);

If you do need the match on the other portions of the string, though, and the number you are looking for will be its own word you could add to that regexp the \b parameter before the (\d+) so that the (.*) won't greedily consume part of your number. i.e.:

preg_match('/(.*)\b(\d+)(\D*)$/', $str, $matches);

Altri suggerimenti

Why not /(\d+)\D*$/? That way, the only capturing group is the integer.

Btw, when I'm working with regexes, i usually use http://gskinner.com/RegExr/

In Javascript:

$str = 'abc 123 def 456';
$matches = $str.match(/\d+/g);
$lastInt = $matches[$matches.length-1];

In PHP

$str = 'abc 123 def 456';
preg_match_all('/(\d+)/', $str, $matches);
$lastInt = end($matches);
echo 'Last integer = ' . $lastInt;

This should do it for ya...

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

If you want to cach the last integer, you should use the $ at the end of the regular expression.

Try with /(\d+)$/ in both languages.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top