PHP regular expression - filter number only - php

I know this might sound as really dummy question, but I'm trying to ensure that the provided string is of a number / decimal format to use it later on with PHP's number_format() function.
How would I do it - say someone is typing 15:00 into the text field - what regular expression and php function should I use to remove the colon from it and make it only return the valid characters.
preg_match() returns array - so I can't pass the result to number_format() unless I implode() it or something like this.
Your help would be very much appreciated.

Using is_numeric or intval is likely the best way to validate a number here, but to answer your question you could try using preg_replace instead. This example removes all non-numeric characters:
$output = preg_replace( '/[^0-9]/', '', $string );

To remove anything that is not a number:
$output = preg_replace('/[^0-9]/', '', $input);
Explanation:
[0-9] matches any number between 0 and 9 inclusively.
^ negates a [] pattern.
So, [^0-9] matches anything that is not a number, and since we're using preg_replace, they will be replaced by nothing '' (second argument of preg_replace).

This is the right answer
preg_match("/^[0-9]+$/", $yourstr);
This function return TRUE(1) if it matches or FALSE(0) if it doesn't
Quick Explanation :
'^' : means that it should begin with the following ( in our case is a range of digital numbers [0-9] )
( to avoid cases like ("abdjdf125") )
'+' : means there should be at least one digit
'$' : means after our pattern the string should end
( to avoid cases like ("125abdjdf") )

You can try that one:
$string = preg_replace('/[^0-9]/', '', $string);
Cheers.

Another way to get only the numbers in a regex string is as shown below:
$output = preg_replace("/\D+/", "", $input);

use built in php function is_numeric to check if the value is numeric.

You could do something like this if you want only whole numbers.
function make_whole($v){
$v = floor($v);
if(is_numeric($v)){
echo (int)$v;
// if you want only positive whole numbers
//echo (int)$v = abs($v);
}
}

Related

How can remove the numberic suffix in php?

For example, if I want to get rid of the repeating numeric suffix from the end of an expression like this:
some_text_here_1
Or like this:
some_text_here_1_5
and I want finally receive something like this:
some_text_here
What's the best and flexible solution?
$newString = preg_replace("/_?\d+$/","",$oldString);
It is using regex to match an optional underscore (_?) followed by one or more digits (\d+), but only if they are the last characters in the string ($) and replacing them with the empty string.
To capture unlimited _ numbers, just wrap the whole regex (except the $) in a capture group and put a + after it:
$newString = preg_replace("/(_?\d+)+$/","",$oldString);
If you only want to remove a numberic suffix if it is after an underscore (e.g. you want some_text_here14 to not be changed, but some_text_here_14 to be changed), then it should be:
$newString = preg_replace("/(_\d+)+$/","",$oldString);
Updated to fix more than one suffix
Strrpos is far better than regex on such a simple string problem.
$str = "some_text_here_13_15";
While(is_numeric(substr($str, strrpos($str, "_")+1))){
$str = substr($str,0 , strrpos($str, "_"));
}
Echo $str;
Strrpos finds the last "_" in str and if it's numeric remove it.
https://3v4l.org/OTdb9
Just to give you an idea of what I mean with regex not being a good solution on this here is the performance.
Regex:
https://3v4l.org/Tu8o2/perf#output
0.027 seconds for 100 runs.
My code with added numeric check:
https://3v4l.org/dkAqA/perf#output
0.003 seconds for 100 runs.
This new code performs even better than before oddly enough, regex is very slow. Trust me on that
You be the judge on what is best.
First you'll want to do a preg_replace() in order to remove all digits by using the regex /\d+/. Then you'll also want to trim any underscores from the right using rtrim(), providing _ as the second parameter.
I've combined the two in the following example:
$string = "some_text_here_1";
echo rtrim(preg_replace('/\d+/', '', $string), '_'); // some_text_here
I've also created an example of this at 3v4l here.
Hope this helps! :)
$reg = '#_\d+$#';
$replace = '';
echo preg_replace($reg, $replace, $string);
This would do
abc_def_ghi_123 > abc_def_ghi
abc_def_1 > abc_def
abc_def_ghi > abc_def_ghi
abd_def_ > abc_def_
abc_123_def > abd_123_def
in case of abd_def_123_345 > abc_def
one could change the line
$reg = '#(?:_\d+)+$#';

preg_replace only first number in string

First of all: I'm very bad with regular expressions, the ones I already have here I found on the net.
I want to increment the first number in a string, e.g. $teststring = "abcd1234efgh56";
I have already found the following:
preg_replace( "|(\d+)|e", "$1+1", $teststring);
will result in abcd1235efgh57
preg_replace( "|(\d+)(?!.*\d)|e", "$1+1", $teststring);
will result in abcd1234efgh57
but how do I increment ONLY the first number (1234 in the example) while leaving the rest of the string as is?
Thank you very much in advance
check out the docs: php.net manual on preg_replace
use the fourth parameter to limit the number of replaces
You could use:
preg_replace('/([^0-9]*)(\d+)(.*)/e', '"$1" . ($2+2) . "$3"' , $str, 1);
This would match all non-numeric characters (if any) before the first number as $1, the first number as $2, and all following characters (if any) as $3.
It then outputs the string with 2 added to the first number (you can change $2+2 to $2+NUMBER).
The final parameter 1 in the function is limiting the repeats to 1 time only...
The optional fourth parameter of preg_replace is limit :
preg_replace($search , $replace, $subject, $limit)
You can put 1 for your case..
it will give you
$teststring = 'abcd1235efgh56'
Try
preg_replace('/^([^0-9]+)?([0-9]+)([^0-9]+)?/', "$2+1", $teststring);

