使用正则表达式删除字符串末尾除指定主题标签之外的所有主题标签

Remove all but specified hashtags at the end of a string using regex

我有一个正则表达式,几乎可以按我的意愿工作,但我需要有关如何仅在字符串末尾删除除选定主题标签之外的所有主题标签的建议。

现在我有以下内容:

preg_replace('/(?!#hashtag|#DoNotRemoveThis)(#[\w-]+)/', '', $post_caption);

输入(去除粗体): 字符串中间的任何#hashtag 都不应删除,无论它是什么,例如#DoNotRemoveThis #KeepThisHashtag 和字符串末尾的任何#hashtag 都应删除,除非它与正则表达式中的例外匹配。 #deletethis #DoNotRemoveThis #thismustgoaway

想要的输出: 字符串中间的任何#hashtag 都不应删除,无论它是什么,例如#DoNotRemoveThis #KeepThisHashtag 和字符串末尾的任何#hashtag 都应删除,除非它与正则表达式中的例外匹配。 #DoNotRemoveThis

唯一的问题是它还会删除字符串中间未指定的主题标签——我希望字符串中的所有主题标签都保持完整,最后的所有主题标签(排除的主题标签除外)都是已删除。

请查看实例以更好地理解:https://regex101.com/r/A0Ebor/1

您可以使用

'/#(?!(?:hashtag|DoNotRemoveThis)\b)[\w-]+(?=(?:\s+#[\w-]+)*\s*$)/iu'

参见regex demo

详情

  • # - 哈希符号
  • (?!(?:hashtag|DoNotRemoveThis)\b) - 如果 hashtagDoNotRemoveThis 后跟单词边界
  • ,则匹配失败
  • [\w-]+ - 1 个或多个单词字符或连字符
  • (?=(?:\s+#[\w-]+)*$) - 只有 return 一个匹配项,如果紧靠当前位置的右侧,有:
    • (?:\s+#[\w-]+)* - 零个或多个序列:
      • \s+ - 1+ 空格
      • #[\w-]+ - 哈希 + 一个或多个单词字符或连字符
    • \s* - 0+ 个空格(如果有尾随空格)
    • $ - 字符串结尾(可以换行,如果不需要,替换为 \z

末尾的 /i 将使模式不区分大小写。

我假设 hastags 以单词 char 结尾,因此 \b。如果您想匹配任何标签,但 hashtagDoNotRemoveThis.

开头的标签,请删除

u UNICODE 修饰符使正则表达式可以很好地处理输入字符串中的所有 Unicode 字母和数字,并且还使 \w Unicode 感知(它将匹配所有 Unicode 字母、数字和_ 个字符)。

如果我们要谈论优化提高模式效率,在 PCRE 中,执行检查 hashtagDoNotRemoveThis 之后,我们匹配 # 后跟 word/hyphen 个字符。但是,要让它发挥作用,我们需要

  • 将 lookaround 分成几个部分,因为在 PCRE 正则表达式中不可能使用交替(它使得 lookbehind 长度未知并且不支持这样的 lookbehinds)
  • #[\w-]+ 模式上使用原子组,即。 (?>#[\w-]+),或所有格量词 ++(即 #[\w-]++ 禁用回溯到模式中。

因此,您可以使用 Casimir 的回答中的模式或原子组变体:

'/#(?>[\w-]+)(?<!#hashtag|#DoNotRemoveThis)(?=(?:\s+#[\w-]+)*\s*$)/ui'

参见 another regex demo

你可以使用这个:

~#[\w-]++(?<!#hashtag|#DoNotRemoveThis)(?=(?:\s+#[\w-]+)*+\s*$)\s*~

demo

详情:

~
#[\w-]++   # match a hashtag (and forbids backtracking using a possessive quantifier)
(?<!#hashtag|#DoNotRemoveThis) # check if the tag isn't forbidden
(?=(?:\s+#[\w-]+)*+\s*$) # check if the tag is followed by eventual other tags until the end
\s* # match an eventual trailing whitespace
~