jordanwb Posted December 10, 2008 Share Posted December 10, 2008 I've read DarkWater's Regex tutorial and I'm getting the hang of Regular Expressions. I've gotten this: #^([\$]?)([0-9]*\.?[0-9]{0,2})$# to test if the string represents a money value. However some people seperate thousands with commas and some with spaces. I want to add that but I'm not sure how to put that in. Quote Link to comment https://forums.phpfreaks.com/topic/136384-regex-to-test-money-value/ Share on other sites More sharing options...
premiso Posted December 10, 2008 Share Posted December 10, 2008 <?php $strings[] = '$900.00'; $strings[] = '$900,001.00'; $strings[] = '$900 001.00'; foreach ($strings as $string) preg_match('#^([\$]?)([0-9,\s]*\.?[0-9]{0,2})$#', $string, $matches[]); print_r($matches); die(); ?> Is that what you are looking for? Quote Link to comment https://forums.phpfreaks.com/topic/136384-regex-to-test-money-value/#findComment-711634 Share on other sites More sharing options...
jordanwb Posted December 10, 2008 Author Share Posted December 10, 2008 I wasn't too far off. But here's the thing, "$90 0 001.00" passes too. I could do str_replace and remove spaces and commas. Quote Link to comment https://forums.phpfreaks.com/topic/136384-regex-to-test-money-value/#findComment-711637 Share on other sites More sharing options...
laffin Posted December 10, 2008 Share Posted December 10, 2008 why the [\$] if its not a range of characters? take a look at some patterns for example of the same value with your different formats 12345678.90 $12345678.90 $12,345,678.90 12 345 678.90 $12,345,678.9 Since these are all gonna be individual strings, And we are checking the whole string. we start with ^ to signify the start of the string the $ is optional, regex has different designators, no designator = just once * = any number (0+) + = one or more (1+) ? = zero or one in this instance we want ?, but ya was right ya have to escape the '$' as it has significance in a regex pattern so next set is $? now comes the tricky part, cuz ya not shure how many digits are gonna be involved or if a seperator will be used. but we do know, the pattern of numbers usually looks like: \d?\d?\d[ ,]? if ya look at the designators above, we have optional digit optional digit and digit followed by either ' ' or a ',' but we need to repeat this cycle an unknown number of times, we can assign this as a capture group and give the capture group a designator as well (\d?\d?\d[ ,]?)* btw did u notice we can assign all those \d's a designator as well? instead of looking each one individually, we can assign a range to the \d, since we know we will always have 1, to a max of 3. we use the range designator {min,max} so now it looks like (\d{1,3}[ ,]?)* now to finish off our regex pattern with the cents, if its there, we can use the capture trick or do as u have done, lets go with the capture group to show the other way? (\.\d{0,2})? and of course, the last part, the end of string delimeter. $ so know ya shud have a pretty complex regex, that can figure out the differences of the same value with different layouts ^\$?(\d{1,3}[ ,]?)*(\.\d{0,2})?$ I Believe that does it Quote Link to comment https://forums.phpfreaks.com/topic/136384-regex-to-test-money-value/#findComment-711650 Share on other sites More sharing options...
laffin Posted December 10, 2008 Share Posted December 10, 2008 I wasn't too far off. But here's the thing, "$90 0 001.00" passes too. I could do str_replace and remove spaces and commas. or ya can expand on the regex to capture 3 digits after an initial 1-3 digit capture ^\$?\d{1,3}([ ,]?\d{3})*(\.\d{0,2})?$ I believe thats correct Quote Link to comment https://forums.phpfreaks.com/topic/136384-regex-to-test-money-value/#findComment-711660 Share on other sites More sharing options...
nrg_alpha Posted December 10, 2008 Share Posted December 10, 2008 I think my angle on this would be to simplify the initial array values (strip out any spaces, commas and dollar signs), check to see if what remains is representative in dollar format (only numbers with a single decimal and numbers (optional), then automatically add the dollar sign and commas in the appropriate places, like thus: $str = array('$900.00', '$900,001.35', '900 001', '$6 75 8 3 1.2', '$1234.5'); foreach ($str as $val){ $trans = array(' ' => '', ',' => '', '$' => ''); // replacement values from spaces, dollar signs & commas to nothingness $val = strtr($val, $trans); // execute those replacements if found preg_match('#^[0-9]+(\.[0-9]{0,2})?$#', $val, $matches); $matches[0] = '$' . number_format($matches[0], 2); echo $matches[0] . '<br />'; } Output: $900.00 $900,001.35 $900,001.00 $675,831.20 $1,234.50 Quote Link to comment https://forums.phpfreaks.com/topic/136384-regex-to-test-money-value/#findComment-711736 Share on other sites More sharing options...
nrg_alpha Posted December 10, 2008 Share Posted December 10, 2008 Ok.. one hitch I didn't see coming is if an key in the initial $str array has letters entered by accident.. According to my snippet provided, the result in this case will be $0.00... so here is the revised code which solves this: $str = array ('$900.00', '$900,001.35', '900 001', '$6 75 K 3 1.2', '$1234.5'); foreach ($str as $val){ $trans = array(' ' => '', ',' => '', '$' => ''); // replacing spaces, dollar signs & commas with nothingness $val = strtr($val, $trans); if (preg_match('#^[0-9]+(\.[0-9]{0,2})?$#', $val, $matches)){ $matches[0] = '$' . number_format($matches[0], 2); echo $matches[0] . '<br />'; } } Output: $900.00 $900,001.35 $900,001.00 $1,234.50 Note the '$6 75 K 3 1.2' entry in the $str array.. this entry will not be included in the final ouput, as it lacks only digits (with the optional decimal and digits). Quote Link to comment https://forums.phpfreaks.com/topic/136384-regex-to-test-money-value/#findComment-711788 Share on other sites More sharing options...
.josh Posted December 10, 2008 Share Posted December 10, 2008 Okay well if you're going to try and make a number out of arbitrary stuff being entered in at arbitrary places (random money formats, letters, whatever....), why not just make a really simple. Just extract the numbers. Who cares where they are or what was used. We'll throw in a decimal match, since there is a difference between 100.00 and 1.0000. Then money_format it. preg_match_all("/\d|\./",$string, $match); setlocale(LC_MONETARY, 'en_US'); $num = money_format('%n', implode($match[0])); Quote Link to comment https://forums.phpfreaks.com/topic/136384-regex-to-test-money-value/#findComment-711859 Share on other sites More sharing options...
nrg_alpha Posted December 10, 2008 Share Posted December 10, 2008 @ Crayon Violent, Touché, my friend This was made much more simplistic than my solution for sure. One *potential* crux could depend, I suppose on how your php is configured? Is money_format a PECL extension or something? When I tried your snippet on my local machine (running PHP 5.2.6), I got a "Fatal error: Call to undefined function money_format()" error...Therefore, I do not have this extension... but when I tested this online with my hosting service provider, it worked out nicely. So I guess "results may vary" so to speak.. but assuming if the hosting provider of the OP in question has this extension / configuration figured properly, it should work nicely. Quote Link to comment https://forums.phpfreaks.com/topic/136384-regex-to-test-money-value/#findComment-711948 Share on other sites More sharing options...
premiso Posted December 10, 2008 Share Posted December 10, 2008 @ Crayon Violent, Touché, my friend This was made much more simplistic than my solution for sure. One *potential* crux could depend, I suppose on how your php is configured? Is money_format a PECL extension or something? When I tried your snippet on my local machine (running PHP 5.2.6), I got a "Fatal error: Call to undefined function money_format()" error...Therefore, I do not have this extension... but when I tested this online with my hosting service provider, it worked out nicely. So I guess "results may vary" so to speak.. but assuming if the hosting provider of the OP in question has this extension / configuration figured properly, it should work nicely. money_format is not available in windows environment. On a Linux server it would work. Look at number_format the user examples, one posted a money formater that may help you. There is also one that can be found on the money_format page. Quote Link to comment https://forums.phpfreaks.com/topic/136384-regex-to-test-money-value/#findComment-711961 Share on other sites More sharing options...
nrg_alpha Posted December 10, 2008 Share Posted December 10, 2008 money_format is not available in windows environment. On a Linux server it would work. Ah, that would explain why I couldn't getting running locally (local is windows (2000 to boot ) ... host is Linux based.. so that also explains why it would work live). I did make use of number_format in my previous example.. so I suppose, taking Crayon's idealogy and integrating it into my own, I come up with: $str = array ('$900.00', '$900,001.35', '900 001', '$6 75 K 34gtJ 1.2', '$1234.5', 'hyg6789,42Jk.805.8'); foreach ($str as $val){ preg_match_all('#[0-9.]#', $val, $matches); $matches = '$' . number_format(implode($matches[0]), 2); echo $matches . '<br />'; } Output: $900.00 $900,001.35 $900,001.00 $675,341.20 $1,234.50 $678,942.81 Quote Link to comment https://forums.phpfreaks.com/topic/136384-regex-to-test-money-value/#findComment-711981 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.