Related
Can we use comparison in a regex pattern? I want to check if a recent matched group is greater than a number. This is the pattern: size=(\d+) and I wanna see if (\d+)>200 then return true.
You can't do it with that same syntax, but what you're after is possible with a more complex expression such as:
Greater than 200:
([1-9]\d+|(?!200)[2-9])\d\d
Include 200:
([1-9]\d+|[2-9])\d\d
As you approach other (and larger) numbers, however, it will be unmanagable.
You would do best to match all numbers, then loop through the results to do the > 200 check, and remove ones that don't comply.
Note: The above regular expressions are just to show that matching numbers greater than 200 is possible in pure regex. It is not recommended however, and more complex/variable numbers will be unworkable.
OP mentioned in comments that they would like to match > 30*1024*1024, which is > 31457280
In the name of proving why regex is a pain, I have written the required pattern:
\b((3[1-9][4-9][5-9][7-9][2-9][8-9]\d+)|(3[1-9][4-9][5-9][7-9][3-9]\d{2,})|(3[1-9][4-9][5-9][8-9]\d{3,})|(3[1-9][4-9][6-9]\d{4,})|(3[1-9][5-9]\d{5,})|(3[2-9]\d{6,})|(?!31457280)(4\d{7,}))\b
(not very pretty!)
No, it's not possible, the purpose of the regular expressions is to match expresions not to program with it
This isn't a big issue for me (as far as I'm aware), it's more of something that's interested me. But what is the main difference, if any, of using is_numeric over preg_match (or vice versa) to validate user input values.
Example One:
<?php
$id = $_GET['id'];
if (!preg_match('/^[0-9]*$/', $id)) {
// Error
} else {
// Continue
}
?>
Example Two:
<?php
$id = $_GET['id'];
if (!is_numeric($id)) {
// Error
} else {
// Continue
}
?>
I assume both do exactly the same but is there any specific differences which could cause problems later somehow? Is there a "best way" or something I'm not seeing which makes them different.
is_numeric() tests whether a value is a number. It doesn't necessarily have to be an integer though - it could a decimal number or a number in scientific notation.
The preg_match() example you've given only checks that a value contains the digits zero to nine; any number of them, and in any sequence.
Note that the regular expression you've given also isn't a perfect integer checker, the way you've written it. It doesn't allow for negatives; it does allow for a zero-length string (ie with no digits at all, which presumably shouldn't be valid?), and it allows the number to have any number of leading zeros, which again may not be the intended.
[EDIT]
As per your comment, a better regular expression might look like this:
/^[1-9][0-9]*$/
This forces the first digit to only be between 1 and 9, so you can't have leading zeros. It also forces it to be at least one digit long, so solves the zero-length string issue.
You're not worried about negatives, so that's not an issue.
You might want to restrict the number of digits, because as things stand, it will allow strings that are too big to be stored as integers. To restrict this, you would change the star into a length restriction like so:
/^[1-9][0-9]{0,15}$/
This would allow the string to be between 1 and 16 digits long (ie the first digit plus 0-15 further digits). Feel free to adjust the numbers in the curly braces to suit your own needs. If you want a fixed length string, then you only need to specify one number in the braces.
According to http://www.php.net/manual/en/function.is-numeric.php, is_numeric alows something like "+0123.45e6" or "0xFF". I think this not what you expect.
preg_match can be slow, and you can have something like 0000 or 0051.
I prefer using ctype_digit (works only with strings, it's ok with $_GET).
<?php
$id = $_GET['id'];
if (ctype_digit($id)) {
echo 'ok';
} else {
echo 'nok';
}
?>
is_numeric() allows any form of number. so 1, 3.14159265, 2.71828e10 are all "numeric", while your regex boils down to the equivalent of is_int()
is_numeric would accept "-0.5e+12" as a valid ID.
Not exactly the same.
From the PHP docs of is_numeric:
'42' is numeric
'1337' is numeric
'1e4' is numeric
'not numeric' is NOT numeric
'Array' is NOT numeric
'9.1' is numeric
With your regex you only check for 'basic' numeric values.
Also is_numeric() should be faster.
is_numeric checks whether it is any sort of number, while your regex checks whether it is an integer, possibly with leading 0s. For an id, stored as an integer, it is quite likely that we will want to not have leading 0s. Following Spudley's answer, we can do:
/^[1-9][0-9]*$/
However, as Spudley notes, the resulting string may be too large to be stored as a 32-bit or 64-bit integer value. The maximum value of an signed 32-bit integer is 2,147,483,647 (10 digits), and the maximum value of an signed 64-bit integer is 9,223,372,036,854,775,807 (19 digits). However, many 10 and 19 digit integers are larger than the maximum 32-bit and 64-bit integers respectively. A simple regex-only solution would be:
/^[1-9][0-9]{0-8}$/
or
/^[1-9][0-9]{0-17}$/
respectively, but these "solutions" unhappily restrict each to 9 and 19 digit integers; hardly a satisfying result. A better solution might be something like:
$expr = '/^[1-9][0-9]*$/';
if (preg_match($expr, $id) && filter_var($id, FILTER_VALIDATE_INT)) {
echo 'ok';
} else {
echo 'nok';
}
is_numeric checks more:
Finds whether the given variable is numeric. Numeric strings consist
of optional sign, any number of digits, optional decimal part and
optional exponential part. Thus +0123.45e6 is a valid numeric value.
Hexadecimal notation (0xFF) is allowed too but only without sign,
decimal and exponential part.
You can use this code for number validation:
if (!preg_match("/^[0-9]+$/i", $phone)) {
$errorMSG = 'Invalid Number!';
$error = 1;
}
If you're only checking if it's a number, is_numeric() is much much better here. It's more readable and a bit quicker than regex.
The issue with your regex here is that it won't allow decimal values, so essentially you've just written is_int() in regex. Regular expressions should only be used when there is a non-standard data format in your input; PHP has plenty of built in validation functions, even an email validator without regex.
PHP's is_numeric function allows for floats as well as integers. At the same time, the is_int function is too strict if you want to validate form data (strings only). Therefore, you had usually best use regular expressions for this.
Strictly speaking, integers are whole numbers positive and negative, and also including zero. Here is a regular expression for this:
/^0$|^[-]?[1-9][0-9]*$/
OR, if you want to allow leading zeros:
/^[-]?[0]|[1-9][0-9]$/
Note that this will allow for values such as -0000, which does not cause problems in PHP, however. (MySQL will also cast such values as 0.)
You may also want to confine the length of your integer for considerations of 32/64-bit PHP platform features and/or database compatibility. For instance, to limit the length of your integer to 9 digits (excluding the optional - sign), you could use:
/^0$|^[-]?[1-9][0-9]{0,8}$/
Meanwhile, all the values above will only restrict the values to integer,
so i use
/^[1-9][0-9\.]{0,15}$/
to allow float values too.
You can use filter_var() to check for integers in strings
<?php
$intnum = "1000022";
if (filter_var($intnum, FILTER_VALIDATE_INT) !== false){
echo $intnum.' is an int now';
}else{
echo "$intnum is not an int.";
}
// will output 1000022 is an int now
I want to make a bid system on a website. That means users can post their bid (natural number). I want to make sure users don't try to post characters, decimal numbers, etc.
I don't want to use is_numeric function because hexadecimal notation is allowed.
I was thinking to use preg_match for this. But in php.net the documentation for this function is little and I have no idea how to use preg_match.
So how should I check if a variable is a natural number with preg_match?
If you don't require decimal points: ctype_digit or filter_var($var, FILTER_VALIDATE_INT).
If you do: filter_var($var, FILTER_VALIDATE_FLOAT).
ctype_digit does what you want:
Checks if all of the characters in the provided string, text, are numerical.
(Before PHP 5.1.0, this function returned TRUE when text was an empty string.)
Either preg_match('/^[0-9]+$/', $var); or ctype_digit
I would generally caution against using regex for parsing numerics, as there are generally better solutions than regex for this, but since you're asking, I'll try to give you some assistance with it:
preg_match uses regular expressions (regex) for it's matching.
You can find out more about regex syntax at sites like http://www.regular-expressions.info/
If you want to match a digit in regex, you can either use [0-9] or \d.
If you want to match one or more of anything, you would use a plus sign.
Finally, regex strings need to be enclosed in a pair of characters. The character chosen is usually a slash (/) character, as some languages specifically require this character, but PHP also allows other characters to be used; tilde (~) is quite common.
So your regex string to match any number of digits would be "/\d+/". This can then be put into a preg_match call like so:
$isnumeric = preg_match("/\d+/",$input_string);
If you have more specific requirements, you can limit the number of characters allowed by replacing the plus sign with {max} or {min,max} where 'min' and 'max' are the number of times the preceding match is allowed. So to allow a number between two and six digits long, you would use this:
$isnumeric = preg_match("/\d{2,6}/",$input_string);
If you need to allow a decimal point, you need to know that the dot character is a special character in regex (it means 'match any character at all'), so you need to escape it with a back-slash.
Therefore, a regex to match a currency amount with two decimal places, and at least one digit before the point would be like this:
$isnumeric = preg_match("/\d+\.\d\d/",$input_string);
Finally, note that regex will return true in all the above if the string simply contains the matched value. To ensure it doesn't contain anything else, you would need to 'anchor' it to the front and end of the string, using the anchor characters: ^ for the start of the string, and $ for the end.
So for the previous example, if you want it to only contain a decimal number, and nothing else, you would need this:
$isnumeric = preg_match("/^\d+\.\d\d$/",$input_string);
Regex is a complex subject, but I hope that gives you a start.
I know this is very old but I wanted to share the next solution in case someone else comes up with this problem.
I'm assuming that by natural number you meant positive integer (which excludes the number 0).
function is_positive_integer( $value ) {
// Check if is integer and greater than zero
if( is_int( $value ) && $value > 0 ) {
return true;
}
// Is not a positive integer
else {
return false;
}
}
This kind of depends on your definition of natural numbers - according to different theories, the number zero (0) does or does not count as a natural number.
To answer your question on how to solve this with preg_match:
If you want to include zero, using preg_match is pretty easy preg_match('^[0-9]+$', $input).
Usage:
if (preg_match('^[0-9]+$', $input))
// $input represents a non-negative numeric value
else
// $input does not represent a non-negative numeric value
If you don't want to include the zero, use preg_match('^[1-9][0-9]*$', $input):
if (preg_match('^[1-9][0-9]*$', $input))
// $input represents a positive numeric value
else
// $input does not represent a positive numeric value
That said - for your particular problem, using ctype_digit is a faster solution, as others already pointed out (you'd have to do a second check if you don't want to allow the number zero).
in_array(str_replace(str_split('0123456789'), '', $s), array(',','.',''));
simple function:
function isnature($x){
$y = ceil($x)-floor($x);
return $y == 0 ? true : false;
}
From a mathematical point of view, a natural number is a positive integer, including zero, so you could check it like this:
is_int($bid) && $bid >= 0
Simplest and faster
if( is_numeric( $key ) && intval( $key ) == $key )
{
//key == number
}
How can you match the following words by PHP, either by regex/globbing/...?
Examples
INNO, heppeh, isi, pekkep, dadad, mum
My attempt would be to make a regex which has 3 parts:
1st match match [a-zA-Z]*
[a-zA-Z]?
rotation of the 1st match // Problem here!
The part 3 is the problem, since I do not know how to rotate the match.
This suggests me that regex is not the best solution here, since it is too very inefficient for long words.
I think regex are a bad solution. I'd do something with the condition like: ($word == strrev($word)).
Regexs are not suitable for finding palindromes of an arbitrary length.
However, if you are trying to find all of the palindromes in a large set of text, you could use regex to find a list of things that might be palindromes, and then filter that list to find the words that actually are palindromes.
For example, you can use a regex to find all words such that the first X characters are the reverse of the last X characters (from some small fixed value of X, like 2 or 3), and then run a secondary filter against all the matches to see if the whole word is in fact a palindrome.
In PHP once you get the string you want to check (by regex or split or whatever) you can just:
if ($string == strrev($string)) // it's a palindrome!
i think this regexp can work
$re = '~([a-z])(.?|(?R))\1~';
I'm creating a registration system that needs to check the name/pass etc. with REGEX (and prefer to), what I've got so far is:
//Check so numbers aren't first, such as 00foobar
preg_match('/^(?!\d)[a-z0-9]+$/iD',$usrname);
//Just simple check
preg_match('/^[a-zA-Z0-9]+$/',$psword);
But I have to do stupid things in IF statements like:
if strlen($psword) > 30 || if (strlen($psword) < 4) ....
How would I impliment the length checking in my two original regular expression statements? This would make me so happy..
same but using the \w and \d for word and digits, but you might want also to include basic symbols like %!?/ ... etc...
preg_match('/^[\w\d]{4,30}$/',$psword);
the {n,v} would validate for minimum n and maximum v elements before.
like A{2,3} would validate for AA and AAA. you can take a look there for more references
On the same fashion if you want only to set the minimum of patern {n,} would do it. For example:
preg_match('/^[\w\d]{4,}$/',$psword);
I think this should do the trick:
preg_match('/^[a-zA-Z0-9]{4,30}$/',$psword);