159

I'm trying to remove everything from a string but just numbers (0-9).

I thought this would work..

echo preg_replace("[^0-9]","",'604-619-5135');

But it echos "604-619-5135". What am I missing???

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
jeffkee
  • 5,106
  • 12
  • 44
  • 76
  • [Why do the PHP preg_* functions require regexp delimiters?](https://stackoverflow.com/q/9550899/2943403) – mickmackusa Jan 18 '22 at 04:45
  • Your pattern works perfectly when the input string is changed to accommodate it. [`echo preg_replace("[^0-9]", "this", '0-9 is replaced');`](https://3v4l.org/WX7pO) outputs: `this is replaced` – mickmackusa Jan 18 '22 at 05:20

4 Answers4

331

Try this:

preg_replace('/[^0-9]/', '', '604-619-5135');

preg_replace uses PCREs which generally start and end with a /.

Wes Cossick
  • 2,923
  • 2
  • 20
  • 35
Chris Eberle
  • 47,994
  • 12
  • 82
  • 119
  • The inner/double quoting doesn't have anything to do with PCRE tho. Apparently (in the days before `(?flags)`) the people who designed/wrote the function/API thought it was a good idea to pass the regex flags with the double quoted `/flags` form instead of using an extra function parameter. – Qtax Jul 07 '11 at 00:28
  • 6
    @Qtax: good point, yeah I know that's where we get the word "grep" from ("g/re/p") – Chris Eberle Jul 07 '11 at 00:39
  • adding character at the las part seems doesnt remove the part – Jenuel Ganawed Oct 11 '21 at 07:54
  • 1
    Or just do it simple and use `/\D/` to get the number or `/\d/` to get the string. – Mr. Jo Dec 06 '21 at 13:42
142

This is for future developers, you can also try this. Simple too

echo preg_replace('/\D/', '', '604-619-5135');
Navneil Naicker
  • 3,586
  • 2
  • 21
  • 31
  • 6
    I have come back 2 the future and I can confirm they have still not found a better way. – Eoin Oct 12 '19 at 17:39
  • 3
    @Eoin to make this pattern "better" add a one-or-more quantifier (`+`) after the `D`. This allows the regex engine to make longer and therefore fewer replacements. Imagine standing in front of a carton of eggs. If I asked you to pick up the dozen eggs, would you do 12 squats or just 1? Though I like to work out, I'd squat once and pick up all of the eggs as a matter of directness. – mickmackusa Jan 18 '22 at 05:24
15

You would need to enclose the pattern in a delimiter - typically a slash (/) is used. Try this:

echo preg_replace("/[^0-9]/","",'604-619-5135');
SBerg413
  • 14,515
  • 6
  • 62
  • 88
  • 2
    [A delimiter can be any non-alphanumeric, non-backslash, non-whitespace character.](http://php.net/manual/en/regexp.reference.delimiters.php) – Mavelo Jan 17 '15 at 05:02
7

NOTE: if you are filtering strings containing - sign is not applicable to this answer because - stands for minus sign and is NOT filtered and removed. (like -2, -4 etc). If you still want to use it please remove - characters and then try.

(- + . e) characters are not stripped with this function

a much more practical way for those who do not want to use regex:

$data = filter_var($data, FILTER_SANITIZE_NUMBER_INT);

note: it works with phone numbers too.

Alp Altunel
  • 3,324
  • 1
  • 26
  • 27
  • 6
    `FILTER_SANITIZE_NUMBER_INT` leaves plus `+` and minus `-` signs, not only digits. – Qrzysio Aug 04 '20 at 19:45
  • yes I said it works with phone numbers like +905360000000 leaves out all other characters – Alp Altunel Aug 07 '20 at 08:38
  • This is e.g. a problem if you try to use it with Whatsapp as WA DOES NOT allow + signs! – Alexander Dobernig Feb 19 '21 at 21:52
  • This answer is completely ineffective for the question asked. Proof: https://3v4l.org/IMQeJ – mickmackusa Jan 18 '22 at 04:43
  • if you read manual page for this you can see that your proof contains - character which is allowed for int if you use -2 for example. so you cannot apply this. you can use $str = str_replace("-", "", $str); and apply this filter_var. – Alp Altunel May 26 '23 at 09:46