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
  • 98,345
  • 23
  • 131
  • 206
FBHY
  • 1,004
  • 1
  • 15
  • 35

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
  • 154,723
  • 16
  • 55
  • 70
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
  • 607,720
  • 39
  • 448
  • 563