0x6563
0x6563

Reputation: 1086

preg_match return longest match

I am trying to return a series of numbers between 5 and 9 digits long. I want to be able to get the longest possible match, but unfortunately preg_match just returns the last 5 characters that match.

$string = "foo 123456";
if (preg_match("/.*(\d{5,9}).*/", $string, $match)) {
    print_r($match);
};

will yield results

Array
(
[0] => foo 123456
[1] => 23456
)

Upvotes: 0

Views: 1252

Answers (2)

nhahtdh
nhahtdh

Reputation: 56809

Since you want only the numbers, you can just remove the .* from the pattern:

$string = "foo 123456";
if (preg_match("/\d{5,9}/", $string, $match)) {
    print_r($match);
};

Note that if the input string is "123456789012", then the code will return 123456789 (which is a substring of a longer sequence of digits).

If you don't want to match a sequence of number that is part of a longer sequence of number, then you must add some look-around:

preg_match("/(?<!\d)\d{5,9}(?!\d)/", $string, $match)

DEMO

(?<!\d) checks that there is no digit in front of the sequence of digits. (?<!pattern) is zero-width negative look-behind, which means that without consuming text, it checks that looking behind from the current position, there is no match for the pattern.

(?!\d) checks that there is no digit after the sequence of digits. (?!pattern) is zero-width negative look-ahead, which means that without consuming text, it checks that looking ahead from the current position, there is no match for the pattern.

Upvotes: 1

Fabien Sa
Fabien Sa

Reputation: 9480

Use a "local" non-greedy like .*?

<?php
$string = "foo 123456 bar"; // work with "foo 123456", "123456", etc.
if (preg_match("/.*?(\d{5,9}).*/", $string, $match)) {
    print_r($match);
};

result :

Array
(
    [0] => foo 123456 bar
    [1] => 123456
)

For more informations : http://en.wikipedia.org/wiki/Regular_expression#Lazy_quantification

Upvotes: 1

Related Questions