PHP preg_replace all text changing - php

I want to make some changes to the html but I have to follow certain rules.
I have a source code like this;
A beautiful sentence http://www.google.com/test, You can reach here http://www.google.com/test-mi or http://www.google.com/test/aliveli
I need to convert this into the following;
A beautiful sentence http://test.google.com/, You can reach here http://www.google.com/test-mi or http://test.google.com/aliveli
I tried using str_replace;
$html = str_replace('://www.google.com/test','://test.google.com');
When I use it like this, I get an incorrect result like;
A beautiful sentence http://test.google.com/, You can reach here http://test.google.com/-mi or http://test.google.com/aliveli
Wrong replace: http://test.google.com/-mi
How can I do this with preg_replace?

With regex you can use a word boundary and a lookahead to prevent replacing at -
$pattern = '~://www\.google\.com/test\b(?!-)~';
$html = preg_replace($pattern, "://test.google.com", $html);
Here is a regex demo at regex101 and a php demo at eval.in
Be aware, that you need to escape certain characters by a backslash from it's special meaning to match them literally when using regex.

It seems you're replacing the subdirectory test to subdomain. Your case seems to be too complicated. But I've given my best to apply some logic which may be reliable or may not be unless your string stays with the same structure. But you can give a try with this code:
$html = "A beautiful sentence http://www.google.com/test, You can reach here http://www.google.com/test-mi or http://www.google.com/test/aliveli";
function set_subdomain_string($html, $subdomain_word) {
$html = explode(' ', $html);
foreach($html as &$value) {
$parse_html = parse_url($value);
if(count($parse_html) > 1) {
$path = preg_replace('/[^0-9a-zA-Z\/-_]/', '', $parse_html['path']);
preg_match('/[^0-9a-zA-Z\/-_]/', $parse_html['path'], $match);
if(preg_match_all('/(test$|test\/)/', $path)) {
$path = preg_replace('/(test$|test\/)/', '', $path);
$host = preg_replace('/www/', 'test', $parse_html['host']);
$parse_html['host'] = $host;
if(!empty($match)) {
$parse_html['path'] = $path . $match[0];
} else {
$parse_html['path'] = $path;
}
unset($parse_html['scheme']);
$url_string = "http://" . implode('', $parse_html);
$value = $url_string;
}
}
unset($value);
}
$html = implode(' ', $html);
return $html;
}
echo "<p>{$html}</p>";
$modified_html = set_subdomain_string($html, 'test');
echo "<p>{$modified_html}</p>";
Hope it helps.

If the sentence is the only case in your problem you don't need to start struggling with preg_replace.
Just change your str_replace() functioin call to the following(with the ',' at the end of search string section):
$html = str_replace('://www.google.com/test,','://test.google.com/,');
This matches the first occurance of desired search parameter, and for the last one in your target sentence, add this(Note the '/' at the end):
$html = str_replace('://www.google.com/test/','://test.google.com/');
update:
Use these two:
$targetStr = preg_replace("/:\/\/www.google.com\/test[\s\/]/", "://test.google.com/", $targetStr);
It will match against all but the ones with comma at the end. For those, use you sould use the following:
$targetStr = preg_replace("/:\/\/www.google.com\/test,/", "://test.google.com/,", $targetStr);

Related

How to remove the first two directories from a file path string?

I have a string "./product_image/Bollywood/1476813695.jpg".
first I remove . from first.
now I want to remove all character between first two / . that means I want
Bollywood/1476813695.jpg
I am trying with this but not work
substr(strstr(ltrim('./product_image/Bollywood/1476813695.jpg', '.'),"/product_image/"), 1);
It always return product_image/Bollywood/1476813695.jpg
Easily done with explode():
$orig = './product_image/Bollywood/1476813695.jpg';
$origArray = explode('/', $orig);
$new = $origArray[2] . '/' . $origArray[3];
result:
Bollywood/1476813695.jpg
If you want something a little different you can use regex with preg_replace()
$pattern = '/\.\/(.*?)\//';
$string = './product_image/Bollywood/1476813695.jpg';
$new = preg_replace($pattern, '', $string);
This returns the same thing and you could, if you wanted, put it all in one line.
$str = "./product_image/Bollywood/1476813695.jpg";
$str_array = explode('/', $str);
$size = count($str_array);
$new_string = $str_array[$size - 2] . '/' . $str_array[$size - 1];
echo $new_string;
please follow the below code
$newstring = "./product_image/Bollywood/1476813695.jpg";
$pos =substr($newstring, strpos($newstring, '/', 2)+1);
var_dump($pos);
and output will be looking
Bollywood/1476813695.jpg
for strpos function detail please go to below link
http://php.net/manual/en/function.strpos.php
for substr position detail please go to below link
http://php.net/manual/en/function.substr.php

