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

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

Related

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

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

PHP regular expression to match multiple email ID formats

I am trying to obtain the local part of an email ID using regex.
The challenge here is that the local part comes in two different formats and I need to figure out which format I'm reading and prepare the alternate form of that email ID. As always the snippet of my code that does this is pasted below.
$testarray = array("user1#gmail.com", "user2.tp#gmail.com", "user3#gmail.com", "user4.tp#gmail.com", "user5.tp#gmail.com");
foreach($testarray as $emailID) {
preg_match("/([\w\d]*)\.([\w\d]*)#gmail.com/", $emailID, $match);
if ($match[2] == "tp") {
$altform = $match[1] . "#gmail.com";
} else {
$altform = $match[1] . ".tp#gmail.com";
}
error_log("ALTERNATE FORM OF $emailID IS $altform");
}
The problem I'm facing here is I'm not getting the desired result as neither $match[1] and $match[2] match anything for "user1#gmail.com".
You need to use an optional group around the dot + word chars subpattern, and then check if the group matched after executing the search:
foreach($testarray as $emailID) {
$altform = "";
if (preg_match("/(\w+)(?:\.(\w+))?#gmail\.com/", $emailID, $match))
{
if (!empty($match[2]) && $match[2] == "tp") {
$altform = $match[1] . "#gmail.com";
} else {
$altform = $match[1] . ".tp#gmail.com";
}
}
print_r("ALTERNATE FORM OF $emailID IS $altform\n");
}
See the online PHP demo.
Notes on the pattern:
(\w+) - Capturing group 1: one or more word chars
(?:\.(\w+))? - 1 or 0 occurrences (due to ? quantifier) of:
\. - a dot
(\w+) - Capturing group 2: one or more word chars
#gmail\.com - a literal string #gmail.com (note the . is escaped to match a literal dot).

php - find match in string

I'm trying to work out how to find a match in a string.
I'm looking for a match on any of the following - = ? [] ~ # ! 0 - 9 A-Z a-z and I need to know what its matched on .
Eg: matched on !, or matched on = and # and ?
Normally I'd use this:
$a = 'How are you?';
if (strpos($a, 'are') !== false) {
echo 'true';
}
However I'm not sure how to do that so it looks up the characters needed.
Also where I may have [], It could be [] or [xxxx] where xxxx could be any number of alpha numeric characters.
I need to match and any of the characters listed, return the characters so I know what was matched and if the [] contain any value return that as well.
Eg:
$a = 'DeviceLocation[West12]';
Would return: $match = '[]'; $match_val= 'West12';
$a = '#=Device';
Would return:$match = '#,=';
$a= '?[1234]=#Martin';
Would return: $match = '?, [], =, #'; $match_val= '1234';
Can any one advise how I can do this.
Thanks
Well, that requirements are a bit vague, but that is what I deduced:
1) if there is an alphanumeric string inside square brackets get it as a separate value
2) all other mentioned chars should be matched one by one and then imploded.
You may use the following regex to get the values you need:
$re = '#\[([a-zA-Z0-9]+)\]|[][=?~#!]#';
Details:
\[ - a [
([a-zA-Z0-9]+) - Group 1 value capturing 1 or more alphanumeric symbols
\] - a closing ]
| - or
[][=?~#!] - a single char, one of the defined chars in the set.
See the regex demo. The most important here is the code that gets the matches (feel free to adapt):
$re = '#\[([a-zA-Z0-9]+)\]|[][=?~#!]#';
$strs =array('DeviceLocation[West12]', '#=Device', '?[1234]=#Martin');
foreach ($strs as $str) {
preg_match_all($re, $str, $matches, PREG_SET_ORDER);
$results = array();
$match_val = "";
foreach ($matches as $m) {
if (!empty($m[1])) {
$match_val = trim($m[1], "[]");
array_push($results, "[]");
} else {
array_push($results, $m[0]);
}
}
echo "Value: " . $match_val . "\n";
echo "Symbols: " . implode(", ", $results);
echo "\n-----\n";
}
See the PHP demo
Output:
Value: West12
Symbols: []
-----
Value:
Symbols: #, =
-----
Value: 1234
Symbols: ?, [], =, #
-----
Please use Regular Expressions, e.g using preg_match
Try this
It will match the string in []
preg_match_all("/\[([^\]]*)\]/", $text, $matches);
And this will match string after ? and #=
preg_match_all("/^#=(\S+)|\?(.*)/", $text, $matches);
var_dump($matches);
You need regular expressions to check for any text inside another with different properties, here is a simple tutorial on that link.

Regular expressions match first number next to a given character

how can I match a the first number next to a % character ?
<?php
$string = 'Get 30% off when you spend over £100 on electronics';
if(strpos($string,'% off') !== false) {
$number = preg_replace("/[^0-9%]/", '', $string);
return $number;
}
this returns 30%100
any help would be great thanks in advance.
This regex will match (and capture) all digits preceding a '%' sign:
'/(\d+)%/'
You can try something like this:
$string = 'Get 30% off when you spend over £100 on electronics';
preg_match('/(\d+)%/', $string, $matches);
print_r($matches[1]);
Do let us know if your requirements are more complex.
Regex:
\d{1,3}%
Explained:
\d{1,3} match a digit [0-9]
Quantifier: {1,3} Between 1 and 3 times, as many times as possible, giving back as needed [greedy]
% matches the character % literally
This seems to do the trick :)
if(strpos($string,'%') !== false) {
$regex_percent = "/((\d{1,5})(?:%))/";
preg_match($regex_percent, $string, $matches_off);
$number = $matches_off[2];
return $number;
}