Get integer value from malformed query string

I'm looking for an way to parse a substring using PHP, and have come across preg_match however I can't seem to work out the rule that I need.
I am parsing a web page and need to grab a numeric value from the string, the string is like this
producturl.php?id=736375493?=tm
I need to be able to obtain this part of the string:
736375493
$matches = array();
preg_match('/id=([0-9]+)\?/', $url, $matches);
This is safe for if the format changes. slandau's answer won't work if you ever have any other numbers in the URL.
php.net/preg-match
<?php
$string = "producturl.php?id=736375493?=tm";
preg_match('~id=(\d+)~', $string, $m );
var_dump($m[1]); // $m[1] is your string
?>
$string = "producturl.php?id=736375493?=tm";
$number = preg_replace("/[^0-9]/", '', $string);
Unfortunately, you have a malformed url query string, so a regex technique is most appropriate. See what I mean.
There is no need for capture groups. Just match id= then forget those characters with \K, then isolate the following one or more digital characters.
Code (Demo)
$str = 'producturl.php?id=736375493?=tm';
echo preg_match('~id=\K\d+~', $str, $out) ? $out[0] : 'no match';
Output:
736375493
For completeness, there 8s another way to scan the formatted string and explicitly return an int-typed value. (Demo)
var_dump(
sscanf($str, '%*[^?]?id=%d')[0]
);
The %*[^?] means: greedily match one or more non-question mark characters, but do not capture the substring. The remainder of the format parameter matches the literal sequence ?id=, then greedily captures one or more numbers. The returned value will be cast as an integer because of the %d placeholder.

Split alphanumeric string between leading digits and trailing letters

I have a string like:
$Order_num = "0982asdlkj";
How can I split that into the 2 variables, with the number as one element and then another variable with the letter element?
The number element can be any length from 1 to 4 say and the letter element fills the rest to make every order_num 10 characters long in total.
I have found the php explode function...but don't know how to make it in my case because the number of numbers is between 1 and 4 and the letters are random after that, so no way to split at a particular letter.
You can use preg_split using lookahead and lookbehind:
print_r(preg_split('#(?<=\d)(?=[a-z])#i', "0982asdlkj"));
prints
Array
(
[0] => 0982
[1] => asdlkj
)
This only works if the letter part really only contains letters and no digits.
Update:
Just to clarify what is going on here:
The regular expressions looks at every position and if a digit is before that position ((?<=\d)) and a letter after it ((?=[a-z])), then it matches and the string gets split at this position. The whole thing is case-insensitive (i).
Use preg_match() with a regular expression of (\d+)([a-zA-Z]+). If you want to limit the number of digits to 1-4 and letters to 6-9, change it to (\d+{1,4})([a-zA-Z]{6,9}).
preg_match("/(\\d+)([a-zA-Z]+)/", "0982asdlkj", $matches);
print("Integer component: " . $matches[1] . "\n");
print("Letter component: " . $matches[2] . "\n");
Outputs:
Integer component: 0982
Letter component: asdlkj
http://ideone.com/SKtKs
You can also do it using preg_split by splitting your input at the point which between the digits and the letters:
list($num,$alpha) = preg_split('/(?<=\d)(?=[a-z]+)/i',$Order_num);
You can use a regex for that.
preg_match('/(\d{1,4})([a-z]+)/i', $str, $matches);
array_shift($matches);
list($num, $alpha) = $matches;
Check this out
<?php
$Order_num = "0982asdlkj";
$split=split("[0-9]",$Order_num);
$alpha=$split[(sizeof($split))-1];
$number=explode($alpha, $Order_num);
echo "Alpha -".$alpha."<br>";
echo "Number-".$number[0];
?>
with regards
wazzy
My preferred approach would be sscanf() because it is concise, doesn't need regex, offers the ability to cast the numeric segment as integer type, and doesn't generate needless fullstring matches like preg_match(). %s does rely, though, on the fact that there will be no whitespaces in the letters segment of the string.
Demo
$Order_num = "0982asdlkj";
var_export (
sscanf($Order_num, '%d%s')
);
This can also be set up to declare individual variables.
sscanf($Order_num, '%d%s', $numbers, $letters)
If wanting to use a preg_ function, preg_split() is most appropriate, but I wouldn't use expensive lookarounds. Match the digits, then forget them (with \K). This will split the string without consuming any characters. Demo
var_export (
preg_split('/\d+\K/', $Order_num)
);
To assign variables, use "symmetric array destructuring".
[$numbers, $letters] = preg_split('/\d+\K/', $Order_num);
Beyond these single function approaches, there will be MANY two function approaches like:
$numbers = rtrim($Order_num, 'a..z');
$letters = ltrim($Order_num, '0..9');
But I wouldn't use them in a professional script because they lack elegance.

Using preg_split on alpha-numeric string in PHP

Consider the string 12345aaa. I want to use preg_split() on it so only the numeric part of it will be returned (i.e. 12345). How would I write the regex for it ?
preg_split is not the function you want, you want preg_match as you don't want to split a string into parts, but to retrieve part of it. As I don't know more details, I can only provide a rough example of how to do it.
$reg = null;
//match the first set of 1 or more numbers
if ( preg_match('/\d+/', $str, $reg) ){
$num = $reg[0];
}

Categories