mk_89
mk_89

Reputation: 2742

Capturing numbers that are larger than 1 decimal place

I'm having problems with a regex which seems to be matching 1 decimal point numbers such as 1.20, 2.50, but not numbers such as 20.50 or 906.10

Here is the regex

/(?:site(?:\\.com)?[\\s\\w\\d^]*)(\\d+\\.\\d{2})/i

I've also tried the following regex, but it seems to miss smaller numbers

/(?:site(?:\\.com)?[\\s\\w\\d^]*)(\\d+\\d+\\d+\\.\\d{2})/i    

Replacing d with [0-9] seems to not work

String

Debit card payment to site.com
Germany
on 01 May 1.30
Debit card payment to  site Germany
on 01 May 4.63
 Debit card payment to site.Com
Germany
on 01 May 3.30
Debit card payment to Paypal *Xiao
Ref:- 23948 0000000000 32.98
Debit card payment to site.Com
Germany
on 20 May 17.49
Debit card refund from site.Com
Germany
on 21 May 429.29 

Any help would be appreciated thank you.

For reference:

$re = "/(?:site(?:\\.com)?[\\s\\w\\d^]*)(\\d+\\.\\d{2})/i"; 
$str = "Debit card payment to site.com
    Germany
    on 01 May 1.30
    Debit card payment to  site Germany
    on 01 May 4.63
     Debit card payment to site.Com
    Germany
    on 01 May 3.30
    Debit card payment to Paypal *Xiao
    Ref:- 23948 0000000000 32.98
    Debit card payment to site.Com
    Germany
    on 20 May 17.49
    Debit card refund from site.Com
    Germany
    on 21 May 429.29 ";
preg_match_all($re, $str, $matches);
print_r($matches)

Upvotes: 3

Views: 53

Answers (5)

Fabian Schmengler
Fabian Schmengler

Reputation: 24551

You only have to change one character:

From

$re = "/(?:site(?:\\.com)?[\\s\\w\\d^]*)(\\d+\\.\\d{2})/i";

To

$re = "/(?:site(?:\\.com)?[\\s\\w\\d^]*?)(\\d+\\.\\d{2})/i"; 
                                       ^

*? stands for non-greedy matching, i.e. the expression does not try to match as much as possible but only as much as necessary. This way it doesn't eat all the numbers.

Upvotes: 0

Toto
Toto

Reputation: 91385

Just add a word boundary \b in your regex:

$re = "/(?:site(?:\\.com)?[\\s\\w\\d^]*)\b(\\d+\\.\\d{2})/i"; 
//                             here  ___^^
$str = "Debit card payment to site.com
    Germany
    on 01 May 1.30
    Debit card payment to  site Germany
    on 01 May 4.63
     Debit card payment to site.Com
    Germany
    on 01 May 3.30
    Debit card payment to Paypal *Xiao
    Ref:- 23948 0000000000 32.98
    Debit card payment to site.Com
    Germany
    on 20 May 17.49
    Debit card refund from site.Com
    Germany
    on 21 May 429.29 ";
preg_match_all($re, $str, $matches);
print_r($matches)

Output:

Array
(
    [0] => Array
        (
            [0] => site.com
    Germany
    on 01 May 1.30
            [1] => site Germany
    on 01 May 4.63
            [2] => site.Com
    Germany
    on 01 May 3.30
            [3] => site.Com
    Germany
    on 20 May 17.49
            [4] => site.Com
    Germany
    on 21 May 429.29
        )

    [1] => Array
        (
            [0] => 1.30
            [1] => 4.63
            [2] => 3.30
            [3] => 17.49
            [4] => 429.29
        )

)

Upvotes: 0

alpha bravo
alpha bravo

Reputation: 7948

or this pattern w/ isg options

site.*?\D\K(\d+\.\d{2})  

Demo
Explanation:

site            # "site"
.               # Any character except line break
*?              # (zero or more)(lazy)
\D              # <character that is not a digit>
\K              # <Reset start of match>
(               # Capturing Group (1)
  \d            # <digit 0-9>
  +             # (one or more)(greedy)
  \.            # "."
  \d            # <digit 0-9>
  {2}           # (repeated {2} times)
)               # End of Capturing Group (1)

Upvotes: 1

Andie2302
Andie2302

Reputation: 4887

To match a decimal number from 0.00 to 9.99 use:

\b\d\.\d{2}\b

Upvotes: 1

chris85
chris85

Reputation: 23892

How about?

$re = "~(site.*?\s+)(\d+\.\d+)~mis";

Upvotes: 0

Related Questions