使用php解析文本中的hashtag并将其替换为链接

9

我有一些带Twitter风格的#hashtags文本。如何编写一个函数来解析可能包含无限数量的#hashtags的文本主体,获取hashtag文本并用<a href="tag/[hashtag text]">[hashtag text]</a>替换它们所有的文本?

我想了很多如何做到这一点,但是我真的不擅长使用正则表达式编写这些函数。

示例文本:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus #tristique non elit eu iaculis. Vivamus eget ultricies nisi. Vivamus hendrerit at mauris condimentum scelerisque. Donec nibh mauris, pulvinar et #commodo a, porta et tellus. Duis eget ante gravida, convallis augue id, blandit lectus. Mauris euismod commodo mi ut fringilla. Sed felis magna, rhoncus vitae mattis varius, sagittis a eros. Donec eget porta ipsum. #Mauris sed mauris ante. Suspendisse potenti. Donec a #pretium #augue, eget hendrerit orci. Integer cursus scelerisque consequat。


展示一个文本的例子,并展示该文本在解析后的结果。 - Brian
7个回答

22

需要在井号前加上一个空格字符,这样 #hashtag blah blah blah 就不会被捕获。 - jraede
1
+1 - 我忘记了单词字符\w,这比[^\s]更好。 - jraede
这在链接中带有井号的情况下不起作用。它会崩溃。 - Mike Barwick
@MikeBarwick - 原始问题没有提到这一点,但这是一个有效的观点,我已经更新了它来解决这个问题。 - Joe

4
这将适用于UTF-8编码文本,并在内容中显示标签前的#(哈希)符号。
preg_replace('/(\#)([^\s]+)/', ' <a href="tag/$2">#$2</a> ', $content);

1
我确认这适用于希腊字符(UTF-8),而上述解决方案仅适用于英文字符!谢谢。 - Theodoros80

1

试试这个:

preg_replace('/(\#)([^\s]+)/', '<a href="tag/$2">$2</a>', $your_content_here);

这将把这个:

This is a #hashtag

变成这个:

This is a <a href="tag/hashtag">hashtag</a>

假设您有:

$your_content_here = 'This is a #hashtag';

@Joe的正则表达式实际上更好 - 我的会让你在hashtag中使用逗号、句号或其他符号。当然,这取决于你如何定义“hashtag”。 - jraede

0

正确答案就是这个。有很多原因。 但最重要的是,你需要考虑你的字符串是否包含URL,否则所有其他答案都会失效。请参见下面的示例:

$text = "#test Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus #tristique non elit eu iaculis. Vivamus eget ultricies nisi. Vivamus hendrerit at mauris condimentum scelerisque. Donec nibh mauris, pulvinar et #commodo a, porta et tellus. Duis eget ante gravida, convallis augue id, blandit lectus. Mauris euismod commodo mi ut fringilla. Sed felis magna, rhoncus vitae mattis varius, sagittis a eros. Donec eget porta ipsum. #Mauris sed mauris ante. Suspendisse potenti. Donec a #pretium #augue, eget hendrerit orci. Integer cursus scelerisque consequat. http://www.example.com/#wdwd/dwdqwdqwdqw#dwqdqwdq";

$text = preg_replace('/(^|[\n\s])#([^\s"\t\n\r<:]*)/is', '$1<a href="http://twitter.com/search?q=%23$2">#$2</a>', $text);

echo $text;

虽然这是这里最好的答案,但它在我使用它的文本上仍然不能百分之百地工作。问题是,如果我的哈希标签直接跟在HTML标签后面,即如果文本是“<p>#whatever</p>”,那么它就找不到它。我想这是因为标签前没有空格?我该如何调整正则表达式以匹配呢? (如果这是一个愚蠢的问题,对不起,我从来没有真正学习过正则表达式) - Daniel Malmgren
请解释在模式中添加is模式修饰符的目的。 - mickmackusa

0

它将从文本中提取并添加到每个标签的链接,无论标签之间是否有空格。

$text = "#test Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus #tristique non elit eu iaculis. Vivamus eget ultricies nisi. Vivamus hendrerit at mauris condimentum scelerisque. Donec nibh mauris, pulvinar et #commodo a, porta et tellus. Duis eget ante gravida, convallis augue id, blandits.Repost#high#fashion#photography#Ishan#portart#photo#Shoot#EishaChopra#luxe#twisty#creative#destination#style#Actor#model#beauty#gorgeous#makeup#and#hair#kamaldeep#fashionista#trending ";
$text = preg_replace('/#(\w+)/', ' <a href="tag/$1">$1</a>', $text);
echo $text;

0

在阅读了页面上其他答案和评论之后,似乎有理由从构成标签字符串的内容中排除某些字符。即:

  1. 空格
  2. 大于号,它是HTML标记的开始
  3. 经典的英文标点符号(如果支持其他语言或场景,请调整必要的标点符号)

其他答案没有提到,我建议在井号符号前使用否定的单词边界。这将强制执行哈希表达式之前的字符不是单词字符。

代码:(演示)

$text = <<<TEXT
Vivamus #tristique non elit eu iaculis.
Donec nibh mauris, pulvinar et #commodo a, porta et tellus. 
Donec eget porta ipsum.#Mauris sed mauris ante.
Donec a #pretium #augue, eget hendrerit orci.
Interference of#hashtag
Hash in <a>#taggytag</a>
"Living my #bestlife"
TEXT;

echo preg_replace('/\B#([^\s<,.?!"]+)/', '<a href="tag/$1">$1</a>', $text);

输出:

Vivamus <a href="tag/tristique">tristique</a> non elit eu iaculis.
Donec nibh mauris, pulvinar et <a href="tag/commodo">commodo</a> a, porta et tellus. 
Donec eget porta ipsum.<a href="tag/Mauris">Mauris</a> sed mauris ante.
Donec a <a href="tag/pretium">pretium</a> <a href="tag/augue">augue</a>, eget hendrerit orci.
Interference of#hashtag
Hash in <a><a href="tag/taggytag">taggytag</a></a>
"Living my <a href="tag/bestlife">bestlife</a>"

如果模式中需要多字节支持,请添加“u”模式修饰符。/\B#([^\s<,.?!"]+)/u

-1
我结合了Joe和jraede的解决方案。
UTF-8安全和正确的标签格式(无逗号等):
preg_replace('~(\#)([^\s!,. /()"\'?]+)~', '<a href="tag/$2">#$2</a>', $text);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接