正则表达式 - 如果包含另一个单词,则不捕获单词

时间:2021-07-15 16:20:54

标签: php regex

我目前正在与正则表达式斗争以实现某些目标,但我自己无法成功......

这里是我的字符串:path/to/folder/@here
我想要的是这样的:a:path/a:to/a:folder/@here

所以我的正则表达式如下:/([^\/]+)/g,但问题是结果将是 (preg_replace('/([^\/@]+)/', 'a:$0'): a:path/a:to/a:folder/a:@here ...

如果捕获的组包含 @,我如何跳过替换?

我尝试了这个,但没有成功:/((?!@)[^\/]+)/g

2 个答案:

答案 0 :(得分:2)

另一种选择是匹配您想要避免的内容,并使用 SKIP FAIL 方法。

/@[^/@]*(*SKIP)(*F)|[^/]+
  • /@ 逐字匹配
  • [^/@]*(*SKIP)(*F) 可选择匹配除 /@ 之外的任何字符,然后跳过此匹配
  • |
  • [^/]+ 匹配 1+ 次出现的任何字符,除了 /

看到一个 regex demo 和一个 PHP demo

例如

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

输出

a:path/a:to/a:folder/@here

答案 1 :(得分:1)

你可以使用

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

参见regex demo详情

  • (?<![^\/]) - 负向后视,需要字符串开头或 / 字符立即出现在当前位置的左侧
  • [^\/@] - 除 /@ 之外的字符
  • [^\/]* - 除 / 之外的零个或多个字符。

PHP demo

$text = 'path/to/folder/@here';
echo preg_replace('~(?<![^/])[^/@][^/]*~', 'a:$0', $text);
// => a:path/a:to/a:folder/@here