PHP regular expressions to filter results - php

I have a list of several email addresses which look like the following
smtp:email1#myemail.com
smtp:email2#something.myemail.com
SMTP:email3#myemail.com
X400: //some random line
Is there any way I can only get the emails which only end in myemail.com? So from the above, this would be
email1#myemail.com
email3#myemail.com
So it should get rid of any random lines, and it should also ignore it if there is anything else in the string e.g. something.
I have managed to get some data by doing
([a-zA-Z]+)(#)
Probably not the best way but it gets me whats infront of the # sign. Any help filtering these out appreciated.
Thanks

You may want to use a regex to filter only emails from domain myemail.com:
<?php
$emailList = <<< LOL
smtp:email1#myemail.com
smtp:email2#something.myemail.com
SMTP:email3#myemail.com
X400: //some random line
LOL;
preg_match_all('/smtp:(.*?#myemail\.com)$/im', $emailList , $matches, PREG_PATTERN_ORDER);
print_r($matches[1]);
/*
Array
(
[0] => email1#myemail.com
[1] => email3#myemail.com
)
*/
Demo:
http://ideone.com/hcd0aa
Regex Explanation:
smtp:(.*?#myemail\.com)$
Options: Case insensitive; Exact spacing; Dot doesn’t match line breaks; ^$ don’t match at line breaks; Greedy quantifiers
Match the character string “smtp:” literally «smtp:»
Match the regex below and capture its match into backreference number 1 «(.*?#myemail\.com)»
Match any single character that is NOT a line break character «.*?»
Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
Match the character string “#myemail” literally «#myemail»
Match the character “.” literally «\.»
Match the character string “com” literally «com»
Assert position at the end of the string, or before the line break at the end of the string, if any «$»

Related

preg match between two strings

I need help with this preg match. I tried this from other post but did not get the result. So finally posting it.
I am trying to extract z,a,b from first and a from second example.
1) Write a function operations with parameter z,a,b and returns b.
2) write a function factorial with parameter a.
This is what I tried so far:
preg_match_all('/\parameter(.*?)\and?/', $question, $match);
$questionVars = $match[1];
print $questionVars;
Thank you so much!
Your solution can be different depending on actual requirements.
If you need a string after parameter as a whole word that can consist of word and comma chars you may use
preg_match('~\bparameter\s+\K\w+(?:\s*,\s*\w+)*~', $s, $m)
See the regex demo. The \bparameter\s+ matches a word boundary, parameter and 1+ whitespace chars, and all this text is omitted with the help of \K, the match reset operator. \w+(?:\s*,\s*\w+)* matches and returns the 1+ word chars followed with 0+ repetitions of a comma enclosed with optional whitespace chars and again 1+ word chars.
If you plan to get those comma-separated chunks separately, use
preg_match_all('~(?:\G(?!^)\s*,\s*|\bparameter\s+)\K\w+~', $s, $m)
See another regex demo. Here, (?:\G(?!^),\s*|\bparameter\s+) will either match the whole word parameter with 1+ whitespace after (\bparameter\s+, as in the previous solution) or the end of the previous successful match with , enclosed with optional whitespace chars (\G(?!^)\s*,\s*). The \K will omit the text matched so far and \w+ will grab the value. You may replace with [^,]* to grab 0+ chars other than a comma.

preg_match lookbehind after second slash

This is my string:
stringa/stringb/123456789,abc,cde
and after preg_match:
preg_match('/(?<=\/).*?(?=,)/',$array,$matches);
output is:
stringb/123456789
How can I change my preg_match to extract the string after second slash (or after last slash)?
Desired output:
123456789
You can match anything other than a / as
/(?<=\/)[^\/,]*(?=,)/
[^\/,]* Negated character class matches anything other than , or \
Regex Demo
Example
preg_match('/(?<=\/)[^\/,]*(?=,)/',$array,$matches);
// $matches[0]
// => 123456789
This should do it.
<?php
$array = 'stringa/stringb/123456789,abc,cde';
preg_match('~.*/(.*?),~',$array,$matches);
echo $matches[1];
?>
Disregard everything until the last forward slash (.*/). Once the last forward slash is found keep all the data until the first comma((.*?),).
You don't need to use lookbehind, i.e.:
$string = "stringa/stringb/123456789,abc,cde";
$string = preg_replace('%.*/(.*?),.*%', '$1', $string );
echo $string;
//123456789
Demo:
http://ideone.com/IxdNbZ
Regex Explanation:
.*/(.*?),.*
Match any single character that is NOT a line break character «.*»
Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
Match the character “/” literally «/»
Match the regex below and capture its match into backreference number 1 «(.*?)»
Match any single character that is NOT a line break character «.*?»
Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
Match the character “,” literally «,»
Match any single character that is NOT a line break character «.*»
Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
$1
Insert the text that was last matched by capturing group number 1 «$1»

PHP RegEx to allow mailto: http:// and tel: hyperlinks

What I need to do is allow a text field to validate and allow either a mailto: http:// or a tel: type of URL.
I'm using PHP 5 (and Laravel 4, but not as relevant to this post).
I've been googling for a while, but I can't seem to get an expression to allow a match for all three types. I've tried some long, complicated strings, and some real short ones and it just returns false.
Here's my latest:
mailto:([^\?]*)|http:([^\?]*)|tel:([^\?]*)
SOLUTION:
Since I'm using Laravel 4, I decided to use the parse_url function instead of a regex. That said, there were some other great solutions provided as well.
My final validator function:
Validator::extend('any_url', function($attribute, $value)
{
$allowed = ['mailto', 'http', 'https', 'tel'];
$parsed = parse_url($value);
return in_array($parsed['scheme'], $allowed);
});
You can use parse_url which will give you the scheme. Then check if it is within the ['mailto', 'http', 'https','tel']
Try this:
((mailto:\w+)|(tel:\w+)|(http://\w+)).+
http://regexr.com/3ar2c
You need to put whole of your regexes within a capture grouping,also you need // after http::
mailto:([^\?]*)|(http://([^\?]*))|(tel:([^\?]*))
Because in your regex the pip works different :
mailto: #first
([^\?]*)|http: #second
([^\?]*)|tel: #third
([^\?]*) #fourth
You probably need this:
/^((?:tel|https?|mailto):.*?)$/
Example:
$strings = array("http://www.me.com", "mailto:hey#there.nyc", "tel:951261412", "hyyy://www.me.com");
foreach($strings as $string){
if (preg_match('/^((?:tel|https?|mailto):.*?)$/im', $string)) {
echo $string ."\n";
}else{
echo "No Match for : $string \n";
}
}
DEMO PHP
DEMO REGEX
EXPLANATION:
^((?:tel|https?|mailto):.*?)$
-----------------------------
Assert position at the beginning of a line (at beginning of the string or after a line break character) (line feed) «^»
Match the regex below and capture its match into backreference number 1 «((?:tel|https?|mailto):.*?)»
Match the regular expression below «(?:tel|https?|mailto)»
Match this alternative (attempting the next alternative only if this one fails) «tel»
Match the character string “tel” literally (case insensitive) «tel»
Or match this alternative (attempting the next alternative only if this one fails) «https?»
Match the character string “http” literally (case insensitive) «http»
Match the character “s” literally (case insensitive) «s?»
Between zero and one times, as many times as possible, giving back as needed (greedy) «?»
Or match this alternative (the entire group fails if this one fails to match) «mailto»
Match the character string “mailto” literally (case insensitive) «mailto»
Match the character “:” literally «:»
Match any single character that is NOT a line break character (line feed) «.*?»
Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
Assert position at the end of a line (at the end of the string or before a line break character) (line feed) «$»

preg_match from some html code

How would I write a php preg_match() in php to pick out the 250 value. I have a large string of html code that I want to pick the 250 out of and I can't seem to get the regular expression right.
This is the html pattern I want to match - note that I want to extract the integer where the 250 is:
<span class="price-ld">H$250</span>
I have been trying for hours to do this and I can't get it to work lol
preg_match('/<span class="price-ld">H$(\d+)<\/span>/i', $your_html, $matches);
print "Its ".$matches[1]." USD";
The regex actually depends on your code. Where are you exactly searching for?
This is the regex you're looking for:
(?<=<span class="price-ld">H\$)\d+(?=</span>)
You can see the results here.
And here's the explanation:
Options: case insensitive; ^ and $ match at line breaks
Assert that the regex below can be matched, with the match ending at this position (positive lookbehind) «(?<=<span class="price-ld">H\$)»
Match the characters “<span class="price-ld">H” literally «<span class="price-ld">H»
Match the character “$” literally «\$»
Match a single digit 0..9 «\d+»
Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=</span>)»
Match the characters “</span>” literally «span>»

parse search string for phrases and keywords

i need to parse a search string for keywords and phrases in php, for example
string 1: value of "measured response" detect goal "method valuation" study
will yield: value,of,measured reponse,detect,goal,method valuation,study
i also need it to work if the string has:
no phrases enclosed in quotes,
any number of phrases encloses in quotes with any number of keywords outside the quotes,
only phrases in quotes,
only space-separated keywords.
i'm leaning towards using preg_match with the pattern '/(\".*\")/' to get the phrases into an array, then remove the phrases from the string, then finally work the keywords into the array. i just can't pull everything together!
i'm also thinking of replacing spaces outside quotes with commas. then explode them to an array. if that's a better option, how do i do that with preg_replace?
is there a better way to go about this? help! thanks much, everyone
preg_match_all('/(?<!")\b\w+\b|(?<=")\b[^"]+/', $subject, $result, PREG_PATTERN_ORDER);
for ($i = 0; $i < count($result[0]); $i++) {
# Matched text = $result[0][$i];
}
This should yield the results you are looking for.
Explanation :
# (?<!")\b\w+\b|(?<=")\b[^"]+
#
# Match either the regular expression below (attempting the next alternative only if this one fails) «(?<!")\b\w+\b»
# Assert that it is impossible to match the regex below with the match ending at this position (negative lookbehind) «(?<!")»
# Match the character “"” literally «"»
# Assert position at a word boundary «\b»
# Match a single character that is a “word character” (letters, digits, etc.) «\w+»
# Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
# Assert position at a word boundary «\b»
# Or match regular expression number 2 below (the entire match attempt fails if this one fails to match) «(?<=")\b[^"]+»
# Assert that the regex below can be matched, with the match ending at this position (positive lookbehind) «(?<=")»
# Match the character “"” literally «"»
# Assert position at a word boundary «\b»
# Match any character that is NOT a “"” «[^"]+»
# Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
There is no need to use a regular expression, the built in function str_getcsv can be used to explode a string with any given delimiter, enclosure and escape characters.
Really it is as simple as.
// where $string is the string to parse
$array = str_getcsv($string, ' ', '"');
$s = 'value of "measured response" detect goal "method valuation" study';
preg_match_all('~(?|"([^"]+)"|(\S+))~', $s, $matches);
print_r($matches[1]);
output:
Array
(
[0] => value
[1] => of
[2] => measured response
[3] => detect
[4] => goal
[5] => method valuation
[6] => study
)
The trick here is to use a branch-reset group: (?|...|...). It's just like an alternation contained in a non-capturing group - (?:...|...) - except that within each branch the capturing-group numbers start at the same number. (For more info, see the PCRE docs and search for DUPLICATE SUBPATTERN NUMBERS.)
Thus, the text we're interested in is always captured group #1. You can retrieve the contents of group #1 for all matches via $matches[1]. (That's assuming the PREG_PATTERN_ORDER flag is set; I didn't specify it like #FailedDev did because it's the default. See the PHP docs for details.)

Categories