Search code examples
phppreg-match

Validating a RewriteRule line using preg_match_all() function


I am trying to validate a RewriteRule line using preg_match_all(),

Here is the line I am trying to validate to :

RewriteRule ^(.*)$ /edt.php

and this is my regex pattern so far :

RewriteRules\s+[^s]+\s+[^s]+\s+([NC,NE,L,R])?/i

The last argument [NC,NE,L,R] is optional in the line.

My complete code with php

$x="RewriteRule ^(.*)$ /edt.php ";

if(preg_match_all("/RewriteRules\s+[^s]+\s+[^s]+\s+([NC,NE,L,R])?/i",$x,$m))
{echo "Line is ok";}
else
{echo "There is something wrong with the line";}

This is not working, I am getting the "else" part of the code in my output. I believe there is something wrong with the pattern , I have already wasted 20mnts trying to solve it by myself, but I could not find where exectly the fault is.

Any help is much appriciated.


Solution

  • There's a lot I don't understand about this question, but I will do what I can to try and help you out here.

    Let's start with your string:

    RewriteRule ^(.*)$ /edt.php
    

    This can be matched a number of ways, but I will just give you a general approach to doing it and show you a couple of potential errors that you have.

    It as though you are just matching a pattern like this:

    RewriteRule SPACE SOMETHING SPACE SOMETHING SPACE OPTIONAL_DATA_WITH BRACKETS
          1       2       3       4       5       6                 7
    

    Here is a regular expression that matches this:

    ^RewriteRule  \s+  .*?  \s+  .*?  (?:$|\s+  \[[A-Z,]+\])
         1         2    3    4    5       6           7   
    

    I have added in whitespace to my expression simply to make it easier to read. There should be no actual space characters in this expression.

    1. ^RewriteRule Simply matching the phrase. We use the ^ to anchor it to the beginning of the line.
    2. \s+ Requiring at least one space before the next item. This is already what you are using.
    3. .*? This is kind of a catch-all that can be refined down to whatever specifics you wish. But for this purpose, I am just saying to match any character ., any number of times *, until you hit the next item to match ?. In this case, the next item is a whitespace character.
    4. \s+ Requiring at least one space before the next item
    5. .*? Matching any character, any number of times until the next item.
    6. (?:$|\s+ This may look like a mess, but it's really just matching either the end of the line or a whitespace character. (?: is made up of two parts that just says to start a new group (, but don't remember it ?:. I am following that with a line ending $ or | a space \s+.
    7. \[[A-Z,]+\]) This last bit of the expression is simply matching a literal opening square brace [, followed by a character class consisting of letters or a comma [A-Z,] and requiring at least one of them to be present +. I'm closing it out with an ending square brace ] and the closing parenthesis ) for the "or".

    This can be fine-tuned quite a bit, but here is a demo for you to play around with:

    https://regex101.com/r/qF7bP6/1

    Errors:

    You have a couple of items that I can tell right away are going to throw off your match.

    I can see that you are checking for RewriteRules instead of RewriteRule.

    Additionally, you are matching the RewriteRule Flags in square braces like this [NC,NE,L,R]. Square braces are special characters in regular expressions, so you're actually attempting to matching an optional single character which must be either a comma or one of the following letters: N, C, E, L or R.

    Finally, you are requiring a space after the URL, even if there is no RewriteRule flag present. There may be more, but those are the ones that jumped out at me.