I have a list of patterns: $allowedTLDS = array(".de", ".at", ".ch", ".org", ".com", ".eu");
Now I a have string like 30212622mail#myname.com and I want to cut everything after the .com away to get the plain mail address.
I've written this function so far:
function extract_correct_email_address($string){
$allowedTLDS = array(".de", ".at", ".ch", ".org", ".com", ".eu");
$foundMatch = false;
$foundTLD = "";
foreach ($allowedTLDS as $tld) {
if (strpos($string, $tld) !== FALSE) {
//found a match
$foundMatch = true;
$foundTLD = $tld;
break 1;
}
}
if($foundMatch){
$str = strtok( $string, $foundTLD).$foundTLD;
return $str;
}
return NULL;
}
Now I have for example these addresses where I get the output on the right side:
input: info#meq.dewww.meq.de
output: info#meq.de
expected: info#meq.de (this one is correct)
input: info#cool-name.de
output: info#co.de
expected: info#cool-name.de
input: something-cool123#nice.decool123.nice.de
expected: something-cool123#nice.de
I hope it is understandable what I want to archive. What am I doing something wrong in the function?
Do it with this nice regular expression - you just can add TLDs:
function extract_correct_email_address($string){
// pattern do match email addresses
$pattern = '/[a-z0-9_\-\+]+#[a-z0-9\-]+\.(de|at|ch|org|com|eu)(?:\.[a-z]{2})?/i';
preg_match($pattern, $string, $matches);
if(count($matches[0])<1) {
return null;
}
return $matches[0];
}
// example string
$string = 'fdsaf das D hansi#test.dewww.lol.net franz#gibts.atdasf dasf asd';
var_dump(extract_correct_email_address($string));
Result:
string(15) "hansi#test.de"
Of course you can extend this to use for extracting multiple emails. Instead of matches[0] check all matches instead.
You can try this. I'm only inspecting the part after the "#". There could be the case somebody ist named "miller.denis#bla.com", so that .de would also be parsed
public function parseMail(){
$string = "something-cool123#nice.decool123.nice.de";
$allowedTLDS = array(".de", ".at", ".ch", ".org", ".com", ".eu");
$mail = explode("#", $string);
foreach ($allowedTLDS as $tld) {
if (strpos($mail[1], $tld) !== FALSE) {
//found a match
$foundTLD = $tld;
dump($mail[1]);
$str = strtok($mail[1], $foundTLD);
return $mail[0].'#'.$str.$foundTLD;
}
}
return NULL;
}
Try using regexp instead:
preg_replace('/(\.(de|at|ch|org|com|eu)).*$/', '\1', $email);
Just add your $allowedTLDS inside the parenthesis.
Examples
$ php -r "echo preg_replace('/(\.(de|at|ch|org|com|eu)).*$/', '\1', 'info#meq.dewww.meq.de') . PHP_EOL;"
> info#meq.de
$ php -r "echo preg_replace('/(\.(de|at|ch|org|com|eu)).*$/', '\1', 'info#cool-name.de') . PHP_EOL;"
> info#cool-name.de
$ php -r "echo preg_replace('/(\.(de|at|ch|org|com|eu)).*$/', '\1', 'something-cool123#nice.decool123.nice.de ') . PHP_EOL;"
> something-cool123#nice.de
Related
I am using a WordPress plugin named Acronyms (https://wordpress.org/plugins/acronyms/). This plugin replaces acronyms with their description. It uses a PHP PREG_REPLACE function.
The issue is that it replaces the acronyms contained in a <pre> tag, which I use to present a source code.
Could you modify this expression so that it won't replace acronyms contained inside <pre> tags (not only directly, but in any moment)? Is it possible?
The PHP code is:
$text = preg_replace(
"|(?!<[^<>]*?)(?<![?.&])\b$acronym\b(?!:)(?![^<>]*?>)|msU"
, "<acronym title=\"$fulltext\">$acronym</acronym>"
, $text
);
You can use a PCRE SKIP/FAIL regex trick (also works in PHP) to tell the regex engine to only match something if it is not inside some delimiters:
(?s)<pre[^<]*>.*?<\/pre>(*SKIP)(*F)|\b$acronym\b
This means: skip all substrings starting with <pre> and ending with </pre>, and only then match $acronym as a whole word.
See demo on regex101.com
Here is a sample PHP demo:
<?php
$acronym = "ASCII";
$fulltext = "American Standard Code for Information Interchange";
$re = "/(?s)<pre[^<]*>.*?<\\/pre>(*SKIP)(*F)|\\b$acronym\\b/";
$str = "<pre>ASCII\nSometext\nMoretext</pre>More text \nASCII\nMore text<pre>More\nlines\nASCII\nlines</pre>";
$subst = "<acronym title=\"$fulltext\">$acronym</acronym>";
$result = preg_replace($re, $subst, $str);
echo $result;
Output:
<pre>ASCII</pre><acronym title="American Standard Code for Information Interchange">ASCII</acronym><pre>ASCII</pre>
It is also possible to use preg_split and keep the code block as a group, only replace the non-code block part then combine it back as a complete string:
function replace($s) {
return str_replace('"', '"', $s); // do something with `$s`
}
$text = 'Your text goes here...';
$parts = preg_split('#(<\/?[-:\w]+(?:\s[^<>]+?)?>)#', $text, null, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
$text = "";
$x = 0;
foreach ($parts as $v) {
if (trim($v) === "") {
$text .= $v;
continue;
}
if ($v[0] === '<' && substr($v, -1) === '>') {
if (preg_match('#^<(\/)?(?:code|pre)(?:\s[^<>]+?)?>$#', $v, $m)) {
$x = isset($m[1]) && $m[1] === '/' ? 0 : 1;
}
$text .= $v; // this is a HTML tag…
} else {
$text .= !$x ? replace($v) : $v; // process or skip…
}
}
return $text;
Taken from here.
I am using a WordPress plugin named Acronyms (https://wordpress.org/plugins/acronyms/). This plugin replaces acronyms with their description. It uses a PHP PREG_REPLACE function.
The issue is that it replaces the acronyms contained in a <pre> tag, which I use to present a source code.
Could you modify this expression so that it won't replace acronyms contained inside <pre> tags (not only directly, but in any moment)? Is it possible?
The PHP code is:
$text = preg_replace(
"|(?!<[^<>]*?)(?<![?.&])\b$acronym\b(?!:)(?![^<>]*?>)|msU"
, "<acronym title=\"$fulltext\">$acronym</acronym>"
, $text
);
You can use a PCRE SKIP/FAIL regex trick (also works in PHP) to tell the regex engine to only match something if it is not inside some delimiters:
(?s)<pre[^<]*>.*?<\/pre>(*SKIP)(*F)|\b$acronym\b
This means: skip all substrings starting with <pre> and ending with </pre>, and only then match $acronym as a whole word.
See demo on regex101.com
Here is a sample PHP demo:
<?php
$acronym = "ASCII";
$fulltext = "American Standard Code for Information Interchange";
$re = "/(?s)<pre[^<]*>.*?<\\/pre>(*SKIP)(*F)|\\b$acronym\\b/";
$str = "<pre>ASCII\nSometext\nMoretext</pre>More text \nASCII\nMore text<pre>More\nlines\nASCII\nlines</pre>";
$subst = "<acronym title=\"$fulltext\">$acronym</acronym>";
$result = preg_replace($re, $subst, $str);
echo $result;
Output:
<pre>ASCII</pre><acronym title="American Standard Code for Information Interchange">ASCII</acronym><pre>ASCII</pre>
It is also possible to use preg_split and keep the code block as a group, only replace the non-code block part then combine it back as a complete string:
function replace($s) {
return str_replace('"', '"', $s); // do something with `$s`
}
$text = 'Your text goes here...';
$parts = preg_split('#(<\/?[-:\w]+(?:\s[^<>]+?)?>)#', $text, null, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
$text = "";
$x = 0;
foreach ($parts as $v) {
if (trim($v) === "") {
$text .= $v;
continue;
}
if ($v[0] === '<' && substr($v, -1) === '>') {
if (preg_match('#^<(\/)?(?:code|pre)(?:\s[^<>]+?)?>$#', $v, $m)) {
$x = isset($m[1]) && $m[1] === '/' ? 0 : 1;
}
$text .= $v; // this is a HTML tag…
} else {
$text .= !$x ? replace($v) : $v; // process or skip…
}
}
return $text;
Taken from here.
In JS you can do:
var chs = "[](){}";
var str = "hello[asd]}";
if (str.indexOf(chs) != -1) {
alert("The string can't contain the following characters: " + chs.split("").join(", "));
}
How can you do this in PHP (replacing alert with echo)?
I do not want to use a regex for the simplicity of what I think.
EDIT:
What I've tried:
<?php
$chs = /[\[\]\(\)\{\}]/;
$str = "hella[asd]}";
if (preg_match(chs, str)) {
echo ("The string can't contain the following characters: " . $chs);
}
?>
Which obviously doesn't work and idk how to do it without regex.
In php you should do this:
$string = "Sometring[inside]";
if(preg_match("/(?:\[|\]|\(|\)|\{|\})+/", $string) === FALSE)
{
echo "it does not contain.";
}
else
{
echo "it contains";
}
The regex says check to see any of the characters are inside the string. you can read more about it here:
http://en.wikipedia.org/wiki/Regular_expression
And about PHP preg_match() :
http://php.net/manual/en/function.preg-match.php
Update:
I have written an updated regex for this, which captures the letters inside:
$rule = "/(?:(?:\[([\s\da-zA-Z]+)\])|\{([\d\sa-zA-Z]+)\})|\(([\d\sa-zA-Z]+)\)+/"
$matches = array();
if(preg_match($rule, $string, $matches) === true)
{
echo "It contains: " . $matches[0];
}
It returnes something like this:
It contains: [inside]
I have changed the regex only which becomes:
$rule = "/(?:(?:(\[)(?:[\s\da-zA-Z]+)(\]))|(\{)(?:[\d\sa-zA-Z]+)(\}))|(\()(?:[\d\sa-zA-Z]+)(\))+/";
// it returns an array of occurred illegal characters
It now returns [] for this "I am [good]"
Why not you try str_replace.
<?php
$search = array('[',']','{','}','(',')');
$replace = array('');
$content = 'hella[asd]}';
echo str_replace($search, $replace, $content);
//Output => hellaasd
?>
Instead of regex we can use string replace for this case.
here is a simple solution without using regex:
$chs = array("[", "]", "(", ")", "{", "}");
$string = "hello[asd]}";
$err = array();
foreach($chs AS $key => $val)
{
if(strpos($string, $val) !== false) $err[]= $val;
}
if(count($err) > 0)
{
echo "The string can't contain the following characters: " . implode(", ", $err);
}
Does anyone know how to get the int from this preg_match? It's only showing me the URI.
$uri = "/user/view/2";
$pattern = "/user/view/[0-9]+";
if(preg_match('#^' . $pattern . '$#', $uri, $matched)) {
print_r($matched);
}
else {
echo "No match!";
}
You have no capture group in your pattern. Change:
$pattern = "/user/view/[0-9]+";
To:
$pattern = "/user/view/([0-9]+)";
And it will be in $matched[1].
You can use T-Regx and go
pattern('^/user/view/[0-9]+$')->match($uri)
->forFirst(function (Match $match) {
$int = $match->group(1);
print_r($int);
})
->orReturn("No match!");
And you don't have to delimiter it with #!
Okay, let's say this is a line
v1=something;v2=something2;
how to get v1 value (something) starting from = and break at ; and same to be done with v2 by calling it (v1)
function getVal($name){
// some code to start grabbing from = and end by ;
}
when i call
getVal("v1");
it should return "something"
This will work
v1=([^;]*)
The match will be in group 1
Just replace v1 in the regex with the key you want to lookup
if (preg_match('/v1=([^;]*)/', $subject, $regs)) {
$result = $regs[1];
} else {
$result = "";
}
If I understand your question, then I think this is what you are looking for:
$line = "v1=something;v2=something2;";
function getVal($name, $line){
preg_match('/'.$name.'=([^;]*)/', $line, $matches);
return $matches[1];
}
echo getVal("v1", $line);
v(?:\d*)=(\w;+)
That will match all v (with digits or no digits after it) and then the match group will be after the = sign. It is group 1.
You are obliged to sent the line to your function (or you can be dirty and use it as global).
So, your function can be something like that :
<?php
function getVal($name, $line){
// some code to start grabbing from = and end by ;
preg_match('#;?' . $name . '=([^;]+);?#', $line, $aMatches);
if(isset($aMatches[1])) {
return $aMatches[1];
}
return false;
}
$line = 'v1=something;v2=something2';
$v1 = getVal('v1',$line);
echo $v1;
?>
Use this Function:
function getVal($name, $line){
preg_match("/{$name}=(.+);(v(\d+)=|$)/U", $line, $matches);
$matches = $matches[0];
$matches = preg_replace("/{$name}=/","",$matches);
$matches = preg_replace("/;v(\d+)=/","",$matches);
return $matches;
}
this will give you exact answer.
Tested and working.:)