Question about REGEX extracting text beetween - php

I'm trying in PHP to get something like this:
$mail = "fakemail#le.mail.uk.test";
$rep = "le.mail";
I tried like this:
function test($mail) {
$pattern = '/^([\w-]+(?:\.[\w-]+)*)#((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/';
preg_match($pattern, $mail, $matches);
echo $matches[2] . "\n";
}
test("fakemail#le.mail.uk");
// result = le.mail
but if i have another . in my mail it's broken
function test($mail) {
$pattern = '/^([\w-]+(?:\.[\w-]+)*)#((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/';
preg_match($pattern, $mail, $matches);
echo $matches[2] . "\n";
}
test("fakemail#le.mail.uk.test.test");
// result = le.mail.uk.test.test.test
// whatIwant = le.mail
or I just want all character between # and until the next ..
I think I have to do a loop with an if but I'm not sure if it's possible
with only regex.

A php way without REGEX, using implode() and explode()
<?php
$sep = '.';
$str1 = 'email#test.com.robot';
$str2 = 'email#test.fr.uk.robot';
$get1 = explode($sep,explode('#',$str1)[1]);
$get2 = explode($sep,explode('#',$str2)[1]);
echo implode($sep,[$get1[0],$get1[1]]);
echo PHP_EOL;
echo implode($sep,[$get2[0],$get2[1]]);
?>
Output:
test.com
test.fr
DEMO: https://3v4l.org/hJu52

Related

How to find out if there is any redundant word in string in php?

I need to find out if there are any redundant words in string or not .Is there any function that can provide me result in true/false.
Example:
$str = "Hey! How are you";
$result = redundant($str);
echo $result ; //result should be 0 or false
But for :
$str = "Hey! How are are you";
$result = redundant($str);
echo $result ; //result should be 1 or true
Thank you
You could use explode to generate an array containing all words in your string:
$array = explode(" ", $str);
Than you could prove if the arrays contains duplicates with the function provided in this answer:
https://stackoverflow.com/a/3145660/5420511
I think this is what you are trying to do, this splits on punctuation marks or whitespaces. The commented out lines can be used if you want the duplicated words:
$str = "Hey! How are are you?";
$output = redundant($str);
echo $output;
function redundant($string){
$words = preg_split('/[[:punct:]\s]+/', $string);
if(max(array_count_values($words)) > 1) {
return 1;
} else {
return 0;
}
//foreach(array_count_values($words) as $word => $count) {
// if($count > 1) {
// echo '"' . $word . '" is in the string more than once';
// }
//}
}
References:
http://php.net/manual/en/function.array-count-values.php
http://php.net/manual/en/function.max.php
http://php.net/manual/en/function.preg-split.php
Regex Demo: https://regex101.com/r/iH0eA6/1

PHP's preg_replace returns null when replacing underscores with white spaces

I have a webpage which includes a hyperlink as follows:
$name = "Hello World";
echo "<a href='page.php?name='". preg_replace(" ", "_", $name) "'> bla bla </a>"
This generates the following link successfully:
...page.php?name=Hello_World
in my page.php I try to reverse the operation:
if($_SERVER[REQUEST_METHOD] == "GET"){
$name = $_GET['name'];
//testing if the problem is with GET
echo $name;
//now here's the problem:
$string = preg_replace("_", " ", $name);
echo $string;
}
the $name echoes correctly but the $string is always null
I've tried all possible combinations like ~~ and // and [_] and \s and using $_GET directly like:
preg_replace("_", " ", $_GET['name']);
none of them worked.
This problem has burned most of my day.
Any help is appreciated.
preg_replace accepts a regular expression as it's first arguments. Neither " " nor "_" are valid regular expressions.
In this case you can use str_replace.
The preg_replace syntax is incorrect as pointed by #Halcyon, the following is correct:
$string = preg_replace('/_/', ' ', $name);
But for such a simple find/replace you can use str_replace instead:
$string = str_replace("_", " ", $name);
echo $string;
you can create a function like sefurl
function makesefurl($url=''){
$s=trim($url);
$tr = array('ş','Ş','ı','I','İ','ğ','Ğ','ü','Ü','ö','Ö','Ç','ç','(',')','/',':',',');
$eng = array('s','s','i','i','i','g','g','u','u','o','o','c','c','','','-','-','');
$s = str_replace($tr,$eng,$s);
$s = preg_replace('/&amp;amp;amp;amp;amp;amp;amp;amp;.+?;/', '', $s);
$s = preg_replace('/\s+/', '-', $s);
$s = preg_replace('|-+|', '-', $s);
$s = preg_replace('/#/', '', $s);
$s = str_replace('.', '.', $s);
$s = trim($s, '-');
$s = htmlspecialchars(strip_tags(urldecode(addslashes(stripslashes(stripslashes(trim(htmlspecialchars_decode($s))))))));
}
echo "<a href='page.php?name='". makesefurl($name) "'> bla bla </a>";
and than you can convert it to before makesefurl function all you need to create another functin like decoder or encoder html command

