Ozzy
Ozzy

Reputation: 10643

REGEX Match everything but / which starts with :

i am writing a regular expression which should do the following:

Match everything which is not a /
Dont match if matched segment starts with :

Example:

asdjhas/*fdjkl*/sdfds:dsfsdf/:sdff/sdffff

The bolded parts should match with the regex. As you can see, all forward slashes are not matched as well as the part which starts with a : only.

I have come up with this: ([^/]+) which works as intended except it will also match parts that start with :. I tried using negative lookahead assertions but to be honest, i really do not understand them.

I am also using PHPs preg library to do the matching for me.

Thanks

Upvotes: 3

Views: 1328

Answers (3)

HamZa
HamZa

Reputation: 14931

Another easy way is just to use preg_split() instead:

$string = 'asdjhas/fdjkl/sdfds:dsfsdf/:sdff/sdffff';
$m = preg_split('/\/(:[^\/]*\/?)?/', $string);
print_r(array_filter($m));

Results:

Array
(
    [0] => asdjhas
    [1] => fdjkl
    [2] => sdfds:dsfsdf
    [3] => sdffff
)

Upvotes: 0

Tomalak
Tomalak

Reputation: 338308

You could split the string on

/(?::[^/]+/*)?

i.e.

$string = 'asdjhas/*fdjkl*/sdfds:dsfsdf/:sdff/sdffff';

$parts = preg_split('#/(?::[^/]+/*)?#', $string);

/*
Array
(
    [0] => asdjhas
    [1] => *fdjkl*
    [2] => sdfds:dsfsdf
    [3] => sdffff
)
*/

Upvotes: 1

Explosion Pills
Explosion Pills

Reputation: 191779

I think that this is what you need, and it does work with your test string:

preg_match_all('@
   (?:    # start group
     ^    # start of string
     |    # OR
     /    # slash character
    )     # end grouping
    (     # start capture
    [^:/] # character class of anything except colon and slash
    .*?   # anything until...
    )     # end capture
    (?=   # start lookahead
    /     # literal slash (lookahead is used so it is not consumed
          # which allows a slash to be used to start the next group)
    |     # OR
    $     # end of the string
    )     # end lookahead
    @x', $str, $matches);

Edit: using lookbehind (?<= instead of (?: seems to work just fine too.

Upvotes: 2

Related Questions