Destramic Posted June 5, 2016 Share Posted June 5, 2016 i'm sorry for having to post a simular thread but i'm really struggling to get my pattern to work after many attempts...i've tried playing around with it but its just not matching multiple patterns this will work great $uri = "/i:news_id"; if (preg_match_all('/(??!\[\/).)*^\/(i|a|h)?[A-Za-z0-9_]+)$(??!\]))/', $uri, $parameters)) { print_r($parameters); } but when chaging this part of the code it won't work $uri = "/i:news_id/:hello"; examples of matching are: /:test /i:test /a:test /b:test but i only want a match as long as the pattern isn't wrapped inside brakcets [ ] invalid: [/:test] i thought the ^ start and $ end characters would have been all i needed...any advise wouldnt greatful...thank you Quote Link to comment https://forums.phpfreaks.com/topic/301301-struggling-to-nail-this/ Share on other sites More sharing options...
requinix Posted June 5, 2016 Share Posted June 5, 2016 So what has changed since brilliant thank you very much requinix. i used this pattern which seems to work fine /(i|s)+:+([A-Za-z0-9_-]\w*)/ last time? I thought this was from a URI, but if that's true then where are these brackets coming from? Quote Link to comment https://forums.phpfreaks.com/topic/301301-struggling-to-nail-this/#findComment-1533433 Share on other sites More sharing options...
Destramic Posted June 5, 2016 Author Share Posted June 5, 2016 well my routing system may contain something like this: /search/xbox[/category/:category] matching: /search/xbox /search/xbox/category/consoles so i decided to make my pattern a bit stonger so it match uri vars which are not inside brackets...so yeah my pattern has changed slightly...with the regex in this posts and the others i'm working on i get the problem of matching multiple patterns in the same string...this is my only problem. can you please tell me where i'm going wrong...thank you Quote Link to comment https://forums.phpfreaks.com/topic/301301-struggling-to-nail-this/#findComment-1533434 Share on other sites More sharing options...
Solution requinix Posted June 5, 2016 Solution Share Posted June 5, 2016 But what about a case like /search/xbox[/category/:category[/subcategory/:subcategory]]This becomes a problem of balanced brackets - simply checking for [] on either side isn't enough. Two suggestions for how to handle this: a) Don't allow optional variables and force the user to make additional routes. I've done this and it helps if you can give the user a way to configure routing in a recursive way, like <route path="/search/xbox"> route information here... <route path="/category/:category"> additional overriding information here... </route> </route>The routing system matches as much as it can, gathers all the information along the way, and decides what to do. You could also support <route path="/search"> route information... <route path="/xbox"> route information... <route path="/category/:category"> route information... </route> </route> </route>where the route information gathered for just "/search" isn't enough to serve a page and thus results in some 404-type behavior. b) Use regular expressions to turn the route pattern into another regular expression. I've done this one too. With your simple example you could have something like $route = "/search/xbox[/category/:category]"; // escape any regex metacharacters already present $regex = preg_quote($route, '#'); // if using # as the pattern delimiters // note that it will escape any of . \ + * ? [ ^ ] $ ( ) { } = ! < > | : - // or you can make this much simpler by not escaping characters and trusting the user to write mostly-regex-safe patterns // transform escaped brackets $regex = preg_replace('/\\\\\[/', '(?:', $regex); $regex = preg_replace('/\\\\\]/', ')?', $regex); // transform variables $regex = preg_replace('/\\\\\w+)/', '(?P<$1>[^/]+)', $regex); // replace [^/]+ with whatever you think matches a variable var_dump($regex); // "/search/xbox(?:/category/(?P<category>[^/]+))?"then if (preg_match('#^' . $regex . '$#', $url, $matches)) {gives you stuff like Array ( [0] => /search/xbox ) Array ( [0] => /search/xbox/category/consoles [category] => consoles [1] => consoles )The route gets [0] for the full match, and both named (useful) and numeric (useless) captures matching the assorted variables (if present). Why did I just say all that? Because at 4:30am I'm not seeing a "nice" way of solving your particular problem of dealing with the []s. Quote Link to comment https://forums.phpfreaks.com/topic/301301-struggling-to-nail-this/#findComment-1533436 Share on other sites More sharing options...
Destramic Posted June 6, 2016 Author Share Posted June 6, 2016 Why did I just say all that? Because at 4:30am I'm not seeing a "nice" way of solving your particular problem of dealing with the []s. for 4:30am you've come up with some good solutions i do like the first option and it does get rid of the bother caused by the brackets and you've openned my mind up to another soltion, thank you...options 2 is what i'm currently doing at the moment. although my regex knowledge is poor could you please explain to me how i can make this pattern match multiple please? $uri = "/i:news_id/:hello"; if (preg_match_all('/^\/(i|a|h)?[A-Za-z0-9_]+)$/', $uri, $parameters)) { print_r($parameters); } thank you for your great information Quote Link to comment https://forums.phpfreaks.com/topic/301301-struggling-to-nail-this/#findComment-1533445 Share on other sites More sharing options...
requinix Posted June 7, 2016 Share Posted June 7, 2016 although my regex knowledge is poor could you please explain to me how i can make this pattern match multiple please? $uri = "/i:news_id/:hello"; if (preg_match_all('/^\/(i|a|h)?[A-Za-z0-9_]+)$/', $uri, $parameters)) { print_r($parameters); } It would match fine if you didn't use the ^ and $ anchors that force the regex to test the entire string at once. And by the way, a slightly cleaner version: #/([ahi]?)\w+)#- # delimiters so you don't have to escape the /s (you can use just about anything as a delimiter and / # ! ~ are the most common)- [ahi] so you don't need | alternation - [ahi]? inside the capturing group so it always captures something (even if it is just an empty string) - \w is equivalent to [A-Za-z0-9_] 1 Quote Link to comment https://forums.phpfreaks.com/topic/301301-struggling-to-nail-this/#findComment-1533446 Share on other sites More sharing options...
Destramic Posted June 12, 2016 Author Share Posted June 12, 2016 wel i feel a lot wiser now...thank you for the breakdown and all your help requinix Quote Link to comment https://forums.phpfreaks.com/topic/301301-struggling-to-nail-this/#findComment-1533601 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.