Extraire des nombres d'une chaîne

332

Je veux extraire les chiffres d'une chaîne qui contient des chiffres et des lettres comme:

"In My Cart : 11 items"

Je veux ici obtenir le numéro 11ou tout autre numéro.

Bizboss
la source
Utilisez ce $ string = "Dans mon panier: 11 articles"; $ number = preg_replace ("/ [^ 0-9] {1,4} /", '', $ string); // retour 11
Shorabh

Réponses:

363
$str = 'In My Cart : 11 12 items';
preg_match_all('!\d+!', $str, $matches);
print_r($matches);
Gaurav
la source
2
Comment puis-je obtenir mon numéro dans une variable simple et non dans Array?
Bizboss
34
$ var = implode ('', $ correspond à [0]);
Gaurav
2
@Bizboss Dans la même veine, essayez $newstr = preg_replace('!\d+!', '', $str);. Il supprimera tous les chiffres de votre chaîne. Exemple: $str = 'In My Cart : 11 12 items';affichera In My Cart : items.
Aether
77
ce n'est pas un moyen respectueux des ressources. utiliser preg_replace("/[^0-9]/","",$string);oufilter_var($str, FILTER_SANITIZE_NUMBER_INT);
eapo
6
@eapo filter_var($str, FILTER_SANITIZE_NUMBER_INT);extrait les chiffres, signe plus et moins . L'expression régulière n'a extrait que des chiffres!
PATROMO
537

Si vous voulez simplement filtrer tout autre que les chiffres, le plus simple est d'utiliser filter_var :

$str = 'In My Cart : 11 items';
$int = (int) filter_var($str, FILTER_SANITIZE_NUMBER_INT);
Daniel Bøndergaard
la source
56
Un tiret avant un nombre sera traité comme un moins.
Elnur Abdurrakhimov
43
Pas seulement avant le numéro. Tout +/- ne sera pas tronqué. Si vous avez, xxx-yyy-24vous obtiendrez --24. Vous pouvez utiliser str_repleace(array('+','-'), '', $result)pour supprimer les deux signes.
imclickingmaniac
4
@imclickingmaniac vous pouvez simplement faire à la max(0,filter_var($str, FILTER_SANITIZE_NUMBER_INT))place en utilisant des tableaux et des remplacements de chaînes.
Eduard
2
utiliser max () renvoie également le signe moins dans les chaînes, espérons que strreplace () est l'option ici. Merci pour les conseils.
Shiva Avula
26
abs((int) filter_var($str, FILTER_SANITIZE_NUMBER_INT));
MECU
300
preg_replace('/[^0-9]/', '', $string);

Cela devrait faire mieux! ...

Mahipalsinh Ravalji
la source
10
J'aime cela parce qu'il renvoie une chaîne, pas un tableau comme le font les exemples avec preg_match_all, et je l'aime parce que je veux juste des nombres, pas un signe plus ou un tiret, comme le fait l'exemple filter_var.
Darrell Duane
43
Attention à cette méthode: quelque chose comme 'In My Car_Price: 500.00imprimera:50000
ErickBest
16
@ErickBest C'est une bonne chose, étant donné que la question était extract the numbers from a string- un point décimal n'est pas un nombre!
rybo111
1
Ceci est un nitpick mais vous voulez probablement utiliser des guillemets simples 'et non des guillemets doubles ".
CommandZ
16
preg_replace ('/ [^ 0-9.] /', '', 'abc1.22'); // renvoie décimal 1,22
zzapper
84

En utilisant preg_replace:

$str = '(111) 111-1111';
$str = preg_replace('/\D/', '', $str);
echo $str;

Sortie: 1111111111

Akash Deep
la source
4
Cela fonctionne très bien. Il convertit la +387 (61) 634-783chaîne en 38761634783directement. Vous n'avez pas à vous occuper de tableaux comme la réponse de Gaurav.
beytarovski
1
Certainement la meilleure réponse. sandbox.onlinephpfunctions.com/code/…
Steffan
Je recommande le +quantificateur pour correspondre à des correspondances plus longues / moins de remplacements.
mickmackusa
21

Pour les nombres flottants,

preg_match_all('!\d+\.?\d+!', $string ,$match);

Merci d'avoir signalé l'erreur. @mickmackusa

Yash
la source
C'est en fait mal :) Ça devrait être'!\d*.?\d+!'
Yash
Je préférerais utiliser ?comme quantificateur du point littéral. Je ne m'attendrais pas à ce qu'une valeur flottante contienne plusieurs symboles de virgule décimale. Ironiquement, le modèle commenté de Yash est faux . Le point a besoin d'une barre oblique devant pour le rendre littéral.
mickmackusa
11

Je ne possède pas le crédit pour cela, mais je dois juste le partager. Cette expression régulière obtiendra des nombres à partir d'une chaîne, y compris les points / lieux décimaux, ainsi que les virgules:

/((?:[0-9]+,)*[0-9]+(?:\.[0-9]+)?)/

Cité à partir d'ici:
php - regex - comment extraire un nombre avec décimal (point et virgule) d'une chaîne (par exemple 1,120.01)?

mroncetwice
la source
Cela ne valide pas la chaîne d'une virgule entre des ensembles de trois nombres entiers. ... le problème de copier-coller le modèle de quelqu'un d'autre et de ne pas le comprendre / le tester.
mickmackusa
9

Vous pouvez utiliser preg_match :

$s = "In My Cart : 11 items";
preg_match("|\d+|", $s, $m);
var_dump($m);
Dmitri Gudkov
la source
echo '<p>'.$m[0].'</p>';
Pathros
9

