Destramic Posted July 11, 2016 Share Posted July 11, 2016 in my regex pattern i have a lot of none or many operators (?) , which has caused a bit of a problem, as a string containing a forward slash will come back with a result. (?<=/)(([ahis]?)\w+))?(\(([\w-]+(?:\|[\w-]+)*)\))?(\*)?(?![^\[\]]*\]) is it possible to match with a string containing at lease on for the one or many groups? and not just a forward slash? $pattern = '#(?<=/)(([ahis]?)\w+))?(\(([\w-]+(?:\|[\w-]+)*)\))?(\*)?(?![^\[\]]*\])#'; if (preg_match_all($pattern, '/news/:action(add|delete|edit)/:type', $matches)) { print_r($matches); // wanted match } if (preg_match_all($pattern, '/test[/hello[/bye]]', $matches)) { print_r($matches); // unwanted match } i'm not able to find evidence that such thing exists, but it's worth an ask. the reason i bundled all of my routing patterns into one regex pattern is so that i have one simple method to phase all route variables. giving me a nice array to work with: Array ( [0] => Array ( [0] => / [1] => /:action(add|delete|edit) [2] => /:type ) [1] => Array ( [0] => [1] => :action [2] => :type ) [2] => Array ( [0] => [1] => [2] => ) [3] => Array ( [0] => [1] => action [2] => type ) [4] => Array ( [0] => [1] => (add|delete|edit) [2] => ) [5] => Array ( [0] => [1] => add|delete|edit [2] => ) [6] => Array ( [0] => [1] => [2] => ) ) private function variables() { $pattern = self::ROUTE_VARIABLES; $parameters = $this->match($pattern); if ($parameters) { $count = count($parameters[0]); $route_split = explode('/', $this->_route); $uri_split = explode('/', $this->_uri); for ($i = 0; $i < $count; $i++) { $match = $parameters[0][$i]; $type = $parameters[2][$i]; $name = $parameters[3][$i]; $key = $this->array_search($match, $route_split); if (!isset($uri_split[$key])) { return false; } $value = $uri_split[$key]; if (!empty($parameters[5][$i])) { $values = explode('|', $parameters[5][$i]); if (!in_array($value, $values)) { return false; } else if (empty($name)) { $this->_route = $this->replace($match, $value, $this->_route); continue; } } else if (!empty($parameters[6][$i])) { if (empty($parameters[1][$i])) { $this->_route = $this->replace($match, '(.*)', $this->_route); continue; } else { $next_key = $key + 1; if (!isset($route_split[$next_key])) { return false; } $next_value = $route_split[$next_key]; $values = array(); for ($j = $key; $j < count($uri_split); $j++) { if ($uri_split[$j] === $next_value) { break; } $values[] = $uri_split[$j]; } $value = implode('/', $values); } } if ((!empty($type) && !$this->is_type($value, $type))) { return false; } $replace = '(?P<' . $name . '>'. $value . '+)'; $this->_route = $this->replace($match, $replace, $this->_route); } } return true; } thank you Quote Link to comment Share on other sites More sharing options...
requinix Posted July 11, 2016 Share Posted July 11, 2016 I can't tell what you're asking for. Do you have an example of the input string, current output, and desired output? in my regex pattern i have a lot of none or many operators (?) ,"or one". Not many. * is none or many. Quote Link to comment Share on other sites More sharing options...
Destramic Posted July 11, 2016 Author Share Posted July 11, 2016 sorry i meaning zero or one time ---> ? this returns my match perfectly $pattern = '#(?<=/)(([ahis]?)\w+))?(\(([\w-]+(?:\|[\w-]+)*)\))?(\*)?(?![^\[\]]*\])#'; if (preg_match_all($pattern, '/news/:action(add|delete|edit)/:type', $matches)) { print_r($matches); } but becuase of the ? zero or one, this subject (/test[/hello[/bye]]) will return matches because of the / $pattern = '#(?<=/)(([ahis]?)\w+))?(\(([\w-]+(?:\|[\w-]+)*)\))?(\*)?(?![^\[\]]*\])#'; if (preg_match_all($pattern, '/test[/hello[/bye]]', $matches)) { print_r($matches); } what i'm asking is there a way of making my pattern look for: /(with at least one of the zero or one groups) or else don't match i just don't want the regex pattern to match on a / hope i made myself a bit more clearer thank you Quote Link to comment Share on other sites More sharing options...
Solution requinix Posted July 12, 2016 Solution Share Posted July 12, 2016 There are too many things that are optional in that regex. Either you need to make some stuff required or you should combine some of them with alternation and make the whole set required. (first?)(second?)(third?) -> (?:first|second|third)If neither of those then we might have to rebuild the regex from scratch... Quote Link to comment Share on other sites More sharing options...
Destramic Posted July 12, 2016 Author Share Posted July 12, 2016 There are too many things that are optional in that regex. Either you need to make some stuff required or you should combine some of them with alternation and make the whole set required. (first?)(second?)(third?) -> (?:first|second|third)If neither of those then we might have to rebuild the regex from scratch... that is what i need...i come up with: #(?<=/)([ahis])?(?:(\w+))?\(([\w-]+(?:\|[\w-]+))*\)|((\w+))?\*)|\w+))(?![^\[\]]*\])# which is a bit spicy...i don't like how i've had to add (\w+)) to every options, also a:var(a) will come with a match althoght it shouldn't i think i'm gonna stop over complicating the pattern and just do each pattern individually thank you for your help again on this matter Quote Link to comment Share on other sites More sharing options...
Destramic Posted July 13, 2016 Author Share Posted July 13, 2016 i only gone and nailed it #/([ahis])?(\w+))?(?\(([\w-+]+(?:\|[\w-]+)+)*\))|(\*)|(?<=:\w))(?![^\[\]]*\])# There are too many things that are optional in that regex. Either you need to make some stuff required or you should combine some of them with alternation and make the whole set required. (first?)(second?)(third?) -> (?:first|second|third)If neither of those then we might have to rebuild the regex from scratch... thanks you for pointing me into the right direction requinix Quote Link to comment 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.