Jump to content
Sign in to follow this  
Destramic

regex none or many ?

Recommended Posts

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

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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...

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.