Utilisation de preg_replace

$str = 'In My Cart : 11 12 items';
$str = preg_replace('/\D/', '', $str);
echo $str;
Hariadi
la source
Je recommande le +quantificateur pour correspondre à des correspondances plus longues / moins de remplacements.
mickmackusa
6

Vous pouvez utiliser la fonction suivante:

function extract_numbers($string)
{
   preg_match_all('/([\d]+)/', $string, $match);

   return $match[0];
}
Jasmeen
la source
Il n'y a aucun avantage à écrire à l' \dintérieur d'une classe de caractères. Puisque vous accédez à la correspondance de chaîne complète, il est inutile d'écrire un groupe de capture dans le modèle.
mickmackusa le
4
preg_match_all('!\d+!', $some_string, $matches);
$string_of_numbers = implode(' ', $matches[0]);

Le premier argument implosé dans ce cas spécifique dit "séparez chaque élément dans les correspondances [0] avec un seul espace". Implode ne mettra pas d'espace (ou quel que soit votre premier argument) avant le premier nombre ou après le dernier nombre.

Quelque chose d'autre à noter est $ matches [0] est l'endroit où le tableau des correspondances (qui correspondent à cette expression régulière) trouvé est stocké.

Pour plus de précisions sur les autres index du tableau, voir: http://php.net/manual/en/function.preg-match-all.php

Bradley Kovacs
la source
4

essayez ceci, utilisez preg_replace

$string = "Hello! 123 test this? 456. done? 100%";
$int = intval(preg_replace('/[^0-9]+/', '', $string), 10);
echo $int;

DEMO

Dave
la source
[^0-9]est plus simplement écrit comme \D.
mickmackusa le
3
$value = '25%';

Ou

$value = '25.025$';

Ou

$value = 'I am numeric 25';
$onlyNumeric = filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);

Cela renverra uniquement la valeur numérique

Rakesh
la source
3

Suivez cette étape, il convertira la chaîne en nombre

$value = '$0025.123';
$onlyNumeric = filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
settype($onlyNumeric,"float");

$result=($onlyNumeric+100);
echo $result;

Une autre façon de procéder:

$res = preg_replace("/[^0-9.]/", "", "$15645623.095605659");
jewelhuq
la source
0

autre manière (chaîne unicode même):

$res = array();
$str = 'test 1234 555 2.7 string ..... 2.2 3.3';
$str = preg_replace("/[^0-9\.]/", " ", $str);
$str = trim(preg_replace('/\s+/u', ' ', $str));
$arr = explode(' ', $str);
for ($i = 0; $i < count($arr); $i++) {
    if (is_numeric($arr[$i])) {
        $res[] = $arr[$i];
    }
}
print_r($res); //Array ( [0] => 1234 [1] => 555 [2] => 2.7 [3] => 2.2 [4] => 3.3 ) 
Mehrdad
la source
0

Ce script crée d'abord un fichier, écrit des nombres sur une ligne et passe à une ligne suivante s'il obtient un caractère autre que le nombre. Enfin, encore une fois, il trie les numéros dans une liste.

string1 = "hello my name 12 is after 198765436281094and14 and 124de"
f= open("created_file.txt","w+")
for a in string1:
    if a in ['1','2','3','4','5','6','7','8','9','0']:
        f.write(a)
    else:
        f.write("\n" +a+ "\n")
f.close()


#desired_numbers=[x for x in open("created_file.txt")]

#print(desired_numbers)

k=open("created_file.txt","r")
desired_numbers=[]
for x in k:
    l=x.rstrip()
    print(len(l))
    if len(l)==15:
        desired_numbers.append(l)


#desired_numbers=[x for x in k if len(x)==16]
print(desired_numbers)
Abhishek Poudel
la source
-1

Selon votre cas d'utilisation, cela peut également être une option:

$str = 'In My Cart : 11 items';
$num = '';

for ($i = 0; $i < strlen($str); $i++) {

    if (is_numeric($str[$i])) {
        $num .= $str[$i];
    }
}

echo $num; // 11

Bien que je convienne d'une expression régulière ou filter_var()serait plus utile dans le cas indiqué.

Kasimir
la source
-1

pour utf8 str:

function unicodeStrDigits($str) {
    $arr = array();
    $sub = '';
    for ($i = 0; $i < strlen($str); $i++) { 
        if (is_numeric($str[$i])) {
            $sub .= $str[$i];
            continue;
        } else {
            if ($sub) {
                array_push($arr, $sub);
                $sub = '';
            }
        }
    }

    if ($sub) {
        array_push($arr, $sub); 
    }

    return $arr;
}
Mehrdad
la source
-1

Si vous ne savez pas de quel format est le numéro? int ou flottant, alors utilisez ceci:

$string = '$125.22';

$string2 = '$125';

preg_match_all('/(\d+.?\d+)/',$string,$matches); // $matches[1] = 125.22

preg_match_all('/(\d+.?\d+)/',$string2,$matches); // $matches[1] = 125
Sajjad Hossain Sagor
la source
-1

Cette fonction gérera également les nombres flottants

$str = "Doughnuts, 4; doughnuts holes, 0.08; glue, 3.4";
$str = preg_replace('/[^0-9\.]/','-', $str);
$str = preg_replace('/(\-+)(\.\.+)/','-', $str);
$str = trim($str, '-');
$arr = explode('-', $str);
Khaldoon Masud
la source
Il n'est absolument pas nécessaire d'introduire des tirets dans ce processus. Cette réponse manque également d'une explication sur la façon dont cela fonctionne et pourquoi vous pensez que c'est une bonne idée.
mickmackusa