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);
Related
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);
I have this code here:
$imagePreFix = substr($fileinfo['basename'], strpos($fileinfo['basename'], "_") +1);
this gets me everything after the underscore, but I am looking to get everything before the underscore, how would I adjust this code to get everything before the underscore?
$fileinfo['basename'] is equal to 'feature_00'
Thanks
You should simple use:
$imagePreFix = substr($fileinfo['basename'], 0, strpos($fileinfo['basename'], "_"));
I don't see any reason to use explode and create extra array just to get first element.
You can also use (in PHP 5.3+):
$imagePreFix = strstr($fileinfo['basename'], '_', true);
If you are completely sure that there always be at least one underscore, and you are interested in first one:
$str = $fileinfo['basename'];
$tmp = explode('_', $str);
$res = $tmp[0];
Other way to do this:
$str = "this_is_many_underscores_example";
$matches = array();
preg_match('/^[a-zA-Z0-9]+/', $str, $matches);
print_r($matches[0]); //will produce "this"
(probably regexp pattern will need adjustments, but for purpose of this example it works just fine).
I think the easiest way to do this is to use explode.
$arr = explode('_', $fileinfo['basename']);
echo $arr[0];
This will split the string into an array of substrings. The length of the array depends on how many instances of _ there was. For example
"one_two_three"
Would be broken into an array
["one", "two", "three"]
Here's some documentation
If you want an old-school answer in the type of what you proposed you can still do the following:
$imagePreFix = substr($fileinfo['basename'], 0, strpos($fileinfo['basename'], "_"));
I have this section some/aaa/9321/something from which I want to extract only 9321. "something" always differs, "aaa" is alyways static. So, I used:
$text = "something/aaa/9321/something";
$first = 'aaa/';
$after = '/';
preg_match("/$first(.*)$after/s",$text,$result);
echo $result;
But isn't working. Can somebody please tell me what I need to use?
I've tried this too:
$text = "something/aaa/9321/something";
$first = 'aaa';
preg_match("|$first(.*)|",$text,$result);
echo substr($result['1'], 1, 4);
But between aaa and something not always 4 characters.
Sorry for bad english. Thanks!
You should always preg_quote strings when you want them to be taken literally in a regular expression:
$text = 'something/aaa/9321/something';
$first = preg_quote('aaa/', '/');
$after = preg_quote('/', '/');
preg_match("/$first(.*)$after/s",$text,$result);
echo $result[1]; // '9321'
Demo
The problem was caused by the fact that / is the delimiter in your regex. You could have also solved this problem by using a different delimiter, such as ~, however, you would just run into the same problem as soon as your string had a ~ or any other character with a special meaning like ., or ?. By using preg_quote, you won't run into this problem again.
Have you tried escaping the /?
Instead of
$first = 'aaa/';
$after = '/';
try
$first = 'aaa\/';
$after = '\/';
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);
?>
I am trying to extract a substring. I need some help with doing it in PHP.
Here are some sample strings I am working with and the results I need:
home/cat1/subcat2 => home
test/cat2 => test
startpage => startpage
I want to get the string till the first /, but if no / is present, get the whole string.
I tried,
substr($mystring, 0, strpos($mystring, '/'))
I think it says - get the position of / and then get the substring from position 0 to that position.
I don't know how to handle the case where there is no /, without making the statement too big.
Is there a way to handle that case also without making the PHP statement too complex?
The most efficient solution is the strtok function:
strtok($mystring, '/')
NOTE: In case of more than one character to split with the results may not meet your expectations e.g. strtok("somethingtosplit", "to") returns s because it is splitting by any single character from the second argument (in this case o is used).
#friek108 thanks for pointing that out in your comment.
For example:
$mystring = 'home/cat1/subcat2/';
$first = strtok($mystring, '/');
echo $first; // home
and
$mystring = 'home';
$first = strtok($mystring, '/');
echo $first; // home
Use explode()
$arr = explode("/", $string, 2);
$first = $arr[0];
In this case, I'm using the limit parameter to explode so that php won't scan the string any more than what's needed.
$first = explode("/", $string)[0];
What about this :
substr($mystring.'/', 0, strpos($mystring, '/'))
Simply add a '/' to the end of mystring so you can be sure there is at least one ;)
Late is better than never. php has a predefined function for that. here is that good way.
strstr
if you want to get the part before match just set before_needle (3rd parameter) to true
http://php.net/manual/en/function.strstr.php
function not_strtok($string, $delimiter)
{
$buffer = strstr($string, $delimiter, true);
if (false === $buffer) {
return $string;
}
return $buffer;
}
var_dump(
not_strtok('st/art/page', '/')
);
One-line version of the accepted answer:
$out=explode("/", $mystring, 2)[0];
Should work in php 5.4+
This is probably the shortest example that came to my mind:
list($first) = explode("/", $mystring);
1) list() will automatically assign string until "/" if delimiter is found
2) if delimiter "/"is not found then the whole string will be assigned
...and if you get really obsessed with performance, you may add extra parameter to explode explode("/", $mystring, 2) which limits maximum of the returned elements.
The function strstr() in PHP 5.3 should do this job.. The third parameter however should be set to true..
But if you're not using 5.3, then the function below should work accurately:
function strbstr( $str, $char, $start=0 ){
if ( isset($str[ $start ]) && $str[$start]!=$char ){
return $str[$start].strbstr( $str, $char, $start+1 );
}
}
I haven't tested it though, but this should work just fine.. And it's pretty fast as well
You can try using a regex like this:
$s = preg_replace('|/.*$|', '', $s);
sometimes, regex are slower though, so if performance is an issue, make sure to benchmark this properly and use an other alternative with substrings if it's more suitable for you.
Using current on explode would ease the process.
$str = current(explode("/", $str, 2));
You could create a helper function to take care of that:
/**
* Return string before needle if it exists.
*
* #param string $str
* #param mixed $needle
* #return string
*/
function str_before($str, $needle)
{
$pos = strpos($str, $needle);
return ($pos !== false) ? substr($str, 0, $pos) : $str;
}
Here's a use case:
$sing = 'My name is Luka. I live on the second floor.';
echo str_before($sing, '.'); // My name is Luka
$arr = explode("/", $string, 2); $first = $arr[0];
This Way is better and more accurate than strtok
because if you wanna get the values before # for example
while the there's no string before # it will give you whats after the sign .
but explode doesnt
$string="kalion/home/public_html";
$newstring=( stristr($string,"/")==FALSE ) ? $string : substr($string,0,stripos($string,"/"));
why not use:
function getwhatiwant($s)
{
$delimiter='/';
$x=strstr($s,$delimiter,true);
return ($x?$x:$s);
}
OR:
function getwhatiwant($s)
{
$delimiter='/';
$t=explode($delimiter, $s);
return ($t[1]?$t[0]:$s);
}