regExp problem - string is matched but it should not match - php

iam trying to check if an user has permission to manage an group:
Expression (ou=|||) is the string I'm looking for
/^OU=|||$|,OU=|||$/i
On a string like "ou=whatever", it returns true (-:
I am sure it's a problem with the pipes, but I have no idea how to solve this.
I am using PHP 5.x with preg_match.

Pipes are metacharacters in a regular expression (meaning "or"). You need to escape them:
/^OU=\|{3}$|,OU=\|{3}$/i
Are you sure that you're using the start- and end-of-string anchors correctly? Right now, this regex will only match the strings
OU=|||
and
<any number of characters>,OU=|||

You need to escape the pipes and include some parenthesis for better readability:
/(^OU=\|\|\|$)|(,OU=\|\|\|$)/i

$has_permission = in_array('OU=|||', explode(',', $permission_string));

Related

PHP regex last occurrence of words

My string is: /var/www/domain.com/public_html/foo/bar/folder/another/..
I want to remove the root folder from this string, to get only public folder, because some servers have multiple websites inside.
My actual regex is: /^(.*?)(www|public_html|public|html)/s
My actual result is: /domain.com/public_html/foo/bar/folder/another/..
But i want to remove the last ocorrence, and get somethig like this: /foo/bar/folder/another/..
Thanks!
You have to use a greedy quantifier and to check if the alternative is enclosed between slashes using lookarounds:
/^.*(?<![^\/])(?:www|public(?:_html)?|html)(?![^\/])/
About the lookarounds: I use negative lookarounds with a negated character class to check if there is a slash or the limit of the string at the same time. This way you are sure that for instance html is a folder and not the part of another folder name.
I removed the s modifier that is useless. I removed the capture groups too since the goal is to replace all with an empty string.
The ? makes your expression non-greedy which is not actually what you want here. Try:
^(.*)(www|public_html|public|html)
which should keep going until the last match.
Demo: https://regex101.com/r/v5WbB3/1/

PHP regular expression with or operation

I would like to use a regex over strings like:
1-* or *-2.
This is what I've come up with so far:
"/(.*\-2)||(1\-.*)/"
but it doesn't seem to work - it returns true every time, regardless of my input string.
How can I create a regular expression to match these strings?
Try this (simplistic) version:
/(^1-|-2$)/
If you need to match more specific, add [0-9] at the corresponding positions and maybe another anchor (^$).
/(^1-[0-9]$|^[0-9]-2$)/
Try this ...
"/(.+-\2)|(\1-.+)/"
try this you need add ^ and $ to match the whole string:
/^(1-0|0-2)$/
or:
/^(1-.*|.*-2)$/
select whatever suits your needs

PHP PregEX for detecting a variant

I am trying to create a registry expression that will detect the following syntax in a string:
OPEN-BRACKET > ANYTHING > PLUS-OR-MINUS > CLOSE-BRACKET
Example String: NB###-#####-#####-###[#+]
Please note that the expression could be anywhere in the string and have multiple occurrences.
I have tried [(.+)(\+|-)] which doesn't seem to work as I imagined it to do in php, but does work in rubular.com
What would the expression be to return the string *and* whether it was a plus or minus?
I'd suggest the pattern:
"(\[(.+)(\+|-)\])"
The parentheses capture the whole group, the \ escapes the [ and ] characters, and also the + character, that, otherwise (when unescaped) have special meanings in regular expressions.
Maybe .+ consumes all due to the default greedyness? What happens if you anchor the string using ^\[(.+)(\+|-)\]$.
If you cannot anchor the string due to multiply occurrences, try using look-ahead feature. And if "ANYTHING" really can be anything, how do you distinguish an ANYTHING +] from a PLUS-OR-MINUS > CLOSE-BRACKET?
If neither plus nor minus is allowed in ANYTHING, go for \[([^+-]+)(\+|-)\].
Thanks for the help. I managed to figure out /\[([\$|a-zA-Z]+)(\+|-)\]/ works as i intended it to.

PHP Regex: match text urls until space or end of string

This is the text sample:
$text = "asd dasjfd fdsfsd http://11111.com/asdasd/?s=423%423%2F gfsdf http://22222.com/asdasd/?s=423%423%2F
asdfggasd http://3333333.com/asdasd/?s=423%423%2F";
This is my regex pattern:
preg_match_all( "#http:\/\/(.*?)[\s|\n]#is", $text, $m );
That match the first two urls, but how do I match the last one? I tried adding [\s|\n|$] but that will also only match the first two urls.
Don't try to match \n (there's no line break after all!) and instead use $ (which will match to the end of the string).
Edit:
I'd love to hear why my initial idea doesn't work, so in case you know it, let me know. I'd guess because [] tries to match one character, while end of line isn't one? :)
This one will work:
preg_match_all('#http://(\S+)#is', $text, $m);
Note that you don't have to escape the / due to them not being the delimiting character, but you'd have to escape the \ as you're using double quotes (so the string is parsed). Instead I used single quotes for this.
I'm not familar with PHP, so I don't have the exact syntax, but maybe this will give you something to try. the [] means a character class so |$ will literally look for a $. I think what you'll need is another look ahead so something like this:
#http:\/\/(.*)(?=(\s|$))
I apologize if this is way off, but maybe it will give you another angle to try.
See What is the best regular expression to check if a string is a valid URL?
It has some very long regular expressions that will match all urls.

problem with regular expressions php

/any_string/any_string/any_number
with this regular expression:
/(\w+).(\w+).(\d+)/
It works, but I need this url:
/specific_string/any_string/any_string/any_number
And I don't know how to get it. Thanks.
/(specific_string).(\w+).(\w+).(\d+)/
Though note that the .s in your regular expression technically match any character and
not just the /
/(specific_string)\/(\w+)\/(\w+)\/(\d+)/
This will have it match only slashes.
This one will match the second url:
"/(\w+)\/(\w+)\/(\w+)\/(\d+)/"
/\/specific_string\/(\w+).(\w+).(\d+)/
Just insert the specific_string in the regexp:
/specific_string\/(\w+)/(\w+)/\d+)/
Another variant with the outer delimiters changed to avoid extraneous escaping:
preg_match("#/FIXED_STRING/(\w+)/(\w+)/(\d+)#", $_SERVER["REQUEST_URI"],
I would use something like this:
"/\/specific_string\/([^\/]+)\/([^\/]+)\/(\d+)/"
I use [^\/]+ because that will match anything that is not a slash. \w+ will work almost all the time, but this will also work if there is an unexpected character in the path somewhere. Also note that my regex requires the leading slash.
If you want to get a little more complicated, the following regex will match both of the patterns you provided:
"/^(?:\/specific_string)*\/([^\/]+)\/([^\/]+)\/(\d+)$/"
This will match:
"/any_string/any_string/any_number"
"/specific_string/any_string/any_string/any_number"
but it will not match
"/some_other_string/any_string/any_string/any_number"

Categories