How to use regular expression to find all numbers starting with "$" - php

I'm dealing with strings that contain non-comma-separated dollar values. For example:
"LOT 2 - $650000"
I need to be able to find the "$650000" and replace it with "$650,000".
The problem is, I'm a complete novice when it comes to regular expressions. I found a post that suggested this for finding numbers:
preg_match_all('!\d+!', $string, $matches);
This does successfully find both the "2" and the "650000" in my string. However, I want to make sure I only get numbers that start with "$", so I only want to get the "$650000".
Can anyone help me adapt the regular expression to get only numbers that start with "$"?

Kevin's answer is better. I went the long way around:
<?php
$dollarString = 'I would like $100000000000 more than I would like $10000000 but that is still better than $1000 and $99 problems.';
echo '<p>dollarString: ';
var_dump($dollarString);
echo '</p>';
function addCommas ($matches){
$output = [];
$number = $matches[1];
$j = 1;
for($i=strlen($number)-1; $i>=0; $i--){
array_push($output, $number[$i]);
if($j%3 == 0 && $i != 0 && $i != strlen($number)-1){array_push($output, ',');}
$j++;
}
array_push($output, '$');
$output = array_reverse($output);
return implode($output);
}
$newString = preg_replace_callback('#\$(\d+)#', 'addCommas', $dollarString);
echo '<p>newString: ';
var_dump($newString);
echo '</p>';
?>

Just add the dollar sign in your pattern and use preg_replace_callback then combine number_format. Something like this:
$string = preg_replace_callback('~\$(\d+)~', function($matches) {
return !empty($matches[1]) ? '$' . number_format($matches[1]) : null;
}, $string);

You could replace matches of the following regular expression with a comma to both confirm the presence of the dollar sign and to insert commas in the correct locations.
/(?:\$|\G)\d+?\K(?=(?:\d{3})+$)/
Start your engine!
The PCRE engine performs the following operations.
(?: : begin non-capture group
\$ : match '$'
| : or
\G : assert position at the end of the previous match
) : end non-capture group
\d+? : match 1+ digits
\K : reset starting point of match and no longer include
previously-consumed characters in reported match
(?= : begin positive lookahead
(?:\d{3}) : match 3 digits in a non-capture group
+ : execute non-capture group 1+ times
$ : match end of string
) : end positive lookahead

Try the following:
preg_match_all('!\$\d+!', $string, $matches);
This website really helped me understand how to achieve this

Related

Replace uppercase letters between special pattern

