I am using preg_replace or str_replace in PHP to replace all the domain name including www
$string = ' https://example.com, https://www.example.com, https://subdomain.example.com ';
$olddomain= "example.com";
$newdomain = "stackoverflow.com";
$output = str_replace($olddomain, $newdomain, $string);
$output = preg_replace('#(www[.])?[.]' . $olddomain. '#', $newdomain, $body);
echo $output;
My expectation:
https://example.com -> https://stackoverflow.com
https://www.example.com -> https://stackoverflow.com
https://subdomain.example.com -> https://subdomain.example.com
preg_replace with regex.
$string = ' https://example.com, https://www.example.com, https://subdomain.example.com ';
$olddomain= "example.com";
$newdomain = "stackoverflow.com";
$output = preg_replace('#(https://(www\.)?)' . $olddomain. '#', '$1' . $newdomain, $string);
echo $output;
Output :
https://stackoverflow.com, https://www.stackoverflow.com, https://subdomain.example.com
No need for a regex, just pass the www. with the other change in into str_replace(). Remember str_replace() accepts an array of things to "change from" and "change to".
$string = ' https://example.com, https://www.example.com, https://subdomain.example.com ';
$olddomain = ["example.com",'www.'];
$newdomain = ["stackoverflow.com", ''];
$output = str_replace($olddomain, $newdomain, $string);
echo $output;
RESULT
https://stackoverflow.com, https://stackoverflow.com, https://subdomain.stackoverflow.com
Without using Regex
$string = ' https://example.com, https://www.example.com, https://subdomain.example.com ';
$olddomain= "example.com";
$newdomain = "stackoverflow.com";
$parts = explode(",", $string);
$new_parts = [];
foreach ($parts as $part) {
$new_parts[] = str_replace(['https://', 'http://', $olddomain], ['https://', 'http://', $newdomain], $part);
}
$output = implode(",", $new_parts);
echo $output;
Return
https://stackoverflow.com, https://www.stackoverflow.com, https://subdomain.example.com
With Array and Regex
$string = ' https://example.com, https://www.example.com, https://subdomain.example.com ';
$olddomain = ["example.com", 'www\.'];
$newdomain = ["stackoverflow.com", ''];
$output = preg_replace('#https://(' . implode('|', $olddomain) . ')#', 'https://' . $newdomain[0], $string);
$output = preg_replace('#(' . $olddomain[1] . ')#', $newdomain[1], $output);
echo $output;
Related
I have this string 45.142.34.3920:8945:userq:passwdwhat I want is I need to separate the proxy address and the port and it's username and pasword. So it should look like 45.142.34.3920:8945 and userq:passwd
Would that help to get you started?
$string = '45.142.34.3920:8945:userq:passwd';
$parts = explode(':', $string);
$host = $parts[0] . ':' . $parts[1];
$user = $parts[2] . ':' . $parts[3];
echo $host . PHP_EOL;
echo $user . PHP_EOL;
I have an input field in which users can specify a pattern for replacements.
But I want to allow them to leave it empty, and treat it like "pattern can be anything". Please remember the string ($subject) can be empty or not empty!
I tried using ".*" for this but it writes a double output. What can I use instead?
An empty pattern is just one of many possible patterns so I prefer to have a regex for it even though I can just do if (empty($pattern)) echo $replacement;.
<?php
echo '<ol>';
echo '<li><ol>';
$pattern = '';
$replacement = 'Sample output';
$subject = 'Foo bar';
echo '<li>' . preg_replace('/' . $pattern . '/', $replacement, $subject);
$pattern = '';
$replacement = 'Sample output';
$subject = '';
echo '<li>' . preg_replace('/' . $pattern . '/', $replacement, $subject);
echo '</ol><li><ol>';
$pattern = '';
if (empty($pattern))
$pattern = '.*';
$replacement = 'Sample output';
$subject = 'Foo bar';
echo '<li>' . preg_replace('/' . $pattern . '/', $replacement, $subject);
$pattern = '';
if (empty($pattern))
$pattern = '.*';
$replacement = 'Sample output';
$subject = '';
echo '<li>' . preg_replace('/' . $pattern . '/', $replacement, $subject);
echo '</ol><li><ol>';
$pattern = '';
if (empty($pattern))
$pattern = '.+';
$replacement = 'Sample output';
$subject = 'Foo bar';
echo '<li>' . preg_replace('/' . $pattern . '/', $replacement, $subject);
$pattern = '';
if (empty($pattern))
$pattern = '.+';
$replacement = 'Sample output';
$subject = '';
echo '<li>' . preg_replace('/' . $pattern . '/', $replacement, $subject);
echo '</ol><li><ol>';
$pattern = '';
if (empty($pattern))
$pattern = '$^';
$replacement = 'Sample output';
$subject = 'Foo bar';
echo '<li>' . preg_replace('/' . $pattern . '/', $replacement, $subject);
$pattern = '';
if (empty($pattern))
$pattern = '$^';
$replacement = 'Sample output';
$subject = '';
echo '<li>' . preg_replace('/' . $pattern . '/', $replacement, $subject);
echo '</ol><li><ol>';
$pattern = '';
if (empty($pattern))
$pattern = '(?:)';
$replacement = 'Sample output';
$subject = 'Foo bar';
echo '<li>' . preg_replace('/' . $pattern . '/', $replacement, $subject);
$pattern = '';
if (empty($pattern))
$pattern = '(?:)';
$replacement = 'Sample output';
$subject = '';
echo '<li>' . preg_replace('/' . $pattern . '/', $replacement, $subject);
echo '</ol><li><ol>';
$pattern = '';
if (empty($pattern))
$pattern = '(?=a)o';
$replacement = 'Sample output';
$subject = 'Foo bar';
echo '<li>' . preg_replace('/' . $pattern . '/', $replacement, $subject);
$pattern = '';
if (empty($pattern))
$pattern = '(?=a)o';
$replacement = 'Sample output';
$subject = '';
echo '<li>' . preg_replace('/' . $pattern . '/', $replacement, $subject);
echo '</ol><li><ol>';
$pattern = '';
if (empty($pattern))
$pattern = '.\A';
$replacement = 'Sample output';
$subject = 'Foo bar';
echo '<li>' . preg_replace('/' . $pattern . '/', $replacement, $subject);
$pattern = '';
if (empty($pattern))
$pattern = '.\A';
$replacement = 'Sample output';
$subject = '';
echo '<li>' . preg_replace('/' . $pattern . '/', $replacement, $subject);
echo '</ol><li><ol>';
$pattern = '';
if (empty($pattern))
$pattern = '\z.';
$replacement = 'Sample output';
$subject = 'Foo bar';
echo '<li>' . preg_replace('/' . $pattern . '/', $replacement, $subject);
$pattern = '';
if (empty($pattern))
$pattern = '\z.';
$replacement = 'Sample output';
$subject = '';
echo '<li>' . preg_replace('/' . $pattern . '/', $replacement, $subject);
echo '</ol><li><ol>';
$pattern = '';
if (empty($pattern))
$pattern = '(?!)';
$replacement = 'Sample output';
$subject = 'Foo bar';
echo '<li>' . preg_replace('/' . $pattern . '/', $replacement, $subject);
$pattern = '';
if (empty($pattern))
$pattern = '(?!)';
$replacement = 'Sample output';
$subject = '';
echo '<li>' . preg_replace('/' . $pattern . '/', $replacement, $subject);
?>
The needed output (for empty and non empty strings) should be:
Sample Output
Sample Output
As you can see below, the output is never like that:
Sample outputFSample outputoSample outputoSample output Sample outputbSample outputaSample outputrSample outputSample outputSample outputSample outputSample outputSample outputFoo barSample outputSample outputFSample outputoSample outputoSample output Sample outputbSample outputaSample outputrSample outputSample outputFoo barFoo barFoo barFoo bar
The replacement gets doubled because preg_replace replaces all match occurrences in the string, and .* pattern is capable of matching empty strings, and it does match the whole string first, and then - it is PCRE feature - allows the next match right at the end of the string. See preg_replace double replacement.
In your case, the solution is using both start of string (^ or \A) and end of string ($ or \z) anchors:
'/\A.*\z/s'
'/^.*$/s'
This way, you will always match a string, be it empty or not, once.
So i'm creating a simple function to mask phone numbers. My phone numbers have a 9 digits and i want preg_replace them with a given mask like 2-2-2-1-2 or 3-2-2-2 and etc.
I tried this:
$mask = explode('-', '3-2-2-2');
$pattern = '';
$replace = '';
foreach ($mask as $key => $value) {
if ($key == 0) {
$pattern = '/\(?(\d{' . $value . '})\)?[- ]';
$replace = '$' . ++$key . '-';
continue;
}
if ($key == count($mask) - 1) {
$pattern .= '?(\d{' . $value . '})/';
$replace .= '$' . ++$key;
break;
}
$pattern .= '?(\d{' . $value . '})[- ]';
$replace .= '$' . ++$key . '-';
}
return preg_replace($pattern, $replace, '902000810');
and the result is 902-00-08-10. Sometimes getting error preg_replace(): No ending delimiter '/' found. How can i refactor this to not getting errors?
Assuming:
$num = '902000810';
$mask = explode('-', '3-2-2-2');
There're other ways than using regex to format a phone number from the mask.
using formatted strings:
$maskPH = array_map(fn($i) => "%{$i}s", $mask);
$formatI = implode('', $maskPH);
$formatO = implode('-', $maskPH);
$result = vsprintf($formatO, sscanf($num, $formatI));
using unpack:
$format = array_reduce($mask, function ($c, $i) {
static $j = 0;
return "{$c}A{$i}_" . $j++ . "/";
});
$result = implode('-', unpack($format, $num));
preg_replace(): No ending delimiter '/' found
means that your pattern does not terminate with a / as last character.
But all three patterns lack proper formatting:
You should modify them accordingly.
From:
$pattern = '/\(?(\d{' . $value . '})\)?[- ]';
$pattern .= '?(\d{' . $value . '})/';
$pattern .= '?(\d{' . $value . '})[- ]';
To:
$pattern = '/\(?(\d{' . $value . '})\)?[- ]/';
$pattern .= '/?(\d{' . $value . '})/';
$pattern .= '/?(\d{' . $value . '})[- ]/';
I'm taking input from textarea form and put it in the long line.
Input is like this:
Country: France
City: Paris
Street: Champ
Then put it in the long line:
$line = $_POST['input'];
now, I need to replace spaces and new lines with <SP> and <BR>, so I do this:
$line = str_replace(" ","<SP>",$line);
$line = str_replace("\n","<BR>",$line);
but I get this:
Country:<SP>France <BR> <BR>City:<SP>Paris <BR> <BR>Street:<SP>Champ
Now, if insted of \n I tried this:
$line = str_replace("\r","<BR>",$line);
I get similar result. If I do them both i Get similar results which obviously has some spaces in it. So Then I do this:
$line = str_replace(" ","",$line);
but it stays the same.
My whole code is:
$line = str_replace(" ","<SP>",$line);
$line = str_replace("\n","<BR>",$line);
$line = str_replace(" ","",$line);
echo $line;
How to remove spaces in this case?
Edit:
I did bin2hex and found out that the space is actually carriage return \r.
So this is the solution:
$line = str_replace("\r","",$line);
Why did \r behave like space in this case?
the comments will probably suffice but I thought I'd share this snippet, which given your example I had a punt at what you are trying to achieve.
<?php
// example string data
$str = "key1 value1 key2 value2 key3 value3";
// clean string
$str = str_replace(" ", " ",$str);
$str = str_replace("\n", " ", $str);
$str = str_replace("\r", " ", $str);
$arr = explode(" ", $str);
$out = "<ul>";
$cnt = 1;
foreach($arr as &$val) {
if ($cnt++ % 2 == 0) {
continue;
} else {
$out = $out . "<li>" . $val . ": " . current($arr) . "</li>";
}
}
$out = $out . "</ul>";
echo $out;
// output source
// <ul><li>key1: value1</li><li>key2: value2</li><li>key3: value3</li></ul>
?>
I am currently making a homepage where logged in users can write comments. The comment string is first run through a function that str_replaces emoticons. After that I want it to exchange
[url=www.whatever.com]linktext[/url]
with:
<a href='www.whatever.com'>linktext</a>
The reason for this is that I want to strip the text for all the html code that isn't controlled by my comment code, in case some users decide to get creative-
and thought it would be best to use preg replace but the code I ended up with (Partially from reading about reg exp from my trusty "O reilly Sql and Php"-book and partially from the web) Is pretty bonkers, and most importantly, doesn't work.
Any help would be appreciated, thanks.
It's probably possible to exchange the entire code, not in 2 segments like I have done. Just decided on that getting 2 smaller parts to work first would be easier, and then merge them afterwards.
code:
function text_format($string)
{
$pattern="/([url=)+[a-zA-Z0-9]+(])+/";
$string=preg_replace($pattern, "/(<a href=\')+[a-zA-Z0-9]+(\'>)+/", $string);
$pattern="/([\/url])+/";
$string=preg_replace($pattern, "/(<\/a>)+/", $string);
return $string;
}
It looks like you're using something similar to BBCode. Why not use a BBCode parser, such as this one?
http://nbbc.sourceforge.net/
It also handles smilies, replacing them with images. If you use their test page, you will still see the text though, because they don't host the images and they set the alt-text to the smily.
I experimented a bit with the following:
function text_format($string)
{
return preg_replace('#\[url=([^\]]+)\]([^\[]*)\[/url\]#', '$2', $string);
}
However, one immediate fault with this is that if linktext is empty, there will be nothing between <a> and </a>. One way around it would be to do another pass with something like this:
preg_replace('##', '$1', $string);
Another option would be to use preg_replace_callback and put this logic inside your callback function.
Finally, this is obviously a common "problem" and has been solved many times by others, and if using a more mature open sourced solution is an option, I'd recommend looking for one.
#Lauri Lehtinen's answer is good for learning the idea behind the technique, but you shouldn't use it in practice because it would make your site extremely vulnerable to XSS attacks. Also, link spammers would appreciate the lack of rel="nofollow" on the generated links.
Instead, use something like:
<?php
// \author Daniel Trebbien
// \date 2010-06-22
// \par License
// Public Domain
$allowed_uri_schemes = array('http', 'https', 'ftp', 'ftps', 'irc', 'mailto');
/**
* Encodes a string in RFC 3986
*
* \see http://tools.ietf.org/html/rfc3986
*/
function encode_uri($str)
{
$str = urlencode('' . $str);
$search = array('%3A', '%2F', '%3F', '%23', '%5B', '%5D', '%40', '%21', '%24', '%26', '%27', '%28', '%29', '%2A', '%2B', '%2C', '%3B', '%3D', '%2E', '%7E');
$replace = array(':', '/', '?', '#', '[', ']', '#', '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=', '.', '~'); // gen-delims / sub-delims / unreserved
return str_ireplace($search, $replace, $str);
}
function url_preg_replace_callback($matches)
{
global $allowed_uri_schemes;
if (empty($matches[1]))
return $matches[0];
$href = trim($matches[1]);
if (($i = strpos($href, ':')) !== FALSE) {
if (strrpos($href, '/', $i) === FALSE) {
if (!in_array(strtolower(substr($href, 0, $i)), $allowed_uri_schemes))
return $matches[0];
}
}
// unescape `\]`, `\\\]`, `\\\\\]`, etc.
for ($j = strpos($href, '\\]'); $j !== FALSE; $j = strpos($href, '\\]', $j)) {
for ($i = $j - 2; $i >= 0 && $href[$i] == '\\' && $href[$i + 1] == '\\'; $i -= 2)
/* empty */;
$i += 2;
$h = '';
if ($i > 0)
$h = substr($href, 0, $i);
for ($numBackslashes = floor(($j - $i)/2); $numBackslashes > 0; --$numBackslashes)
$h .= '\\';
$h .= ']';
if (($j + 2) < strlen($href))
$h .= substr($href, $j + 2);
$href = $h;
$j = $i + floor(($j - $i)/2) + 1;
}
if (!empty($matches[2]))
$href .= str_replace('\\\\', '\\', $matches[2]);
if (empty($matches[3]))
$linkText = $href;
else {
$linkText = trim($matches[3]);
if (empty($linkText))
$linkText = $href;
}
$href = htmlspecialchars(encode_uri(htmlspecialchars_decode($href)));
return "$linkText";
}
function render($input)
{
$input = htmlspecialchars(strip_tags('' . $input));
$input = preg_replace_callback('~\[url=((?:[^\]]|(?<!\\\\)(?:\\\\\\\\)*\\\\\])*)((?<!\\\\)(?:\\\\\\\\)*)\]' . '((?:[^[]|\[(?!/)|\[/(?!u)|\[/u(?!r)|\[/ur(?!l)|\[/url(?!\]))*)' . '\[/url\]~i', 'url_preg_replace_callback', $input);
return $input;
}
which I believe is safe against XSS. This version has the added benefit that it is possible to write out links to URLs that contain ']'.
Evaluate this code with the following "test suite":
echo render('[url=http://www.bing.com/][[/[/u[/ur[/urlBing[/url]') . "\n";
echo render('[url=][/url]') . "\n";
echo render('[url=http://www.bing.com/][[/url]') . "\n";
echo render('[url=http://www.bing.com/][/[/url]') . "\n";
echo render('[url=http://www.bing.com/][/u[/url]') . "\n";
echo render('[url=http://www.bing.com/][/ur[/url]') . "\n";
echo render('[url=http://www.bing.com/][/url[/url]') . "\n";
echo render('[url=http://www.bing.com/][/url][/url]') . "\n";
echo render('[url= javascript: window.alert("hi")]click me[/url]') . "\n";
echo render('[url=#" onclick="window.alert(\'hi\')"]click me[/url]') . "\n";
echo render('[url=http://www.bing.com/] [/url]') . "\n";
echo render('[url=/?#[\\]#!$&\'()*+,;=.~] [/url]') . "\n"; // link text should be `/?#[]#!$&'()*+,;=.~`
echo render('[url=http://localhost/\\\\]d]abc[/url]') . "\n"; // href should be `http://localhost/%5C`, link text should be `d]abc`
echo render('[url=\\]][/url]') . "\n"; // link text should be `]`
echo render('[url=\\\\\\]][/url]') . "\n"; // link text should be `\]`
echo render('[url=\\\\\\\\\\]][/url]') . "\n"; // link text should be `\\]`
echo render('[url=a\\\\\\\\\\]bcde\\]fgh\\\\\\]ijklm][/url]') . "\n"; // link text should be `a\\]bcde]fgh\]ijklm`
Or, just look at the Codepad results.
As you can see, it works.