2

I have a string in PHP where I want to extract only integer and decimal numbers, this is an example:

<?php 

$string = 'María vive en un pueblo de 25 957 habitantes y cobra 1859 euros al mes. OJO: no sé si os habéis fijado, pero los números del último ejemplo 
no llevan un punto o una coma separando los millares (25.957 o 1.859). Sé que resulta extraño, pero la nueva normativa de la R.A.E. 
dice que los números de cuatro cifras NO llevarán separación (1859) y los números de cinco cifras o más NO llevarán ni puntos ni comas, 
sino una separación (25 957 o 1 343 392). El 94% de los niños ha traído los deberes hechos. He pagado $50,95 dólares.';

?>

In this case I try to get numbers using this line:

$numbers = preg_replace('/[^0-9\.,]/', ' ', $string);

But the problem is the result is:

25 957 1859 . , 25.957 1.859 . , . . . 1859 , 25 957 1 343 392 . 94 . 50,95 .   

And I want to get this result:

25 957 1859 25.957 1.859 1859 25 957 1 343 392 94 50,95

How can I fix it?

I'd like your help.

1
  • If it's possible I want to consider those details Commented Aug 16, 2019 at 23:21

3 Answers 3

4

You're using a . for thousands and a , for decimals, and it looks like your text is intended for humans so there will always be a number immediately before a . and ,.

So what you want is 1 or more numbers, followed by 0 or more thousand-groups (a . followed by 3 more numbers), optionally followed by exactly one , and one or more numbers.

One or more numbers: [0-9]+
0 or more thousand-groups: (\.[0-9]{3})*
Optionally a `,` and one or more numbers: (,[0-9]+)?

Combined: [0-9]+(\.[0-9]{3})*(,[0-9]+)?

$string = 'María vive en un pueblo de 25 957 habitantes y cobra 1859 euros al mes. OJO: no sé si os habéis fijado, pero los números del último ejemplo 
no llevan un punto o una coma separando los millares (25.957 o 1.859). Sé que resulta extraño, pero la nueva normativa de la R.A.E. 
dice que los números de cuatro cifras NO llevarán separación (1859) y los números de cinco cifras o más NO llevarán ni puntos ni comas, 
sino una separación (25 957 o 1 343 392). El 94% de los niños ha traído los deberes hechos. He pagado $50,95 dólares.';

$matches = [];
preg_match_all('/[0-9]+(\.[0-9]{3})*(,[0-9]+)?/', $string, $matches);

print_r($matches[0]);

/*
Array
(
    [0] => 25
    [1] => 957
    [2] => 1859
    [3] => 25.957
    [4] => 1.859
    [5] => 1859
    [6] => 25
    [7] => 957
    [8] => 1
    [9] => 343
    [10] => 392
    [11] => 94
    [12] => 50,95
)
*/
Sign up to request clarification or add additional context in comments.

2 Comments

@user3783243 yes, my expression is only using a , as a decimal separator. It is using a . for a thousand separator. The given text does not have any numbers with a , as a thousand separator (although it does have numbers with a space as a thousand separator, but that wasn't part of what OP wanted).
Thanks for your answer, this works great, I just needed to add an implode() function, thanks again!
2

Probably not the most elegant way to do it but you could use two preg_replace functions based on your first REGEX and remove the decimals without any numbers wrapped around them like so :

$numbers = preg_replace('/[^0-9\.,]+/', ' ', $string);
$decimals = preg_replace('/([^0-9][\.,])/', '', $numbers);
var_dump($decimals); // string(56) " 25 957 1859 25.957 1.859 1859 25 957 1 343 392 94 50,95"

Live example here : https://3v4l.org/9aUCt

Comments

1

Use this regular expression:

(\d*\.)?\d+

NOTE
This exp will match 25 957 like 2 matches (for the space between numbers).

2 Comments

what you mean? I did not understand
according to the first post it is exactly what he wanted to do

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.