PHP: preg_replace() to get "parent" component of NameSpace

How can I use the preg_replace() replace function to only return the parent "component" of a PHP NameSpace?
Basically:
Input: \Base\Ent\User; Desired Output: Ent
I've been doing this using substr() but I want to convert it to regex.
Note: Can this be done without preg_match_all()?
Right now, I also have a code to get all parent components:
$s = '\\Base\\Ent\\User';
print preg_replace('~\\\\[^\\\\]*$~', '', $s);
//=> \Base\Ent
But I only want to return Ent.
Thank you!
As Rocket Hazmat says, explode is almost certainly going to be better here than a regex. I would be surprised if it's actually slower than a regex.
But, since you asked, here's a regex solution:
$path = '\Base\Ent\User';
$search = preg_match('~([^\\\\]+)\\\\[^\\\\]+$~', $path, $matches);
if($search) {
$parent = $matches[1];
}
else {
$parent = ''; // handles the case where the path is just, e.g., "User"
}
echo $parent; // echos Ent
I think maybe preg_match might be a better choice for this.
$s = '\\Base\\Ent\\User';
$m = [];
print preg_match('/([^\\\\]*)\\\\[^\\\\]*$/', $s, $m);
print $m[1];
If you read the regular expression backwards, from the $, it says to match many things that aren't backslashes, then a backslash, then many things that aren't backslashes, and save that match for later (in $m).
How about
$path = '\Base\Ent\User';
$section = substr(strrchr(substr(strrchr($path, "\\"), 1), "\\"), 1);
Or
$path = '\Base\Ent\User';
$section = strstr(substr($path, strpos($path, "\\", 1)), "\\", true);

Replace a specified portion of a string

How can I use str_replace method for replacing a specified portion(between two substrings).
For example,
string1="www.example.com?test=abc&var=55";
string2="www.example.com?test=xyz&var=55";
I want to replace the string between '?------&' in the url with ?res=pqrs&. Are there any other methods available?
You could use preg_replace to do that, but is that really what you are trying to do here?
$str = preg_replace('/\?.*?&/', '?', $input);
If the question is really "I want to remove the test parameter from the query string" then a more robust alternative would be to use some string manipulation, parse_url or parse_str and http_build_query instead:
list($path, $query) = explode('?', $input, 2);
parse_str($query, $parameters);
unset($parameters['test']);
$str = $path.'?'.http_build_query($parameters);
Since you're working with URL's, you can decompose the URL first, remove what you need and put it back together like so:
$string1="www.example.com?test=abc&var=55";
// fetch the part after ?
$qs = parse_url($string1, PHP_URL_QUERY);
// turn it into an associative array
parse_str($qs, $a);
unset($a['test']); // remove test=abc
$a['res'] = 'pqrs'; // add res=pqrs
// put it back together
echo substr($string1, 0, -strlen($qs)) . http_build_query($a);
There's probably a few gotchas here and there; you may want to cater for edge cases, etc. but this works on the given inputs.
Dirty version:
$start = strpos($string1, '?');
$end = strpos($string1, '&');
echo substr($string1, 0, $start+1) . '--replace--' . substr($string1, $end);
Better:
preg_replace('/\?[^&]+&/', '?--replace--&', $string1);
Depending on whether you want to keep the ? and &, the regex can be mofidied, but it would be quicker to repeat them in the replaced string.
Think of regex
<?php
$string = 'www.example.com?test=abc&var=55';
$pattern = '/(.*)\?.*&(.*)/i';
$replacement = '$1$2';
$replaced = preg_replace($pattern, $replacement, $string);
?>

Parsing a Source With REGEX

I want to get all Performance ID's from this page .
<?php
$content = file_get_contents("http://www124.popmundo.com/Common/Performances.asp?action=ComingPerformances&ArtistID=1962457");
$regex = "Performances\.asp\?action=Arrangements&PerformanceID=([0-9]+)";
//$regex = "/Performances\.asp\?action=Arrangements&PerformanceID=([0-9]+)/";
//$regex = "/Performances\.asp\?action=Arrangements&PerformanceID=([0-9]+)/s";
//all pattern variations tested, not working
if(preg_match_all($regex, $content, $m))
print_r($m);
else
echo "FALSE";
// this is returning FALSE
Use & instead of & in your regex.
Try this:
$regex = "/Performances\.asp\?action=Arrangements&PerformanceID=([0-9]+)/";
It looks like an escape problem. Not knowing php, I would guess one of these
might fix it:
$regex = 'Performances\.asp\?action=Arrangements&PerformanceID=([0-9]+)';
or
$regex = "Performances\\.asp\\?action=Arrangements&PerformanceID=([0-9]+)";
or
$regex = '/Performances\.asp\?action=Arrangements&PerformanceID=([0-9]+)/';

