使用lookahead和lookbehind在正则bbcode之间忽略一个单词



我想在此处扩展特定代码:

/(?<![@#]|([img]))b(".str_replace(" ", "[-_ ]", $key).")(?![/img])b/i

当前,它检测到@还是#是否直接在有关的$key后面(很好),或者[img][/img]是否直接在$key之前/之后(问题)。我想添加一个通配符,以便无法更换[img][/img]之间的任何地方的$key,同时仍然保持@#仍然必须直接在$key后面的事实。我知道不允许通配符在外观上。

这是可能的吗?

编辑:我对自己的代码进行了误解。我意识到,即使[img]没有先于单词,[/img]仍然会触发,从而允许@BLUE[/img]不触发。我希望将#/@[img][/img]之间的案例分开。对此的帮助也将有很大帮助。

基本上,[img][/img]中的所有内容都将忽略$key@$key#$keypreg_replace。但是,即使是独立的@$key#$key(没有[img]标签),$key也不应更换。

使用Lookarounds不是一个好方法

目标是跳过[img]标签之间的内容,让我们看看:

$result = preg_replace('~[(img|url)].*?[/1](*SKIP)(*FAIL)|(?<![@#])bHELLOb~s',
                       'GOODBYE', $str);

(*SKIP)禁止在右侧副本失败时重试符合左侧的字符串部分。

(*FAIL)迫使模式失败。

由于 [img]标签总是首先是由模式的第一个分支尝试的,因此模式的第二个分支匹配始终在[img]标签外的字符串部分。

另一种方式

您可以将您搜索的密钥描述为一个词,该单词是几个[img]..[/img]和其他不是[img]标签或关键词的字符:

$pattern = <<<'LOD'
~
(?>                      # atomic group: all possible content before "HELLO"
    (?>                      # other characters
        [^[H]++                  # all characters except [ and H
      |                        # OR
        [(?!img]|url])          # a [ not followed by img or url
      |                        # OR
        BH                      # an H not preceded by a word boundary
      |                        # OR
        H(?!ELLOb)              # an H not followed by ELLO and a word boundary
    )+
  |                        # OR
    [(img|url)].*?[/1]    # img or url tags
)*
K                       # resets all from the match result
(?<![@#])HELLO
~sx
LOD;

最新更新