2

I'm currently fighting with regex to achieve something and can't success by myself ...

Here my string: path/to/folder/@here
What I want is something like this: a:path/a:to/a:folder/@here

So my regex is the following one : /([^\/]+)/g, but the problem is that the result will be (preg_replace('/([^\/@]+)/', 'a:$0'): a:path/a:to/a:folder/a:@here ...

How can I had skip the replace if the captured group contains @ ?

I tried this one, without any success : /((?!@)[^\/]+)/g

dawg
  • 90,796
  • 20
  • 120
  • 197
FBHY
  • 995
  • 1
  • 15
  • 32

2 Answers2

2

Another option could be to match what you want to avoid, and use a SKIP FAIL approach.

/@[^/@]*(*SKIP)(*F)|[^/]+
  • /@ Match literally
  • [^/@]*(*SKIP)(*F) Optionally match any char except / and @ and then skip this match
  • | Or
  • [^/]+ Match 1+ occurrences of any char except /

See a regex demo and a PHP demo.

For example

$str = 'path/to/folder/@here';
echo preg_replace('#/@[^/@]*(*SKIP)(*F)|[^/]+#', 'a:$0', $str);

Output

a:path/a:to/a:folder/@here
The fourth bird
  • 127,136
  • 16
  • 45
  • 63
1

You can use

(?<![^\/])[^\/@][^\/]*

See the regex demo. Details:

  • (?<![^\/]) - a negative lookbehind that requires either start of string or a / char to appear immediately to the left of the current location
  • [^\/@] - a char other than / and @
  • [^\/]* - zero or more chars other than /.

See the PHP demo:

$text = 'path/to/folder/@here';
echo preg_replace('~(?<![^/])[^/@][^/]*~', 'a:$0', $text);
// => a:path/a:to/a:folder/@here
Wiktor Stribiżew
  • 561,645
  • 34
  • 376
  • 476