我有一个几乎可以正常使用的正则表达式,但我需要有关如何仅在字符串末尾删除所有选定主题标签的建议。
现在我有以下内容:
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
答案 0 :(得分:1)
您可以使用
'/#(?!(?:hashtag|DoNotRemoveThis)\b)[\w-]+(?=(?:\s+#[\w-]+)*\s*$)/iu'
请参阅regex demo。
<强>详情
#
- 哈希符号(?!(?:hashtag|DoNotRemoveThis)\b)
- 如果有hashtag
或DoNotRemoveThis
后跟字边界,则匹配失败[\w-]+
- 一个或多个单词字符或连字符(?=(?:\s+#[\w-]+)*$)
- 只返回当前位置右侧的匹配,有:
(?:\s+#[\w-]+)*
- 零个或多个序列:
\s+
- 1+空格#[\w-]+
- 哈希+一个或多个单词字符或连字符\s*
- 0+空格(如果有尾随空格)$
- 字符串结尾(可以使用换行符,如果不是预期的话,请替换为\z
)最后的/i
会使模式不区分大小写。
我假设hastags以单词char结尾,因此\b
。如果您想匹配任何主题标签,请删除,但以 hashtag
或DoNotRemoveThis
开头。
u
UNICODE修饰符使得正则表达式能够很好地处理输入字符串中的所有Unicode字母和数字,并使\w
识别Unicode(它将匹配所有Unicode字母,数字和{{ 1}} char)。
如果我们要谈论优化和增强模式效率,在PCRE中,检查_
和{{1}是否合理} 在之后我们匹配hashtag
后面跟着单词/连字符字符。但是,为了使其有效,我们需要
DoNotRemoveThis
模式上的原子组,即。 #
,或占有量词#[\w-]+
(即(?>#[\w-]+)
,禁止回溯到模式中。所以,你可以使用卡西米尔答案中的模式,或原子组变体:
++
答案 1 :(得分:1)
你可以使用这个:
~#[\w-]++(?<!#hashtag|#DoNotRemoveThis)(?=(?:\s+#[\w-]+)*+\s*$)\s*~
细节:
~
#[\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
~