Can I use regex for this?

Is this possible with regex?
I have a file, and if a '#' is found in the file, the text after the '#' with the '#' is to be replaced with the file with the same name as after the '#'.
File1: "this text is found in file1"
File2: "this file will contain text from file1: #file1".
File2 after regex: "this file will contain text from file1: this text is found in file1".
I wish to do this with php and I've heard that the preg function is better than the ereg, but whatever works is fine with me =)
Thanks a lot!
EDIT:
It has to be programmed, so that it looks through file2 without knowing which files to concatenate before it has gone through all occurrences of a # :)
PHP's native functions str_pos and str_replace are better to use when you're searching through larger files or strings. ;)
First of all the grammar of your templating is not a very good one becuase the parser may not exactly sure when will the file name ends.
My suggestion would be that you change to the one that can better detect the boundry like {#:filename}.
Anyhow, the code I give below follows your question.
<?php
// RegEx Utility functions -------------------------------------------------------------------------
function ReplaceAll($RegEx, $Processor, $Text) {
// Make sure the processor can be called
if(!is_callable($Processor))
throw new Exception("\"$Processor\" is not a callable.");
// Do the Match
preg_match_all($RegEx, $Text, $Matches, PREG_OFFSET_CAPTURE + PREG_SET_ORDER);
// Do the replacment
$NewText = "";
$MatchCount = count($Matches);
$PrevOffset = 0;
for($i = 0; $i < $MatchCount; $i++) {
// Get each match and the full match information
$EachMatch = $Matches[$i];
$FullMatch = is_array($EachMatch) ? $EachMatch[0] : $EachMatch;
// Full match is each match if no grouping is used in the regex
// Full match is the first element of each match if grouping is used in the regex.
$MatchOffset = $FullMatch[1];
$MatchText = $FullMatch[0];
$MatchTextLength = strlen($MatchText);
$NextOffset = $MatchOffset + $MatchTextLength;
// Append the non-match and the replace of the match
$NewText .= substr($Text, $PrevOffset, $MatchOffset - $PrevOffset);
$NewText .= $Processor($EachMatch);
// The next prev-offset
$PrevOffset = $NextOffset;
}
// Append the rest of the text
$NewText .= substr($Text, $PrevOffset);
return $NewText;
}
function GetGroupMatchText($Match, $Index) {
if(!is_array($Match))
return $Match[0];
$Match = $Match[$Index];
return $Match[0];
}
// Replacing by file content -----------------------------------------------------------------------
$RegEx_FileNameInText = "/#([a-zA-Z0-9]+)/"; // Group #1 is the file name
$ReplaceFunction_ByFileName = "ReplaceByFileContent";
function ReplaceByFileContent($Match) {
$FileName = GetGroupMatchText($Match, 1); // Group # is the gile name
// $FileContent = get_file_content($FileName); // Get the content of the file
$FileContent = "{# content of: $FileName}"; // Dummy content for testing
return $FileContent; // Returns the replacement
}
// Main --------------------------------------------------------------------------------------------
$Text = " === #file1 ~ #file2 === ";
echo ReplaceAll($RegEx_FileNameInText, $ReplaceFunction_ByFileName, $Text);
This will returns === {# content of: file1} ~ {# content of: file2} ===.
The program will replace all the regex match with the replacement returned from the result of the given function name.
In this case, the callback function is ReplaceByFileContent in which the file name is extract from the group #1 in the regex.
I believe my code is self documented but if you have any question, you can ask me.
Hope I helps.
Much cleaner:
<?php
$content = file_get_content('content.txt');
$m = array();
preg_match_all('`#([^\s]*)(\s|\Z)`ism', $content, $m, PREG_SET_ORDER);
foreach($m as $match){
$innerContent = file_get_contents($match[1]);
$content = str_replace('#'.$match[1], $innerContent, $content);
}
// done!
?>
regex tested with: http://www.spaweditor.com/scripts/regex/index.php

Categories