Php 使用regex删除字符串末尾的所有hashtag(指定的hashtag除外)

Php 使用regex删除字符串末尾的所有hashtag(指定的hashtag除外),php,regex,string,preg-replace,Php,Regex,String,Preg Replace,我有一个regex表达式,几乎可以按照我的意愿工作,但是我需要关于如何删除字符串末尾的所有hashtag(除了选定的hashtag)的建议 现在我有以下几点: preg_replace('/(?!#hashtag|#DoNotRemoveThis)(#[\w-]+)/', '', $post_caption); 输入(删除粗体): 无论字符串是什么,都不应该删除字符串中间的任何一个哈希标记,例如,如果不匹配ReXEX中的ExpEx,则应该删除该字符串的结尾处的任何哈希标记和字符串末尾的任何哈希

我有一个regex表达式,几乎可以按照我的意愿工作,但是我需要关于如何删除字符串末尾的所有hashtag(除了选定的hashtag)的建议

现在我有以下几点:

preg_replace('/(?!#hashtag|#DoNotRemoveThis)(#[\w-]+)/', '', $post_caption);
输入(删除粗体): 无论字符串是什么,都不应该删除字符串中间的任何一个哈希标记,例如,如果不匹配ReXEX中的ExpEx,则应该删除该字符串的结尾处的任何哈希标记和字符串末尾的任何哈希标记。strong>#删除此#不要删除此#此必须为y

想要的输出: 无论字符串是什么,无论字符串是什么,都不应该移除它,例如,在这个字符串的结尾处的任何一个哈希标记都应该被移除,除非它匹配正则表达式中的ExpEx。DoNotRemoveThis

唯一的问题是它还删除了字符串中间的未指定的哈希标记——我希望字符串中的所有哈希标记保持完整,并且在结尾(除被排除的部分之外)的所有标签都要删除。 请参阅实时示例以了解更多信息:

您可以使用

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

详细信息

  • #
    -哈希符号
  • (?!(?:hashtag | DoNotRemoveThis)\b)
    -如果有
    hashtag
    DoNotRemoveThis
    后跟单词边界,则匹配失败
  • [\w-]+
    -1个或多个单词字符或连字符
  • (?=(?:\s+#[\w-]+)*$)
    -仅在当前位置右侧出现以下情况时返回匹配项:
    • (?:\s+#[\w-]+)*
      -零个或多个以下序列:
      • \s+
        -1+空格
      • #[\w-]+
        -哈希+一个或多个单词字符或连字符
    • \s*
      -0+空格(如果有尾随空格)
    • $
      -字符串结尾(可以换行,如果不需要换行,则替换为
      \z
结尾的
/i
将使模式不区分大小写

我假设hastags以单词char结尾,因此,
\b
。如果要匹配除以
hashtag
开头的hashtag以外的任何hashtag,请将其删除

u
UNICODE修饰符使正则表达式能够很好地处理输入字符串中的所有UNICODE字母和数字,并且使
\w
UNICODE感知(它将匹配所有UNICODE字母、数字和
\ucode>字符)

如果我们要在PCRE中谈论优化和提高模式效率,那么在匹配
#
后面的单词/连字符后,检查
hashtag
DoNotRemoveThis
是有意义的。然而,为了让它发挥作用,我们需要

  • 将lookbehind拆分为多个,因为在PCRE正则表达式中,不可能使用替换(它使lookbehind长度未知,并且不支持此类lookbehind)
  • .[\w-]+
    模式上使用一个原子组,即
    (?>.[\w-]+)
    ,或所有格量词
    +
    (即
    .[\w-]+
    ,它禁用对模式的回溯
因此,您可以使用Casimir答案中的模式,或原子群变体:

'/#(?>[\w-]+)(?<!#hashtag|#DoNotRemoveThis)(?=(?:\s+#[\w-]+)*\s*$)/ui'
'/#(?>[\w-]+)(?您可以使用这个:

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

详情:

~
#[\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
~
~
#[\w-]++#匹配哈希标记(并禁止使用所有格量词回溯)

(?
/(?!#hashtag |##DoNotRemoveThis)(#[\w-]+)$/
尝试在RegexOk的末尾添加一个美元符号(表示字符串的结尾),我明白了:末尾的一系列hashtag意味着。@WiktorStribiż是的,我想删除#删除此和#此mustgoway。其他hashtag应该保持不变。在您的示例中,尝试最后的第三个hashtag(#删除此项)不应该被删除,对吗?因为它不在字符串的末尾…那么你为什么给它命名#deletethis?请澄清它工作得很好-但是有一个问题:我应该在正则表达式中的什么位置放置/I以使其不区分大小写?请参阅我的更新,只需在尾部
/
@AbrahamMurcianoBenzadon之后添加
I
修饰符即可因为
hashtag | DoNotRemoveThis
包含字母。添加一个
u
修饰符,
/iu
@WiktorStribiż谢谢,您的详细解释也非常感谢!这基本上与我的模式相同。您可以在我的答案下面添加一条注释。而且由于外观落后和占有欲强,它的可移植性较差模式中的标识符。不是真的,主要区别是这一个是有效的。如果你认为我的答案只是你的一个副本,请随意标记它。