I have a regular expression that Im using in php:
$word_array = preg_split(
'/(\/|\.|-|_|=|\?|\&|html|shtml|www|php|cgi|htm|aspx|asp|index|com|net|org|%|\+)/',
urldecode($path), NULL, PREG_SPLIT_NO_EMPTY
);
It works great. It takes a chunk of url paramaters like:
/2009/06/pagerank-update.html
and returns an array like:
array(4) {
[0]=>
string(4) "2009"
[1]=>
string(2) "06"
[2]=>
string(8) "pagerank"
[3]=>
string(6) "update"
}
The only thing I need is for it to also not return strings that are less than 3 characters. So the "06"
string is garbage and I'm currently using an if statement to weed them out.
How about trying
preg_match()
instead ofpreg_split()
?The pattern (using the Assertions):
The function call:
You can try the function here: functions-online.com/preg_match_all.html
Hope this helps
I'm guessing you're building a URL router of some kind.
Detecting which parameters are useful and which are not should not be part of this code. It may vary per page whether a short parameter is relevant.
In this case, couldn't you just ignore the 1'th element? Your page should (or 'handler') should have knowledge over which parameters it wants to be called with, it should do the triage.
I would think that if you were trying to derive meaning from the URL's that you would actually want to write clean URL's in such a way that you don't need a complex regex to derive the value.
In many cases this involves using server redirect rules and a front controller or request router.
So what you build are clean URL's like
Without any
.html
,.php
, etc. in the URL at all.It seems to me that you are not addressing the problem at the point of entry into the system (i.e the web server) adequately so as to make your URL parsing as simple as it should be.
The magic of the split. My original assumption was technically not correct (albeit a solution easier to come to). So let's check your split pattern:
I re-arranged it a bit. The outer parenthesis is not necessary and I moved the single characters into a character class at the end:
That for some sorting upfront. Let's call this pattern the split pattern,
s
in short and define it.You want to match all parts that are not of those characters from the split-at pattern and at minimum three characters.
I could achieve this with the following pattern, including support of the correct split sequences and unicode support.
Or in smaller:
Result:
The same principle can be used with
preg_split
as well. It's a little bit different:Usage:
Result:
These routines work as asked for. But this does have its price with performance. The cost is similar to the old answer.
Related questions:
Because you are using a split routine, it will split - regardless of the length.
So what you can do is to filter the result. You can do that again with a regular expression (
preg_filter
), for example one that is dropping everything smaller three characters:Result:
Don't use a regex to break apart that path. Just use
explode
.Then, if you need to break apart an individual element of the array, do that, like on your "pagerank-update" element at the end.
EDIT:
The key is that you have two different problems. First you want to break apart the path elements on slashes. Then, you want to break up the filename into smaller parts. Don't try to cram everything into one regex that tries to do everything.
Three discrete steps:
It is far clearer if you break up your logic into discrete logical chunks rather than trying to make the regex do everything.