I do have a var like this:
$mail_from = "Firstname Lastname <email#domain.com>";
I would like to receive either an
array(name=>"firstname lastname", email=>"email#domain.com")
or
the values in two separate vars ($name = "...", $email = "...")
I have been playing around with preg_replace but somehow do not get it done ...
Did extensive search but did not find a way to get this done.
This is the closest I got:
$str = 'My First Name <email#domain.com>';
preg_match('~(?:"([^"]*)")?\s*(.*)~',$str,$var);
print_r($var);
echo "<br>Name: ".$var[0];
echo "<br>Mail: ".$var[2];
How do I get "email#domain.com" into $var['x]?
Thank you.
This works for your example and should always work, when the email is within angle brackets.
$str = 'My First Name <email#domain.com>';
preg_match('~(?:([^<]*?)\s*)?<(.*)>~', $str, $var);
print_r($var);
echo "<br>Name: ".$var[1];
echo "<br>Mail: ".$var[2];
Explanation:
(?:([^<]*?)\s*)? matches optionally everything that is not a < and everything except the trailing whitespace is stored in group 1.
<(.*)> matches something between angle brackets and store it in group 2.
//trythis
$mail_from = "Firstname Lastname <email#domain.com>";
$a = explode("<", $mail_from);
$b=str_replace(">","",$a[1]);
$c=$a[0];
echo $b;
echo $c;
Try this:
(?<=")([^"<>]+?) *<([^<>"]+)>(?=")
Explanation:
<!--
(?<=")([^"<>]+?) *<([^<>"]+)>(?=")
Options: ^ and $ match at line breaks
Assert that the regex below can be matched, with the match ending at this position (positive lookbehind) «(?<=")»
Match the character “"” literally «"»
Match the regular expression below and capture its match into backreference number 1 «([^"<>]+?)»
Match a single character NOT present in the list “"<>” «[^"<>]+?»
Between one and unlimited times, as few times as possible, expanding as needed (lazy) «+?»
Match the character “ ” literally « *»
Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
Match the character “<” literally «<»
Match the regular expression below and capture its match into backreference number 2 «([^<>"]+)»
Match a single character NOT present in the list “<>"” «[^<>"]+»
Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
Match the character “>” literally «>»
Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=")»
Match the character “"” literally «"»
-->
Code:
$result = preg_replace('/(?<=")([^"<>]+?) *<([^<>"]+)>(?=")/m', '<br>Name:$1<br>Mail:$2', $subject);
Related
I have the following:
$pattern = "/^([\w_]{1})(.+)([\w_]{1}#)/u";
$replacement = "$1*$3***$4";
$email = "testa#weste.de";
echo "obfuscated: ".preg_replace($pattern, $replacement, $email).RT;
The result is: t*a#***weste.de
But I would like to have: t*#w***.de
How to grab the letter after the # and not before. And how does it work with the .de part?
For the replacement in the example data, you might use a match with \K to forget what is matched after the first character and keep it.
To keep the first character after the # sign, you can use a capture group and use that in the replacement.
^\w\K[^\s#]+#(\w)[^\s.#]+
^ Start of string
\w Match a single word char (That will also match _)
\K Forget what is matched so far
[^\s#]+ Match 1+ chars other than # or a whitespace char
# Match the # char
(\w) Capture group 1, match a word char (to keep)
[^\s.#]+ Match 1+ chars other than #, a whitespace char or dot
Regex demo | Php demo
In the replacement use a single capture group *#$1***
$email = "testa#weste.de";
$pattern = "/^\w\K[^\s#]+#(\w)[^\s.#]+/";
$replacement = "*#$1***";
echo preg_replace($pattern, $replacement, $email);
Output
t*#w***.de
You can make the pattern as specific as you would like. If there should for example be a dot followed by at least 2 chars a-z at the end of the string, and you don't want to stop matching at the first dot after the #
^\w\K[^\s#]+#(\w)[^\s#]+(?=\.[a-z]{2,}$)
Regex demo
I found this way to do it:
$email = 'someemail#domain.com'
[$firstPart, $lastPart] = explode('#', $email);
$maskedEmail = str_replace(substr($firstPart, 0, 7), str_repeat('*', 7), $email);
Uses PHP native functions and works just fine!
Let's say I want to split this string in two variables:
$string = "levis 501";
I will use
preg_match('/\d+/', $string, $num);
preg_match('/\D+/', $string, $text);
but then let's say I want to split this one in two
$string = "levis 5° 501";
as $text = "levis 5°"; and $num = "501";
So my guess is I should add a rule to the preg_match('/\d+/', $string, $num); that looks for numbers only at the END of the string and I want it to be between 2 and 3 digits.
But also the $text match now has one number inside...
How would you do it?
To slit a string in two parts, use any of the following:
preg_match('~^(.*?)\s*(\d+)\D*$~s', $s, $matches);
This regex matches:
^ - the start of the string
(.*?) - Group 1 capturing any one or more characters, as few as possible (as *? is a "lazy" quantifier) up to...
\s* - zero or more whitespace symbols
(\d+) - Group 2 capturing 1 or more digits
\D* - zero or more characters other than digit (it is the opposite shorthand character class to \d)
$ - end of string.
The ~s modifier is a DOTALL one forcing the . to match any character, even a newline, that it does not match without this modifier.
Or
preg_split('~\s*(?=\s*\d+\D*$)~', $s);
This \s*(?=\s*\d+\D*$) pattern:
\s* - zero or more whitespaces, but only if followed by...
(?=\s*\d+\D*$) - zero or more whitespaces followed with 1+ digits followed with 0+ characters other than digits followed with end of string.
The (?=...) construct is a positive lookahead that does not consume characters and just checks if the pattern inside matches and if yes, returns "true", and if not, no match occurs.
See IDEONE demo:
$s = "levis 5° 501";
preg_match('~^(.*?)\s*(\d+)\D*$~s', $s, $matches);
print_r($matches[1] . ": ". $matches[2]. PHP_EOL);
print_r(preg_split('~\s*(?=\s*\d+\D*$)~', $s, 2));
I want to do something like stackoverflow. actually changing this style []() to this style . here is my try:
$str = '[link](#)';
$str = str_replace('[','<a href="',$str); // output: <a href="link](#)
$str = str_replace(']','">',$str); // output: <a href="link">(#)
$str = str_replace('(','',$str); // output: <a href="link">#)
$str = str_replace(')','</a>',$str); // output: #
but now, I need to change link with #, how can I do that ?
You want to take a look at preg_replace(), with this you can use a regex to replace it, e.g.
$str = preg_replace("/\[(.*?)\]\((.*?)\)/", "<a href='$2'>$1</a>", $str);
regex explanation:
\[(.*?)\]\((.*?)\)
\[ matches the character [ literally
1st Capturing group (.*?)
.*? matches any character (except newline)
Quantifier: *? Between zero and unlimited times, as few times as possible, expanding as needed [lazy]
\] matches the character ] literally
\( matches the character ( literally
2nd Capturing group (.*?)
.*? matches any character (except newline)
Quantifier: *? Between zero and unlimited times, as few times as possible, expanding as needed [lazy]
\) matches the character ) literally
I am new to job as well as for regular expressions. I am using php.
For the following string i want to extract the report number.
Dear Patient! (patient name) Your Reports(report number) has arrived.
can someone help me in creating a regular expression.
thank you
Solved:
$str ='Dear Patient! (P.JOHN) Your Reports (REPORTNO9) has arrived.';
$str = str_replace('(', '', $str);
$str = str_replace(')', '', $str);
preg_match('/Reports\s*(\w+)/', $str, $match);
echo $match[1]; //=> "REPORTNO9"
The Regular Expression
/Dear (\w+)! Your Reports(.*?)(?=has arrived)/
PHP usage
<?php
$subject = 'Dear Patient! Your Reports(report number) has arrived.';
if (preg_match('/Dear (\w+)! Your Reports(.*?)(?=has arrived)/', $subject, $regs)) {
var_dump($regs);
}
Result
array(3) {
[0]=>
string(42) "Dear Patient! Your Reports(report number) "
[1]=>
string(7) "Patient"
[2]=>
string(16) "(report number) "
}
Explanation
"
Dear\ # Match the characters “Dear ” literally
( # Match the regular expression below and capture its match into backreference number 1
\w # Match a single character that is a “word character” (letters, digits, etc.)
+ # Between one and unlimited times, as many times as possible, giving back as needed (greedy)
)
!\ Your\ Reports # Match the characters “! Your Reports” literally
( # Match the regular expression below and capture its match into backreference number 2
. # 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)
)
(?= # Assert that the regex below can be matched, starting at this position (positive lookahead)
has\ arrived # Match the characters “has arrived” literally
)
"
You can use "split()" to extract the specific part of a string like this, so you don't have to use regex :
<?php
$my_string = ""; // Put there you string
$array_my_string = array();
$array_my_string = split('Reports', $my_string);
$tempResult = array_my_string[1]; // Will contains "(report number) has arrived."
$array_my_string = split(' has arrived', $tempResult);
$finalResult = $array_my_result[0]; // Will contains "(report number)"
?>
I have a string that can be very long and contain various lines and characters.
I am wanting to extract all lines that are surrounded by SB & EB:
SB1EB
SBa description of various lengthEB
SB123.456.78EB
SB99.99EB
SB99.99EB
SB2EB
SBanother description of various lengthEB
SB123.456.00EB
SB199.99EB
SB199.99EB
3
another description of various length that I don't want to return
123.456.00
599.99
599.99
SB60EB
SBanother description of various length that i want to keepEB
SB500.256.10EB
SB0.99EB
SB0.99EB
another bit of text that i don't want - can span multiple lines
This is the pattern I am using in PHP:
preg_match_all('/SB(\d+)EB\nSB(\w.*)EB\nSB(\d{3}\.\d{3}\.\d{2})EB\nSB(\d.*)EB\nSB(\d.*)EB\n/', $string, $matches)
So this should hopefully return:
[0] -> SB1EB
SBa description of various lengthEB
SB123.456.78EB
SB99.99EB
SB99.99EB
[1] -> SB2EB
SBanother description of various lengthEB
SB123.456.00EB
SB199.99EB
SB199.99EB
[2] -> SB60EB
SBanother description of various length that i want to keepEB
SB500.256.10EB
SB0.99EB
SB0.99EB
But I'm obviously doing something wrong because it isn't matching anything. Can somebody help please?
SOLUTION:
Based on #Sajid reply:
if (preg_match_all('/(?:SB.+?EB(?:[\r\n]+|$))/', $string, $result)) {
for($i=0;$i<count($result[0]);$i++){
$single_item = $result[0][$i];
$single_item = str_replace("SB","",$single_item);
$single_item = str_replace("EB","",$single_item);
if (preg_match('/(\d{3}\.\d{3}\.\d{2})/', $single_item)) {
$id = $single_item;
$qty = $result[0][$i-2];
$name = $result[0][$i-1];
$price = $result[0][$i+1];
$total = $result[0][$i+2];
}
}
}
It's a bit messy, but it works! :)
Thanks
A bit of a hack, but this will do the job:
$a = array();
if (preg_match_all('/(?:SB.+?EB(?:[\r\n]+|$)){5}/', $x, $a)) {
print_r($a);
}
Note that ?: is used to make the group non-capture, and the results will be in $a[0] (eg, $a[0][0], $a[0][1], $a[0][2] ...)
Based on #Sajid reply:
if (preg_match_all('/(?:SB.+?EB(?:[\r\n]+|$))/', $string, $result))
{
for ($i=0; $i<count($result[0]); $i++)
{
$single_item = $result[0][$i];
$single_item = str_replace("SB","",$single_item);
$single_item = str_replace("EB","",$single_item);
if (preg_match('/(\d{3}\.\d{3}\.\d{2})/', $single_item))
{
$id = $single_item;
$qty = $result[0][$i-2];
$name = $result[0][$i-1];
$price = $result[0][$i+1];
$total = $result[0][$i+2];
}
}
}
It's a bit messy, but it works! :)
preg_match_all('/SB\d+EB.*?(?=(?:SB\d+EB)|$)/s', $subject, $result, PREG_PATTERN_ORDER);
for ($i = 0; $i < count($result[0]); $i++) {
# Matched text = $result[0][$i];
}
So basically what I am doing (based on your input) is simply checking the "header" string SB\d+EB as an entry point and consuming everything until I find another "header" or the end of the input. Note the /s modifier so that . matches newlines.
Explanation:
# SB\d+EB.*?(?=(?:SB\d+EB)|$)
#
# Options: dot matches newline
#
# Match the characters “SB” literally «SB»
# Match a single digit 0..9 «\d+»
# Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
# Match the characters “EB” literally «EB»
# Match any single character «.*?»
# Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
# Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=(?:SB\d+EB)|$)»
# Match either the regular expression below (attempting the next alternative only if this one fails) «(?:SB\d+EB)»
# Match the regular expression below «(?:SB\d+EB)»
# Match the characters “SB” literally «SB»
# Match a single digit 0..9 «\d+»
# Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
# Match the characters “EB” literally «EB»
# Or match regular expression number 2 below (the entire group fails if this one fails to match) «$»
# Assert position at the end of the string (or before the line break at the end of the string, if any) «$»