Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regular Expressions: querystring parameters matching

Tags:

regex

I'm trying to learn something about regular expressions.
Here is what I'm going to match:

/parent/child  
/parent/child?  
/parent/child?firstparam=abc123  
/parent/child?secondparam=def456  
/parent/child?firstparam=abc123&secondparam=def456  
/parent/child?secondparam=def456&firstparam=abc123  
/parent/child?thirdparam=ghi789&secondparam=def456&firstparam=abc123  
/parent/child?secondparam=def456&firstparam=abc123&thirdparam=ghi789  
/parent/child?thirdparam=ghi789  
/parent/child/  
/parent/child/?  
/parent/child/?firstparam=abc123  
/parent/child/?secondparam=def456  
/parent/child/?firstparam=abc123&secondparam=def456  
/parent/child/?secondparam=def456&firstparam=abc123  
/parent/child/?thirdparam=ghi789&secondparam=def456&firstparam=abc123  
/parent/child/?secondparam=def456&firstparam=abc123&thirdparam=ghi789  
/parent/child/?thirdparam=ghi789

My expression should "grabs" abc123 and def456.
And now just an example about what I'm not going to match ("question mark" is missing):

/parent/child/firstparam=abc123&secondparam=def456

Well, I built the following expression:

^(?:/parent/child){1}(?:^(?:/\?|\?)+(?:firstparam=([^&]*)|secondparam=([^&]*)|[^&]*)?)?

But that doesn't work.
Could you help me to understand what I'm doing wrong?
Thanks in advance.

UPDATE 1

Ok, I made other tests. I'm trying to fix the previous version with something like this:

/parent/child(?:(?:\?|/\?)+(?:firstparam=([^&]*)|secondparam=([^&]*)|[^&]*)?)?$

Let me explain my idea:
Must start with /parent/child:

/parent/child

Following group is optional

(?: ... )?

The previous optional group must starts with ? or /?

(?:\?|/\?)+

Optional parameters (I grab values if specified parameters are part of querystring)

(?:firstparam=([^&]*)|secondparam=([^&]*)|[^&]*)?

End of line

$

Any advice?

UPDATE 2

My solution must be based just on regular expressions. Just for example, I previously wrote the following one:

/parent/child(?:[?&/]*(?:firstparam=([^&]*)|secondparam=([^&]*)|[^&]*))*$

And that works pretty nice. But it matches the following input too:

/parent/child/firstparam=abc123&secondparam=def456

How could I modify the expression in order to not match the previous string?

like image 949
NicolaBaldi Avatar asked Feb 22 '26 06:02

NicolaBaldi


1 Answers

You didn't specify a language so I'll just usre Perl. So basically instead of matching everything, I just matched exactly what I thought you needed. Correct me if I am wrong please.

while ($subject =~ m/(?<==)\w+?(?=&|\W|$)/g) {
    # matched text = $&
}

(?<=        # Assert that the regex below can be matched, with the match ending at this position (positive lookbehind)
   =        # Match the character “=” literally
)
\\w         # Match a single character that is a “word character” (letters, digits, and underscores)
   +?       # Between one and unlimited times, as few times as possible, expanding as needed (lazy)
(?=         # Assert that the regex below can be matched, starting at this position (positive lookahead)
            # Match either the regular expression below (attempting the next alternative only if this one fails)
      &     # Match the character “&” literally
   |        # Or match regular expression number 2 below (attempting the next alternative only if this one fails)
      \\W   # Match a single character that is a “non-word character”
   |        # Or match regular expression number 3 below (the entire group fails if this one fails to match)
      \$    # Assert position at the end of the string (or before the line break at the end of the string, if any)
)

Output:

Results

like image 120
FailedDev Avatar answered Feb 24 '26 20:02

FailedDev