I am writing a code to read bounced emails from inbox. I am getting the body of the email like so:
$body = imap_body($conn, $i);
After I get the body string, I split it into an array with explode.
$bodyParts = explode(PHP_EOL, $body);
The bounced emails that I am concerned with, they all have a particular header set i.e. X-OBJ-ID. I can loop through $bodyParts to check if that particular header is set or not, but how do I get it's value if the header exists. Currently, the header string looks like this for those bounced emails which had that header set:
"X-OBJ-ID: 24\r"
So, basically my question is: How do I extract 24 from the above string?
Lookbehinds can be helpful in such cases
/(?<=X-OBJ-ID: )\d+/
(?<=X-OBJ-ID: ) look behind. Ensures that the digits is preceded by X-OBJ-ID:
\d+ Matches digits.
Regex Demo
Example
preg_match("/(?<=X-OBJ-ID: )\d+/", "X-OBJ-ID: 24\r", $matches);
print_r($matches)
=> Array (
[0] => 24
)
Try
$int = filter_var($str, FILTER_SANITIZE_NUMBER_INT);
or you can do it via regular expression
preg_replace("/[^0-9]/","",$string);
You could do something like so:
$str = "X-OBJ-ID: 24\r";
preg_match('X-OBJ-ID:\s+(\d+)', $str, $re);
print($re);
This should match your string and store the 24 within a capture group which will be then made accessible through $re.
try this code
preg_replace('/\D/', '', $str)
it removes all the non numeric characters from the string
My solution:
<?php
$string = '"X-OBJ-ID: 24\r"';
preg_match_all('^\X-OBJ-ID: (.*?)[$\\\r]+^', $string, $matches);
echo !empty($matches[1]) ? trim($matches[1][0]) : 'No matches found';
?>
See it working here http://viper-7.com/kuMyVh
Related
i want to make regex to detect this format image(numeric, string). ex: image(100, 'test').
i have tried this one, but just detect the image(numeric)
/image\((\d+)\)/
Any help with second parameter and the ,?
Also how i can get the second parameter?
You can try the following pattern:
/image\(\d+,\s*'.+?'\)/
I removed the capture group since it would be not needed if using the regex for validation only.
Demo
If you want to capture the number and text, then use capture groups:
$input = "code image(123, 'meh') more code";
if (preg_match("/image\((\d+),\s*'(.+?)'\)/", $input, $m)) {
echo "match";
}
$number = $m[1];
$text = $m[2];
Try this:
image\((\d+), '(.+?)'\)
The . matches anything and the rest is pretty much self-explanatory. Group 1 is your number, group 2 is the string.
You can try this one:
image\(\s*\d+\s*\,\s*'.*'\s*\)
I have a string contain emoji.
I want extract emoji's from that string,i'm using below code but it doesn't what i want.
$string = "π hello world π";
preg_match('/([0-9#][\x{20E3}])|[\x{00ae}\x{00a9}\x{203C}\x{2047}\x{2048}\x{2049}\x{3030}\x{303D}\x{2139}\x{2122}\x{3297}\x{3299}][\x{FE00}-\x{FEFF}]?|[\x{2190}-\x{21FF}][\x{FE00}-\x{FEFF}]?|[\x{2300}-\x{23FF}][\x{FE00}-\x{FEFF}]?|[\x{2460}-\x{24FF}][\x{FE00}-\x{FEFF}]?|[\x{25A0}-\x{25FF}][\x{FE00}-\x{FEFF}]?|[\x{2600}-\x{27BF}][\x{FE00}-\x{FEFF}]?|[\x{2900}-\x{297F}][\x{FE00}-\x{FEFF}]?|[\x{2B00}-\x{2BF0}][\x{FE00}-\x{FEFF}]?|[\x{1F000}-\x{1F6FF}][\x{FE00}-\x{FEFF}]?/u', $string, $emojis);
i want this:
$emojis = ["π", "π"];
but return this:
$emojis = ["π"]
and also if:
$string = "π
πβπΏ"
it return only first emoji
$emoji = ["π
"]
Try looking at preg_match_all function. preg_match stops looking after it finds the first match, which is why you're only ever getting the first emoji back.
Taken from this answer:
preg_match stops looking after the first match. preg_match_all, on the other hand, continues to look until it finishes processing the entire string. Once match is found, it uses the remainder of the string to try and apply another match.
http://php.net/manual/en/function.preg-match-all.php
So your code would become:
$string = "π hello world π";
preg_match_all('/([0-9#][\x{20E3}])|[\x{00ae}\x{00a9}\x{203C}\x{2047}\x{2048}\x{2049}\x{3030}\x{303D}\x{2139}\x{2122}\x{3297}\x{3299}][\x{FE00}-\x{FEFF}]?|[\x{2190}-\x{21FF}][\x{FE00}-\x{FEFF}]?|[\x{2300}-\x{23FF}][\x{FE00}-\x{FEFF}]?|[\x{2460}-\x{24FF}][\x{FE00}-\x{FEFF}]?|[\x{25A0}-\x{25FF}][\x{FE00}-\x{FEFF}]?|[\x{2600}-\x{27BF}][\x{FE00}-\x{FEFF}]?|[\x{2900}-\x{297F}][\x{FE00}-\x{FEFF}]?|[\x{2B00}-\x{2BF0}][\x{FE00}-\x{FEFF}]?|[\x{1F000}-\x{1F6FF}][\x{FE00}-\x{FEFF}]?/u', $string, $emojis);
print_r($emojis[0]); // Array ( [0] => π [1] => π )
I have a server application which looks up where the stress is in Russian words. The end user writes a word ΠΆΠ°ΠΆΠ΄Π°. The server downloads a page from another server which contains the stresses indicated with apostrophes for each case/declension like this ΠΆΠ°'ΠΆΠ΄Π°. I need to find that word in the downloaded page.
In Russian the stress is always written after a vowel. I've been using so far a regex that is a grouping of all possible combinations (ΠΆΠ°'ΠΆΠ΄Π°|ΠΆΠ°ΠΆΠ΄Π°'). Is there a more elegant solution using just a regex pattern instead of making a PHP script which creates all these combinations?
EDIT:
I have a word ΠΆΠ°ΠΆΠ΄Π°
The downloaded page contains the string ΠΆΠ°'ΠΆΠ΄Π°. (notice the
apostrophe, I do not before-hand know where the apostrophe in the
word is)
I want to match the word with apostrophe (ΠΆΠ°'ΠΆΠ΄Π°).
P.S.: So far I have a PHP script creating the string (ΠΆΠ°'ΠΆΠ΄Π°|ΠΆΠ°ΠΆΠ΄Π°') used in regex (apostrophe is only after vowels) which matches it. My goal is to get rid of this script and use just regex in case it's possible.
If I understand your question,
have these options (d'isorder|di'sorder|dis'order|diso'rder|disor'der|disord'er|disorde'r|disorderββ') and one of these is in the downloaded page and I need to find out which one it is
this may suit your needs:
<pre>
<?php
$s = "d'isorder|di'sorder|dis'order|diso'rder|disor'der|disord'er|disorde'r|disorder'|disorde'";
$s = explode("|",$s);
print_r($s);
$matches = preg_grep("#[aeiou]'#", $s);
print_r($matches);
running example: https://eval.in/207282
Uhm... Is this ok with you?
<?php
function find_stresses($word, $haystack) {
$pattern = preg_replace('/[aeiou]/', '\0\'?', $word);
$pattern = "/\b$pattern\b/";
// word = 'disorder', pattern = "diso'?rde'?r"
preg_match_all($pattern, $haystack, $matches);
return $matches[0];
}
$hay = "something diso'rder somethingelse";
find_stresses('disorder', $hay);
// => array(diso'rder)
You didn't specify if there can be more than one match, but if not, you could use preg_match instead of preg_match_all (faster). For example, in Italian language we have Γ ncora and ancΓ²ra :P
Obviously if you use preg_match, the result would be a string instead of an array.
Based, on your code, and the requirements that no function is called and disorder is excluded. I think this is what you want. I have added a test vector.
<pre>
<?php
// test code
$downloadedPage = "
there is some disorde'r
there is some disord'er in the example
there is some di'sorder in the example
there also' is some order in the example
there is some disorder in the example
there is some dso'rder in the example
";
$word = 'disorder';
preg_match_all("#".preg_replace("#[aeiou]#", "$0'?", $word)."#iu"
, $downloadedPage
, $result
);
print_r($result);
$result = preg_grep("#'#"
, $result[0]
);
print_r($result);
// the code you need
$word = 'also';
preg_match("#".preg_replace("#[aeiou]#", "$0'?", $word)."#iu"
, $downloadedPage
, $result
);
print_r($result);
$result = preg_grep("#'#"
, $result
);
print_r($result);
Working demo: https://eval.in/207312
I have this string:
a:3:{i:0;i:2;i:1;i:3;i:2;i:4;}
I want to get number between "a:" and ":{" that is "3".
I try to user substr and strpos but no success.
I'm newbie in regex , write this :
preg_match('/a:(.+?):{/', $v);
But its return me 1.
Thanks for any tips.
preg_match returns the number of matches, in your case 1 match.
To get the matches themselves, use the third parameter:
$matches = array();
preg_match(/'a:(\d+?):{/', $v, $matches);
That said, I think the string looks like a serialized array which you could deserialize with unserialize and then use count on the actual array (i.e. $a = count(unserialize($v));). Be careful with userprovided serialized strings though β¦
If you know that a: is always at the beginning of the string, the easiest way is:
$array = explode( ':', $string, 3 );
$number = $array[1];
You can use sscanfDocs to obtain the number from the string:
# Input:
$str = 'a:3:{i:0;i:2;i:1;i:3;i:2;i:4;}';
# Code:
sscanf($str, 'a:%d:', $number);
# Output:
echo $number; # 3
This is often more simple than using preg_match when you'd like to obtain a specific value from a string that follows a pattern.
preg_match() returns the number of times it finds a match, that's why. you need to add a third param. $matches in which it will store the matches.
You were not too far away with strpos() and substr()
$pos_start = strpos($str,'a:')+2;
$pos_end = strpos($str,':{')-2;
$result = substr($str,$pos_start,$pos_end);
preg_match only checks for appearance, it doesn't return any string.
<?php
$url = 'here i give a url';
$raw = file_get_contents($url);
preg_match('/\w(\d*).*?\$/',$raw,$matches);
echo $matches;
?>
in a given external website I need the closest number to the first appearance of a symbol here the symbol is $
this is what I tried for now I just get "array" printed
Am I interpreting your question correctly if you, given the following input:
<div>
<span>12.92$</span>
<span>24.82$</span>
</div>
want to get back 12.92$? I.e. you want the first occurrence of an amount of money from a web site?
If so, try the following:
// Will find any number on the form xyz.abc.
// Will NOT cope with formatting such as 12 523.25 or 12,523.25
$regex = '/(\d+(:?.\d+)?) *([$])/'
preg_match($regex, $website, $matches);
//matches[0] => 123.45$
//matches[1] => 123.45
//matches[2] => $
Another, more ambitious try (Which could fail more often) would be:
// Will find any number on the form xyz.abc.
// Attempts to cope with formatting such as 12 523.25 or 12,523.25
$regex = '/(\d{1,3}(:?[, ]?\d{3})*(:?.\d+)?) *([$])/'
preg_match($regex, $website, $matches);
//matches[0] => 12 233.45$
//matches[1] => 12 233.45
//matches[2] => $
if you get array printed > try echo $matches[0]; or echo $matches[1];
// update
// test2.php
lkadf $ lksajdf;
// test.php
$url = 'test2.php';
$raw = file_get_contents($url);
preg_match('/\w(\d*).*?\$/',$raw,$matches);
echo $matches[0]; ?>
Will output:
lkadf $ (the first part).
Use preg match with $matches[1], but you need to change your regex to
preg_match('/\w(\d+).*?\$/',$raw,$matches);
The * matches zero or more times, when really you want at least one digit. Change it to + so you match one or more.
$regex = '/([$])* (\d+(:?.\d+)?) /' ;
preg_match($regex, $str, $matches);
it works I just switched the sides for $199 !
now I need also an option to get only the second apearance:
code .....
$199 ......
....
$299
....
matches[2] should print 299