使用正则表达式

时间:2017-06-28 13:01:17

标签: php regex string preg-replace

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

现在我有以下内容:

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

输入(删除粗体): 不管它是什么,都不应该删除字符串中间的任何#hashtag,例如#DoNotRemoveThis #KeepThisHashtag和字符串末尾的任何#标签应该被删除,除非它与正则表达式中的exeptions匹配。 #delethishis #DoNotRemoveThis #tustustgoawa y

通缉输出: 不管它是什么,都不应该删除字符串中间的任何#hashtag,例如#DoNotRemoveThis #KeepThisHashtag和字符串末尾的任何#标签应该被删除,除非它与正则表达式中的exeptions匹配。 #DoNotRemoveThis

唯一的问题是它还删除了字符串中间未指定的主题标签 - 我希望字符串中的所有主题标签保持不变,并删除末尾的所有主题标签(除了排除的标签)。

请参阅实例,以便更好地理解:https://regex101.com/r/A0Ebor/1

2 个答案:

答案 0 :(得分:1)

您可以使用

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

请参阅regex demo

<强>详情

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

最后的/i会使模式不区分大小写。

我假设hastags以单词char结尾,因此\b。如果您想匹配任何主题标签,请删除,但 hashtagDoNotRemoveThis开头。

u UNICODE修饰符使得正则表达式能够很好地处理输入字符串中的所有Unicode字母和数字,并使\w识别Unicode(它将匹配所有Unicode字母,数字和{{ 1}} char)。

如果我们要谈论优化增强模式效率,在PCRE中,检查_和{{1}是否合理} 之后我们匹配hashtag后面跟着单词/连字符字符。但是,为了使其有效,我们需要

  • 将外观拆分为几个,就像在PCRE正则表达式中一样,不可能使用替换(它使得后视长度未知,并且不支持这样的外观)
  • 使用DoNotRemoveThis模式上的原子组,即。 #,或占有量词#[\w-]+(即(?>#[\w-]+),禁止回溯到模式中。

所以,你可以使用卡西米尔答案中的模式,或原子组变体:

++

请参阅another regex demo

答案 1 :(得分:1)

你可以使用这个:

~#[\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
~