I am trying to find a piece of regex to match a currency value.
I would like to match only numbers and 1 decimal point ie
Allowed
10
100
100.00
Not Allowed
Alpha Characters
100,00
+/- 100
I have search and tried quite a few without any luck.
Hope you can advise
if (preg_match('/^[0-9]+(?:\.[0-9]+)?$/', $subject))
{
# Successful match
}
else
{
# Match attempt failed
}
Side note : If you want to restrict how many decimal places you want, you can do something like this :
/^[0-9]+(?:\.[0-9]{1,3})?$/im
So
100.000
will match, whereas
100.0001
wont.
If you need any further help, post a comment.
PS If you can, use the number formatter posted above. Native functions are always better (and faster), otherwise this solution will serve you well.
How about this
if (preg_match('/^\d+(\.\d{2})?$/', $subject))
{
// correct currency format
} else {
//invalid currency format
}
You might want to consider other alternatives to using a regex.
For example, there's the NumberFormatter class, which provides flexible number and currency parsing and formatting, with build in internationalisation support.
It's built into PHP 5.3 and later, and is available as an extension on earlier versions of PHP 5.
Try this regular expression:
^(?:[1-9]\d+|\d)(?:\.\d\d)?$
Related
I'm new to php and I'm trying to write a function to find an invalid postcode. This is an option, however I've been told this isnt the ideal format:
function postcode_valid($postcode) {
return preg_match('/\w{2,3} \d\w{2}/', $postcode);
}
//more accurate
//[A-Z]{1,2}[0-9]{1,2}[A-Z]? [0-9][A-Z]{2}
I understand the first function, but I don't know how to write the 'ideal' solution as a function, please can you advise?
If the regular expression you provided in the comment field is the correct one and you don't know how to use it in PHP, here is the solution:
function postcode_valid($postcode) {
return preg_match('/^[A-Z]{1,2}[0-9]{1,2}[A-Z]? [0-9][A-Z]{2}$/', $postcode);
}
You need to add two slashes (one in front, one at the end) of the regular expression and pack it in a string in PHP. I would also highly recommend you to use ^ and $ at the beginning resp. at the end of the regular expression to indicate the beginning and the end of the string (otherwise, it is valid, if only a part of the string contains the correct pattern i.e. a longer string with a valid part would be accepted.) Here is a live example.
If you are looking for the validation of a UK post code, you should be using the following regex instead (source):
(GIR 0AA)|((([A-Z-[QVX]][0-9][0-9]?)|(([A-Z-[QVX]][A-Z-[IJZ]][0-9][0-9]?)|(([A-Z-[QVX]][0-9][A-HJKPSTUW])|([A-Z-[QVX]][A-Z-[IJZ]][0-9][ABEHMNPRVWXY])))) [0-9][A-Z-[CIKMOV]]{2})
If you are looking for something else, please provide a comment below.
Right up front, I dislike Regular Expressions. It is desired to allow input of domain or domain + port options of the DSN to be set in a single input. Also that localhost is an option as well as subdomains.
The best I could come was acquired from an article called Domain name regular expression example
Which provides this expression for Java
^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,6}$
It was realized that it almost works but the part for a period is \\. and should be \. in Php
From the php.net manual some PDO_MYSQL DSN examples are:
mysql:host=localhost;dbname=testdb
mysql:host=localhost;port=3307;dbname=testdb
The only part I want to perform the regular expression on is
localhost
localhost;port=3307
This is to be used for a filter of a HTML form as part of a Php based installation of a Php app (hope this make sense).
So this is what I came up with:
'/^((?!-)[a-z0-9-]{1,63}(?<!-)(\.){0,1})+([a-z]{0,9})(?<!\.)((;port=){1}[0-9]{2,6}){0,1}$/i'
It is important that the string does not start or end with hyphens or contain whitespace.
Here is something more in depth https://gist.github.com/CrandellWS/bc0cbcbb1df5c4b4361a
and a link to the overall project https://github.com/CrandellWS/ams
Can this expression be shorter or optimized in order to help prevent end-user errors?
More importantly as Regular Expression is not my strongest point any possible gotchas that can be prevented from please explain how and why.
For My reference these 2 sites have been immensely helpful in figuring out Regular Expressions http://www.regexr.com/ and http://txt2re.com/
If you only want to check if it is valid,(without caring on about match groups):
^[^-][a-z0-9-]{0,63}[^-](\.[a-z]{0,9})*(;port=[0-9]{2,6})?$
If you are not so exact you could test:
^[^-][a-z0-9-]*[^-](\.[a-z]+)*(;port=[0-9]+)?$
or
^[^-][\w-]*[^-](\.\w+)*(;port=\d+)?$
But essentially the every time you shrink it you are losing accuracy
Update 1:
[\w\d-]* vs [A-Za-z0-9-]{1,63} here the length of the string will not be checked
? vs {0,1} is equivalent (just shorter)
\d vs [0-9] is equivalent (just shorter)
\w vs [A-Za-z0-9_] is equivalent (just shorter)
And no negative lookbehinds (?<! ...) they make everything a bit complicated
missing accuracy: It now there are some entries possible, that shouldn't be valid, since length checks are missing and now underscore is also allowed(before not)
Update 2:
To prevent spaces at the beginning characters just add this
^[^\s-][\w-]*[^\s-](\.\w+)*(;port=\d+)?$
[^\s-] ... excludes only spaces or hyphens, any other character is allowed (even a dot)
But to get closer to your expression (without lookbehind)
^\w[\w-]*\w(\.\w+)*(;port=\d+)?$
and to remove the underscores, but it is a bit longer
^[a-z0-9][a-z0-9-]*[a-z0-9](\.[a-z0-9-]+)*(;port=\d+)?$
I can suggest try to make it more strict like this:
example
It dosen't consider unix_socket and it's not short but simple to understand. You can try to make it more precise.
UPDATED
Try also this example
Let me surprise you that parameters in DSN can go in random order.
This is to be used for a filter of a HTML form as part of a Php based installation of a Php app
For my life I won't understand why would you torture a user asking them to create a DSN-like string (which they likely have no idea of) and then torture yourself verifying it. Instead of just asking for separate host and (optional) port fields, just like any installation script in the world does.
Let me suggest you to make yourself familiar with some existing installation scripts, before starting for your own. One from Wordpress will do.
It just occured to me that may be you need help with PHP conditionals. Here you go:
if (isset($_POST['dbhost'])) {
if ($_POST['dbport'])
{
$DB_PORT = $_POST['dbport']
} else {
$DB_PORT = 3306;
}
$DB_HOST = $_POST['dbhost'];
$DB_DATABASE = $_POST['dbname'];
$DB_USERNAME = $_POST['dbuser'];
$DB_PASSWORD = $_POST['dbpass'];
$DB_DSN = 'mysql:host=$DB_HOST;port=$DB_PORT;dbname=$DB_DATABASE";
This simple code will solve all your problems without Regular Expressions you don't like. I hope that your dislikes do not extend to simple conditionals though.
After having checked everywhere in vain I decided to post this problem here. I am Working on an online shop where the client needs to show automatically a "free shipping label" for all items that cost 100€ or more. I did make a function that worked with plain numbers (80€), but when the price is in this format (2.453,90€) it doesn´t.
I would really appreciate your help if you could shed some light on this issue. Thanks in advance
just remove dot and put dot instead of comma for php to recognize this as a number:
$plainNumber = floor(str_replace(",",".",str_replace(".","","2.453,90")));
if($plainNumber >= 100)
{
//do intended stuff
}
You could use regular expressions to transforms formatted numbers in raw numbers.
$number = preg_replace('/\./', '', $number);
$number = preg_replace('/,/', '.', $number);
You could also store raw numbers instead of formatted numbers.
Stringified data types are a not uncommon beginner error. You should always handle numbers as native numbers and only convert to string when printing them.
When you use numbers, good old comparison operators become useful.
I'm writing a script that will allow a user to input a string that is a math statement, to then be evaluated. I however have hit a roadblock. I cannot figure out how, using preg_match, to dissallow statements that have variables in them.
Using this, $calc = create_function("", "return (" . $string . ");" ); $calc();, allows users to input a string that will be evaluated, but it crashes whenever something like echo 'foo'; is put in place of the variable $string.
I've seen this post, but it does not allow for math functions inside the string, such as $string = 'sin(45)';.
For a stack-based parser implemented in PHP that uses Djikstra's shunting yard algorithm to convert infix to postfix notation, and with support for functions with varying number of arguments, you can look at the source for the PHPExcel calculation engine (and which does not use eval)
Also have a look at the responses to this question
How complex of a math function do you need to allow? If you only need basic math, then you might be able to get away with only allowing whitespace + the characters 0123456789.+/-* or some such.
In general, however, using the language's eval-type capabilities to just do math is probably a bad idea.
Something like:
^([\d\(\)\+\-*/ ,.]|sin\(|cos\(|sqrt\(|...)+$
would allow only numbers, brackets, math operations and provided math functions. But it won't check if provided expression is valid, so something like +++sin()))333((( would be still accepted.
I wonder if this class would help you? Found that doing a search on Google for "php math expressions".
I have an input for users where they are supposed to enter their phone number. The problem is that some people write their phone number with hyphens and spaces in them. I want to put the input trough a filter to remove such things and store only digits in my database.
I figured that I could do some str_replace() for the whitespaces and special chars.
However I think that a better approach would be to pick out just the digits instead of removing everything else. I think that I have heard the term "whitelisting" about this.
Could you please point me in the direction of solving this in PHP?
Example: I want the input "0333 452-123-4" to result in "03334521234"
Thanks!
This is a non-trivial problem because there are lots of colloquialisms and regional differences. Please refer to What is the best way for converting phone numbers into international format (E.164) using Java? It's Java but the same rules apply.
I would say that unless you need something more fully-featured, keep it simple. Create a list of valid regular expressions and check the input against each until you find a match.
If you want it really simple, simply remove non-digits:
$phone = preg_replace('![^\d]+!', '', $phone);
By the way, just picking out the digits is, by definition, the same as removing everything else. If you mean something different you may want to rephrase that.
$number = filter_var(str_replace(array("+","-"), '', $number), FILTER_SANITIZE_NUMBER_INT);
Filter_Var removes everything but pluses and minuses, and str_replace gets rid of those.
or you could use preg_replace
$number = preg_replace('/[^0-9]/', '', $number);
You could do it two ways. Iterate through each index in the string, and run is_numeric() on it, or you could use a regular expression on the string.
On the client side I do recommand using some formating that you design when creating a form. This is good for zip or telephone fields. Take a look at this jquery plugin for a reference. It will much easy later on the server side.