Reputation: 8182
I really don't know what my problem is lately, but Regex seems to be giving me the most trouble.
Very simple thing I need to do, but can't seem to get it:
I have a uri that returns either /xmlfeed or /xmlfeed/what/is/this
I want to match /xmlfeed on any occasion.
I've tried many variations of the following:
preg_match('/(\/.*?)\/?/', $_SERVER['REQUEST_URI'], $match);
I would read this as: Match forwardslash then match any character until you come to an optional forwardslash.
Upvotes: 0
Views: 143
Reputation: 8182
Using the suggestions posted, I ended up trying this:
echo $_SERVER['REQUEST_URI'];
preg_match("/(\/.*)[^\/]/", $_SERVER['REQUEST_URI'], $match);
$url = "http://".$_SERVER['SERVER_NAME'].$match[0];
foreach($match as $k=>$v){
echo "<h1>$k - $v</h1>";
}
I also tried it without the .* and without the parentheses.
Without the .* AND () it returns the / with the next character ONLY.
Like it is, it just returns the entire URI everytime
So, when ran with the code above, the output is
/tea-time-blog/post/20
0 - /tea-time-blog/post/20
1 - /tea-time-blog/post/2
This code is being eval()'d by the way. I don't think that should make any differnce in the way PHP handles the regular expression.
Upvotes: 0
Reputation: 943175
In PHP: '/(\/.*?)\/?/'
is a string containing a regular expression.
First you have to decode the string: /(/.*?)\/?/
So you have a forward slash that starts the result expression. An opening brace. A forward slash that ends the matching part of the expression … and I'm pretty sure that it will then error since you haven't closed the brace.
So, to get this working:
/
with the backslash \
You want to match everything after and including the first slash, but before any (optional) second slash (so we don't want the ?
that makes it non-greedy):
/(\/[^\/]*)/
Which, expressed as a PHP string is:
'/(\\/([^\\/]*)/'
Upvotes: 1
Reputation: 75222
Your problem is the reluctant quantifier. After the initial slash is matched, .*?
consumes the minimum number of characters it's allowed to, which is zero. Then /?
takes over; it doesn't see a slash in the next position (which is immediately after the first slash), but that's okay because it's optional. The result: the regex always matches a single slash, and group #1 always matches an empty string.
Obviously, you can't just replace the reluctant quantifier with a greedy one. But if you replace the .*
with something that can't match a slash, you don't have to worry about greediness. That's what K Prime's regex, '#/[^/]+#'
does. Notice as well how it uses #
as the regex delimiter and avoids the necessity of escaping slashes within the regex.
Upvotes: 1
Reputation: 5849
Why not:
preg_match ('#/[^/]+#', _SERVER['REQUEST_URI'], $match);
?
$match[0]
will give you what you need
Upvotes: 2
Reputation: 342313
why do you need regex that make you confused??
$string = "/xmlfeed/what/is/this";
$s = explode("/",$string,3);
print "/".$s[1]."\n";
output
$ php test.php
/xmlfeed
Upvotes: 2
Reputation: 15108
I know this is avoiding the regex, and therefore avoids the question, but how about splitting the uri (at slashes) into an array.
Then you can deal with the elements of the array, and ignore the bits of the uri you don't want.
Upvotes: 0