Say we have two price strings in different format:
$s_price = '85.95' or '1500.00'
$r_price = '$ 85.95' or '1,500'
But all these prices are the same and should match.
I have a regex to do that but don't know if this is how we do it:
(\d+)*(,)?\d+(.)?\d*
To retrieve and parse a float from a string in PHP, use the floatval() method.
For the symbols, it depends on wether you always use the same conventions for your currencies (comma for thousands separator and dot for decimals). In that case, you should remove non-digits except dots with the preg_replace() method (the correspondig Regex could be /[^0-9.]/)
<?php
function sanitize($price) {
return floatval(preg_replace('/[^0-9.]/', '', $price));
}
$a1 = '85.95';
$a2 = '1500.00';
$b1 = '$ 85.95';
$b2 = '1,500';
sanitize($a1); // (float) 85.95
sanitize($a2); // (float) 1500
sanitize($b1); // (float) 85.95
sanitize($b2); // (float) 1500
sanitize($a1) === sanitize($b1); // (bool) true
sanitize($a2) === sanitize($b2); // (bool) true
sanitize($a1) <= sanitize($a2); // (bool) true
sanitize($b1) >= sanitize($b2); // (bool) false
Hope it will help !
You have a lot of optional parts in your pattern using ? and * and you could omit the capturing groups if you are not referring to them in the code.
What you might do is match an optional part for the dollar sign followed by 0+ horizontal whitespace chars.
Then match 1+ digits followed by an optional part to match a dot or comma and 1+ digits:
(?<!\S)(?:\$\h*)?\d+(?:[,.]\d+)\b
Explanation
(?<!\S) Assert what is on the left is not a non whitespace char
(?:\$\h*)? Optionally match a dollar sign and 0+ horizontal whitespace chars
\d+(?:[,.]\d+) Match 1+ digits followed by an optional part to match either a dot or comma and 1+ digits
\b word boundary to prevent the digit being part of a larger word
Regex demo | Php demo
you store numbers as integer or float
and to compare you need to use || not or
hope that was helpful
Related
http://www.tehplayground.com/#0qrTOzTh3
$inputs = array(
'2', // no match
'29.2', // no match
'2.48',
'8.06.16', // no match
'-2.41',
'-.54', // no match
'4.492', // no match
'4.194,32',
'39,299.39',
'329.382,39',
'-188.392,49',
'293.392,193', // no match
'-.492.183,33', // no match
'3.492.249,11',
'29.439.834,13',
'-392.492.492,43'
);
$number_pattern = '-?(?:[0-9]|[0-9]{2}|[0-9]{3}[\.,]?)?(?:[0-9]|[0-9]{2}|[0-9]{3})[\.,][0-9]{2}(?!\d)';
foreach($inputs as $input){
preg_match_all('/'.$number_pattern.'/m', $input, $matches);
print_r($matches);
}
It seems you are looking for
$number_pattern = '-?(?<![\d.,])\d{1,3}(?:[,.]\d{3})*[.,]\d{2}(?![\d.])';
See the PHP demo and a regex demo.
The anchors are not used, there are lookarounds on both sides of the pattern instead.
Pattern details:
-? - an optional hyphen
(?<![\d.,]) - there cannot be a digit, comma or dot befire the current location
-\d{1,3} - 1 to 3 digits
(?:[,.]\d{3})* - zero or more sequences of a comma or dot followed with 3 digits
[.,] - a comma or dot
\d{2} - 2 digits that are
(?![\d.]) - not followed with a digit or dot.
Note in PHP, you do not need to specify the /m MULTILINE mode and use the $ end of string anchor,
preg_match_all('/'.$number_pattern.'/', $input, $matches);
is enough to match the numbers you need in larger texts.
If you need to match them as standalone strings, use a simpler
^-?\d{1,3}(?:[,.]\d{3})*[.,]\d{2}$
See the regex demo.
Let's say I only allow this kind of format 2015-2016 which contains number and only one dash. How can I do this with preg_match? I tried the following, but with no luck.
$a = '2015-2016';
if(!preg_match('/[^0-9\-]/i',$a)) {
then return not valid data`
}
Hope this will help
preg_match('/^\d{4}-\d{4}$/', $string);
^ Start of the string
\d{4} match a digit [0-9] Exactly 4 times
- matches the character - literally
\d{4} match a digit [0-9] Exactly 4 times
$ End of the string
$a = '2015-2016';
if(!preg_match('/^[0-9 \-]+$/',$a)) {
then return not valid data }
Try that.
How to match exact word contains any special character ?
$string = 'Fall in love with #PepsiMoji! Celebrate #WorldEmojiDay by downloading our keyboard # http://bit.ly/pepsiKB & take your text game up a notch. - teacher';
preg_match("/\b#worldemojiday\b/i",$string); //false
I want to match exact word containing any character. Like if I want to match word 'download' in this string, It should return false
preg_match("/\bdownload\b/i",$string); //false
But when I search for downloading, It should return true.
Thanks
The problem is with \b word boundary before # non-word character. \b cannot match the position between 2 non-word (or between 2 word) characters, thus, you do not get a match.
A solution is either to remove the first \b, or use \B (a non-word boundary matching between 2 word or 2 non-word characters) instead of it.
\B#worldemojiday\b
Or
#worldemojiday\b
See demo (or this one)
Note that \B also matches at the beginning of a string.
Here is a way to build a regex dynamically, adding word boundaries only where necessary:
$srch = "žvolen";
$srch = preg_quote($srch);
if (preg_match('/\w$/u', $srch)) {
$srch .= '\\b';
}
if (preg_match('/^\w/u', $srch)) {
$srch = '\\b' . $srch;
}
echo preg_match("/" . $srch . "/ui", "žvolen is used.");
What about using lookarounds:
(?<!\w)#WorldEmojiDay(?!\w)
This ensures, that there's no word character before or after the string. See test at regex101
I need a regex to see if the $input ONLY contained alphabetic characters or white spaces also need one to check if $numInput ONLY contained numeric characters or white spaces AND one combined so:
$alphabeticOnly = 'abcd adb';
$numericOnly = '1234 567';
$alphabeticNumeric = 'abcd 3232';
So in all of the above examples alphabetic, numeric, whitespace are allowed ONLY NO symbols.
How can I get those 3 diffrent regular expression?
This should help you
if (!preg_match('/^[\sa-zA-Z]+$/', $alphabeticOnly){
die('alpha match fail!');
}
if (!preg_match('/^[\s0-9]+$/', $numericOnly){
die('numeric match fail!');
}
if (!preg_match('/^[\sa-zA-Z0-9]+$/', $alphabeticNumeric){
die('alphanumeric match fail!');
}
This is pretty basic
/^[a-z\s]+$/i - letter and spaces
/^[\d\s]+$/ - number and spaces
/^[a-z\d\s]+$/i - letter, number and spaces
Just use them in preg_match()
In order to be unicode compatible, you should use:
/^[\pL\s]+$/ // Letters or spaces
/^[\pN\s]+$/ // Numbers or spaces
/^[\pL\pN\s]+$/ // Letters, numbers or spaces
What would be Regex to match the following 10-digit numbers:
0108889999 //can contain nothing except 10 digits
011 8889999 //can contain a whitespace at that place
012 888 9999 //can contain two whitespaces like that
013-8889999 // can contain one dash
014-888-9999 // can contain two dashes
If you're just looking for the regex itself, try this:
^(\d{3}(\s|\-)?){2}\d{4}$
Put slightly more legibly:
^ # start at the beginning of the line (or input)
(
\d{3} # find three digits
(
\s # followed by a space
| # OR
\- # a hyphen
)? # neither of which might actually be there
){2} # do this twice,
\d{4} # then find four more digits
$ # finish at the end of the line (or input)
EDIT: Oops! The above was correct, but it was also too lenient. It would match things like 01088899996 (one too many characters) because it liked the first (or the last) 10 of them. Now it's more strict (I added the ^ and $).
I'm assuming you want a single regex to match any of these examples:
if (preg_match('/(\d{3})[ \-]?(\d{3})[ \-]?(\d{4})/', $value, $matches)) {
$number = $matches[1] . $matches[2] . $matches[3];
}
preg_match('/\d{3}[\s-]?\d{3}[\s-]?\d{4}/', $string);
0108889999 // true
011 8889999 // true
012 888 9999 // true
013-8889999 // true
014-888-9999 // true
To match the specific parts:
preg_match('/(\d{3})[\s-]?(\d{3})[\s-]?(\d{4}/)', $string, $matches);
echo $matches[1]; // first 3 numbers
echo $matches[2]; // next 3 numbers
echo $matches[3]; // next 4 numbers
You can try this pattern. It satisfies your requirements.
[0-9]{3}[-\s]?[0-9]{3}[-\s]?[0-9]{4}
Also, you can add more conditions to the last character by appending [\s.,]+: (phone# ending with space, dot or comma)
[0-9]{3}[-\s]?[0-9]{3}[-\s]?[0-9]{4}[\s.,]+