Regex: Using capture data further in the regex

I want to parse some text that start with ":" and could be surround with parentheses to stop the match so:
"abcd:(someText)efgh" and
"abcd:someText"
will return someText.
but i have a problem to set the parentheses optionnal.
I make this but it does not works:
$reg = '#:([\\(]){0,1}([a-z]+)$1#i';
$v = 'abc:(someText)def';
var_dump(preg_match($reg,$v,$matches));
var_dump($matches);
The $1 makes it failed.
i don't know how to tell him :
If there is a "(" at the beginning, there must be ")" at the end.
You can't test if the count of something is equal to another count. It's a regex problem who can only be used with regular language (http://en.wikipedia.org/wiki/Regular_language). To achieve your goal, as you asked - and that is if there's a '(' should be a ')' -, you'll need a Context-Free Language (http://en.wikipedia.org/wiki/Context-free_language).
Anyway, you can use this regex:
'/:(\([a-z]+\)|[a-z]+)/i
To return the match of different sub-patterns in the regex to the same element of the $matches array, you can use named subpattern with the internal option J to allow duplicate names. The return element in $matches is the same as the name of the pattern:
$pattern = '~(?J:.+:\((?<text>[^)]+)\).*|.+:(?<text>.+))~';
$texts = array(
'abc:(someText)def',
'abc:someText'
);
foreach($texts as $text)
{
preg_match($pattern, $text, $matches);
echo $text, ' -> ', $matches['text'], '<br>';
}
Result:
abc:(someText)def -> someText
abc:someText -> someText
Demo
This regex will match either :word or :(word) groups 1 and 2 hold the respective results.
if (preg_match('/:([a-z]+)|\(([a-z]+)\)/i', $subject, $regs)) {
$result = ($regs[1])?$regs[1]:$regs[2];
} else {
$result = "";
}
regex: with look-behind
"(?<=:\(|:)[^()]+"
test with grep:
kent$ echo "abcd:(someText)efgh
dquote> abcd:someOtherText"|grep -Po "(?<=:\(|:)[^()]+"
someText
someOtherText
Try this
.+:\((.+)\).*|.+:(.+)
if $1 is empty there are no parentheses and $2 has your text.

Categories