What is the simplest way to split this string using PHP?

I have the below string in PHP.
:guest!lbjpewueqi#AF8A326D.E0B4A40D.F85DC93A.IP
I need to create these variables from the string:
$nick = guest
$user = lbjpewueqi
$host = AF8A326D.E0B4A40D.F85DC93A.IP
What is the best function to use to do this?
Ideally I would like to create some sort of function so I can pass to it the string and what part I want returned.
For example:
$string = "guest!lbjpewueqi#AF8A326D.E0B4A40D.F85DC93A.IP";
echo stringToPart($string, nick);
guest
echo stringToPart($string, nick);
lbjpewueqi
echo stringToPart($string, host);
AF8A326D.E0B4A40D.F85DC93A.IP
Another version:
function stringToPart($string, $part) {
if (preg_match('/^:(.*)!(.*)#(.*)/', $string, $matches)) {
$nick = $matches[1];
$user = $matches[2];
$host = $matches[3];
return isset($$part) ? $$part : null;
}
}
More strict than preg_split solutions - it checks separators order.
Maybe this code may helpful for you
$p = '/[:!#]/';
$s = ":guest!lbjpewueqi#AF8A326D.E0B4A40D.F85DC93A.IP";
print_r( preg_split( $p, $s ), 1 );
You can declare a function like this:
$s = ":guest!lbjpewueqi#AF8A326D.E0B4A40D.F85DC93A.IP";
function stringToPart($str, $part) {
$pat['nick'] = '/:(.*)!/';
$pat['user'] = '/.*!(.*)#/';
$pat['host'] = '/#(.*)/';
preg_match($pat[$part], $str, $m);
if (count($m) > 1) return $m[1];
return null;
}
echo stringToPart($s,'nick')."\n";
echo stringToPart($s,'user')."\n";
echo stringToPart($s,'host')."\n";
The below should do what you're looking for.
$pattern = "/[:!#]/";
$subject = ":guest!lbjpewueqi#AF8A326D.E0B4A40D.F85DC93A.IP";
print_r(preg_split($pattern, $subject));
The pattern is specifying what characters to split on so you could in theory have any amount of characters here if there were other instance you needed to account for different strings being passed in.
To return the values instead of just printing then to the screen use this:
$pattern = "/[:!#]/";
$subject = ":guest!lbjpewueqi#AF8A326D.E0B4A40D.F85DC93A.IP";
$result = preg_split($pattern, $subject));
$nick = $result[1];
$user = $result[2];
$host = $result[3];
stringToPart(':guest!lbjpewueqi#AF8A326D.E0B4A40D.F85DC93A.IP','nick');
function stringToPart($string, $type){
$result['nick']= substr($string,strpos($string,':')+1,(strpos($string,'!')-strpos($string,':')-1));
$result['user']= substr($string,strpos($string,'!')+1,(strpos($string,'#')-strpos($string,'!')-1));
$result['host']= substr($string,strpos($string,'#')+1);
return $result[$type];
}
<?php
function stringToPart($string, $key)
{
$matches = null;
$returnValue = preg_match('/:(?P<nick>[^!]*)!(?P<user>.*?)#(?P<host>.*)/', $string, $matches);
if (isset($matches[$key]))
{
return $matches[$key];
} else
{
return NULL;
}
}
$string = ':guest!lbjpewueqi#AF8A326D.E0B4A40D.F85DC93A.IP';
echo stringToPart($string, "nick");
echo "<br />";
echo stringToPart($string, "user");
echo "<br />";
echo stringToPart($string, "host");
echo "<br />";
?>

Preg Replace in PHP for Heading Tags

