Home > Blockchain >  Exclude part of string - PHP Regex
Exclude part of string - PHP Regex

Time:03-10

Cases and desired outputs:

/order/list/edit/1          => true
/order/list/item            => false
/order/list/1/item          => false
/order/list/1/item/2/edit   => false

my current solution:

/order\/list\/(?:(?!item).)/

current output:

/order/list/edit/1          => true
/order/list/item            => false
/order/list/1/item          => true
/order/list/1/item/2/edit   => true

Any idea to solve this problem?

Code to test:

$regex = "/order\/list\/(?:(?!item).)/";
$urls = [
    '/order/list/edit/1',
    '/order/list/item',
    '/order/list/1/item',
    '/order/list/1/item/2/edit'
];

echo $regex . '<br>';
foreach ($urls as $url) {
    echo (preg_match($regex, $url) ? 'true' : 'false') . " - " . $url . '<br>';
}

the regex should return true for all strings that start with "/order/list/" and have no "item" after that

CodePudding user response:

You're missing a semicolon (:) after the exclamation point (!) in your regex and the asterisk (*) to repeat the check for all subsequent characters. As beautifully explained in this answer, the correct syntax to exclude a word is

(?:(?!:word).)*

Furthermore, to make everything more readable when you use regex to match URLs, I suggest to use a different delimiter, for example you could use the @. This allows you to write your URL without escaping the slash (just / instead of \/).

I would also recommend to use the Start ^ and End $ characters to make sure that /order/list/ is indeed the first thing in your URL.

Here's the complete regex based on the observations above

@^/order/list/((?!item).)*$@

So in PHP

$regex = "@^/order/list/((?!item).)*$@";

And this will output

true - /order/list/edit/1

false - /order/list/item

false - /order/list/1/item

false - /order/list/1/item/2/edit

  • Related