I like to replace the letters "KELLY" bettween "#" with the same length of "#". (here, repetitive five #'s instead of 'KELLY')
$str = "####KELLY#####"; // any alpabet letters can come.
preg_replace('/(#{3,})[A-Z]+(#{3,})/', "$1$2", $str);
It returns ######### (four hashes then five hashes) without 'KELLY'.
How can I get ############## which is four original leading hashes, then replace each letter with a hash, then the five original trailing hashes?
The \G continue metacharacter makes for a messier pattern, but it enables the ability to use preg_replace() instead of preg_replace_callback().
Effectively, it looks for the leading three-or-more hashes, then makes single-letter replacements until it reaches the finishing sequence of three-or-more hashes.
This technique also allows hash markers to be "shared" -- I don't actually know if this is something that is desired.
Code: (Demo)
$str = "####KELLY##### and ###ANOTHER###### not ####foo#### but: ###SHARE###MIDDLE###HASHES### ?";
echo $str . "\n";
echo preg_replace('/(?:#{3}|\G(?!^))\K[A-Z](?=[A-Z]*#{3})/', '#', $str);
Output:
####KELLY##### and ###ANOTHER###### not ####foo#### but: ###SHARE###MIDDLE###HASHES### ?
############## and ################ not ####foo#### but: ############################# ?
Breakdown:
/ #starting pattern delimiter
(?: #start non-capturing group
#{3} #match three hash symbols
| # OR
\G(?!^) #continue matching, disallow matching from the start of string
) #close non-capturing group
\K #forget any characters matched up to this point
[A-Z] #match a single letter
(?= #lookahead (do not consume any characters) for...
[A-Z]* #zero or more letters then
#{3} #three or more hash symbols
) #close the lookahead
/ #ending pattern delimiter
Or you can achieve the same result with preg_replace_callback().
Code: (Demo)
echo preg_replace_callback(
'/#{3}\K[A-Z]+(?=#{3})/',
function($m) {
return str_repeat('#', strlen($m[0]));
},
$str
);
I solved the problem with preg_replace_callback function in php.
Thanks CBroe for the tips.
preg_replace_callback('/#{3,}([A-Z]+)#{3,}/i', 'replaceLetters', $str);
function replaceLetters($matches) {
$ret = '';
for($i=0; $i < strlen($matches[0]); $i++) {
$ret .= "#";
}
return $ret;
}

Replace 3d whitespace with comma and whitespace in string

To replace a whitespace with a comma and whitespace in a string I should do something like this:
$result = preg_replace('/[ ]+/', ', ', trim($value));
The result: Some, example, here, for, you
However, I only want to replace the 3d white space, so that the result would look like this:
Some example here, for you
How do I do that?
You may use something like
$value = " Some example here for you ";
$result = preg_replace('/^\S+(?:\s+\S+){2}\K\s+/', ',$0', trim($value), 1);
echo $result; // => Some example here, for you
See the PHP demo and the regex demo.
Pattern details
^ - start of string
\S+ - 1+ non-whitespaces
(?:\s+\S+){2} - two consecutive occurrences of
\s+ - 1+ whitespaces
\S+ - 1+ non-whitespaces
\K - a match reset operator
\s+ - (the $0 in the replacement pattern references this substring) 1+ whitespaces.
You can use an callback function and control when to replace:
<?php
$string = 'Some example here for you';
$i = 0;
$string = preg_replace_callback('/\s+/',function($m) use(&$i){
$i++;
if($i == 3) {
return ', ';
}
return ' ';
},$string);
echo $string;
Try this
$result = preg_replace('/^([^\s]+)\s+((?1)\s+(?1))/', '\1 \2,', trim($value));
Test it
Explanation:
^ start of string
([^\s]+) - capture everything not a space
\s+ space 1 or more
((?1)\s+(?1)) - (?1) repeat first capture group, we do this 2x with a space between, and capture that. I guess you could capture them separately, but what's the point.
The nice thing about (?{n}) is if you have to change the regex for the word capturing you only have to change it 1 time, not 3. Probably it doesn't matter here so much, but I like using it...

Removing all characters and numbers except last variable with dash symbol

Hi I want to remove a characters using preg_replace in php so i have this code here which i want to remove the whole characters, letters and numbers except the last digit(s) which has dash(-) symbol followed by a digits so here's my code.
echo preg_replace('/(.+)(?=-[0-9])|(.+)/','','asdf1245-10');
I expect the result will be
-10
the problem is above is not working very well. I checked the pattern using http://www.regextester.com/ it seems like it works, but on the other side http://www.phpliveregex.com/ doesn't work at all. I don't know why but anyone who can help to to figure it out?
Thanks a lot
Here is a way to go:
echo preg_replace('/^.+?(-[0-9]+)?$/','$1','asdf1245-10');
Output:
-10
and
echo preg_replace('/^.+?(-[0-9]+)?$/','$1','asdf124510');
Output:
<nothing>
My first thinking is to use explode in this case.. make it simple like the following code.
$string = 'asdf1245-10';
$array = explode('-', $string);
end($array);
$key = key($array);
$result = '-' . $array[$key];
$result => '-10';
An other way:
$result = preg_match('~\A.*\K-\d+\z~', $str, $m) ? $m[0] : '';
pattern details:
\A # start of the string anchor
.* # zero or more characters
\K # discard all on the left from match result
-\d+ # the dash and the digits
\z # end of the string anchor
echo preg_replace('/(\w+)(-\w+)/','$2', 'asdf1245-10');

Regex PHP - dont match specific string followed by numeric

Im looping over a large number of files in a directory, and want to extract all the numeric values in a filename where it starts lin64exe , for instance, lin64exe005458002.17 would match 005458002.17. I have this part sorted, but in the directory there are other files, such as part005458 and others. How can I make it so I only get the numeric (and . ) after lin64exe ?
This is what I have so far:
[^lin64exe][^OTHERTHINGSHERE$][0-9]+
Regex to match the number with decimal point which was just after to lin64exe is,
^lin64exe\K\d+\.\d+$
DEMO
<?php
$mystring = "lin64exe005458002.17";
$regex = '~^lin64exe\K\d+\.\d+$~';
if (preg_match($regex, $mystring, $m)) {
$yourmatch = $m[0];
echo $yourmatch;
}
?> //=> 005458002.17
You can try with look around as well
(?<=^lin64exe)\d+(\.\d+)?$
Here is demo
Pattern explanation:
(?<= look behind to see if there is:
^ the beginning of the string
lin64exe 'lin64exe'
) end of look-behind
\d+ digits (0-9) (1 or more times (most possible))
( group and capture to \1 (optional):
\. '.'
\d+ digits (0-9) (1 or more times (most possible))
)? end of \1
$ the end of the string
Note: use i for ignore case
sample code:
$re = "/(?<=^lin64exe)\\d+(\\.\\d+)?$/i";
$str = "lin64exe005458002.17\nlin64exe005458002\npart005458";
preg_match_all($re, $str, $matches);
You can use this regex and use captured group #1 for your number:
^lin64exe\D*([\d.]+)$
RegEx Demo
Code:
$re = '/^lin64exe\D*([\d.]+)$/i';
$str = "lin64exe005458002.17\npart005458";
if ( preg_match($re, $str, $m) )
var_dump ($m[1]);

How do i parse a Google Voice email address with PHP/Regex?

I would like to extract 16197226146 from the following string using PHP:
"(480) 710-6186" <18583894531.16197226146.S7KH51hwhM#txt.voice.google.com>
Could someone please help me with the regex please?
<\d*?\.(\d+)
< Match "<"
\d Match digits
* 0 or more times
? Lazy, take as little as possible
\. Match a "."
( Capture
\d Match digits
+ 1 or more times
) Stop capturing
That matches the second number after a .. The match is in group 1.
if (preg_match("/<\d*?\.(\d+)/", $subject, $regs)) {
$result = $regs[1];
} else {
$result = "";
}
You can play with the regex here.
You could use explode.
$value = "(480) 710-6186"<18583894531.16197226146.S7KH51hwhM#txt.voice.google.com>";
$result = explode('.', $value);
echo $result[1]; // is 16197226146

Categories