I have a markdown text content which I have to replace without using library functions.So I used preg replace for this.It works fine for some cases.For cases like heading
for eg Heading
=======
should be converted to <h1>Heading</h1> and also
##Sub heading should be converted to <h2>Sub heading</h2>
###Sub heading should be converted to <h3>Sub heading</h3>
I have tried
$text = preg_replace('/##(.+?)\n/s', '<h2>$1</h2>', $text);
The above code works but I need to have count of hash symbol and based on that I have to assign heading tags.
Anyone help me please....
Try using preg_replace_callback.
Something like this -
$regex = '/(#+)(.+?)\n/s';
$line = "##Sub heading\n ###sub-sub heading\n";
$line = preg_replace_callback(
$regex,
function($matches){
$h_num = strlen($matches[1]);
return "<h$h_num>".$matches[2]."</h$h_num>";
},
$line
);
echo $line;
The output would be something like this -
<h2>Sub heading</h2> <h3>sub-sub heading</h3>
EDIT
For the combined problem of using = for headings and # for sub-headings, the regex gets a bit more complicated, but the principle remains the same using preg_replace_callback.
Try this -
$regex = '/(?:(#+)(.+?)\n)|(?:(.+?)\n\s*=+\s*\n)/';
$line = "Heading\n=======\n##Sub heading\n ###sub-sub heading\n";
$line = preg_replace_callback(
$regex,
function($matches){
//var_dump($matches);
if($matches[1] == ""){
return "<h1>".$matches[3]."</h1>";
}else{
$h_num = strlen($matches[1]);
return "<h$h_num>".$matches[2]."</h$h_num>";
}
},
$line
);
echo $line;
Whose Output is -
<h1>Heading</h1><h2>Sub heading</h2> <h3>sub-sub heading</h3>
Do a preg_match_all like this:
$string = "#####asdsadsad";
preg_match_all("/^#/", $string, $matches);
var_dump ($matches);
And based on count of matches you can do whatever you want.
Or, use the preg_replace_callback function.
$input = "#This is my text";
$pattern = '/^(#+)(.+)/';
$mytext = preg_replace_callback($pattern, 'parseHashes', $input);
var_dump($mytext);
function parseHashes($input) {
var_dump($input);
$matches = array();
preg_match_all('/(#)/', $input[1], $matches);
var_dump($matches[0]);
var_dump(count($matches[0]));
$cnt = count($matches[0]);
if ($cnt <= 6 && $cnt > 0) {
return '<h' . $cnt . ' class="if you want class here">' . $input[2] . '</h' . $cnt . '>';
} else {
//This is not a valid h tag. Do whatever you want.
return false;
}
}

complex regex with preg_replace, replace a word not inside [ and ]

I'm having trouble finding a correct regex to achieve what I want.
I have a sentence like that :
Hi, my name is Stan, you are welcome, hello.
and I would like to transform it like that :
[hi|hello|welcome], my name is [stan|jack] you are [hi|hello|welcome] [hi|hello|welcome].
Right now my regex is half working, because somes words are not replaced, and those replaced are deleting some characters
Here is my test code
<?php
$test = 'Hi, my name is Stan, you are welcome, hello.';
$words = array(
array('hi', 'hello', 'welcome'),
array('stan', 'jack'),
);
$result = $test;
foreach ($words as $group) {
if (count($group) > 0) {
$replacement = '[' . implode('|', $group) . ']';
foreach ($group as $word) {
$result = preg_replace('#([^\[])' . $word . '([^\]])#i', $replacement, $result);
}
}
}
echo $test . '<br />' . $result;
Any help will be appreciated
The regex you are using is overcomplicated. You simply need to use a regex substitution using regular brackets ():
<?php
$test = 'Hi, my name is Stan, you are welcome, hello.';
$words = array(
array('hi', 'hello', 'welcome'),
array('stan', 'jack'),
);
$result = $test;
foreach ($words as $group) {
if (count($group) > 0) {
$imploded = implode('|', $group);
$replacement = "[$imploded]";
$search = "($imploded)";
$result = preg_replace("/$search/i", $replacement, $result);
}
}
echo $test . '<br />' . $result;
Your regular expression:
'#([^\[])' . $word . '([^\]])#i'
matches one character before and after $word as well. And as they do, they replace it. So your replacement string needs to reference these parts, too:
'$1' . $replacement . '$2'
Demo
preg_replace supports array as parameter. No need to iterate with a loop.
$s = array("/(hi|hello|welcome)/i", "/(stan|jack)/i");
$r = array("[hi|hello|welcome]", "[stan|jack]");
preg_replace($s, $r, $str);
or dynamically
$test = 'Hi, my name is Stan, you are welcome, hello.';
$s = array("hi|hello|welcome", "stan|jack");
$r = array_map(create_function('$a','return "[$a]";'), $s);
$s = array_map(create_function('$a','return "/($a)/i";'), $s);
echo preg_replace($s, $r, $str);
//[hi|hello|welcome], my name is [stan|jack], you are [hi|hello|welcome], [hi|hello|welcome].

Categories