Jay Zus
Jay Zus

Reputation: 573

Regex matching doesn't work as expected

I'm trying to match every string (url) starting with "string" and not ending in -[number]

So I made this regex

string/?.*(?!-[0-9]*)

which, for what I understood, is supposed to be read as:

match every string starting with "string", having possibly a '/' after it, having any string after it not including '-' followed by any number or numbers.

here's my test strings

string/kkk/aaa/sss/ddd-123
string/kkk/aaa/sss/ddd
string/kkk/aaa/sss
string/kkk/aaa
string/kkk
string/
string/kkk/
string/kkk/aaa/
string/74002

the regex just match everything, no matter what.

Could someone tell me where I went wrong ?

Upvotes: 1

Views: 488

Answers (3)

Kami
Kami

Reputation: 19457

In your expression you have added .* at the before the lookahead.

This means * will skip all available characters matching . before proceeding to the next step - This in essence is everything and hence your expression matches everything. This is usually used when you want to return everything after a pattern.

You need to move the .* in to the lookahead statement or use a non-greedy version.

Try something like

^string/?(?!.+?-\d+$).*

The above will match all string that do not end with - and digits. It will also return the entire string for instances where the pattern is matched. I have used the non-greedy .+? here to avoid confusion as well as adding the ^ start and $ end of line selectors. The .* matches all the characters if the pattern is successful.

Upvotes: 2

Prasanth Bendra
Prasanth Bendra

Reputation: 32840

Try this :

$str  = "string/kkk/aaa/sss/ddd123";
echo preg_match("/^string\/(?!.*-\d+$)/",$str);

Upvotes: 0

Mario
Mario

Reputation: 36567

Your problem is you don't force the regular expression to match the whole string.

For example, take this line:

string/kkk/aaa/sss/ddd-123

In this case .* will simply match everything after string/ including the -123. A non-greedy match would match everything excluding the d-123. In either case it succeeds in not finding what's given in the negative lookahead.

You'll have to force the regular expression to match the string end ($) (and probably the string start (^) as well:

^string/?.*(?!-[0-9]*)$

Upvotes: 0

Related Questions