PHP - RegEx获取推文的最后一个hashtags部分

时间:2014-08-10 15:21:37

标签: php regex twitter

请发布以下示例发布的推文:

any #kind of @characters here #hashtag1 #stunning #hasthag2 [just punctuation here]*
any #kind of @characters here #hashtag1 #hashtag2 #stunning [just punctuation here]*
any #kind of @characters here #stunning #hashtag1 #hashtag2 [just punctuation here]*

我需要一个regural表达式,它返回推文的最后一部分,即结尾的n + hashtag,知道其中一个(在任何位置)将是一个已知的(例如#stunning)。

我目前的实施是:

(.*)(((#[^\s]+)[ ]?)*(#stunning)[ ]?((#[^\s]+)[ ]?)*)([\W]*)

http://regex101.com/r/rX3kM1/1

PHP代码:

$tweet = "any #kind of @characters here #hashtag1 #hashtag2 #stunning !!?!?...";
preg_match("/(.*)(((#[^\s]+)[ ]?)*(#stunning)[ ]?((#[^\s]+)[ ]?)*)([\W]*)/", $tweet, $match);
print_r($match);

输出:

Array
(
    [0] => any #kind of @characters here #hashtag1 #hashtag2 #stunning !!?!?...
    [1] => any #kind of @characters here #hashtag1 #hashtag2
    [2] => #stunning
    [3] =>
    [4] =>
    [5] => #stunning
    [6] =>
    [7] =>
    [8] => !!?!?...
)

Desidered Output:

Array
(
    [0] => any #kind of @characters here #hashtag1 #hashtag2 #stunning !!?!?...
    [1] => any #kind of @characters here 
    [2] => #hashtag1 #hashtag2 #stunning
    ...
)

5 个答案:

答案 0 :(得分:1)

如果我理解正确,以下正则表达式应该这样做:

^(.*?)((?:#\w+\W*)*(?:#stunning)\W*?(?:#\w+\W*?)*)(\W*)$

http://regex101.com/r/rX3kM1/5

它匹配#stunning的最后一次出现以及之前和之后的任何主题标签。在它们之间和最后一个之后只允许使用非单词字符。

最后一个hastags在第2组,第1组之前的文本和最后一个之后的标点符号在第3组。

答案 1 :(得分:1)

如果要符合条件,您的主题标签组必须同时

  1. 其中有#stunning
  2. 是句子中的最后一组主题标签(后跟任何内容)
  3. 您可以使用:

    (?=.*#stunning)#\w+(?:\s+#\w+)*(?!.*\s#\w)
    

    <强>解释

    • (?=.*#stunning)确保强制主题标签在混合
    • #\w+抓取第一个#标签
    • (?:\s+#\w+)*
    • 之后直接获取 的可能标签
    • (?!.*\s#\w)确保之后没有留下任何标签

    请参阅demo here

    如果您希望仅在结束标签组后面允许使用标点符号,则可以将(?!.*\s#\w)替换为(?=\W*$)(?=[\s:!;.?...]*$) - 具体取决于您所谓的“标点符号”。

答案 2 :(得分:0)

我还没有完全理解你的问题,但如果你想获得最后一个标签,你可以使用这个正则表达式:

.*(#\w+)

<强> Working demo

enter image description here

答案 3 :(得分:0)

<?php
$str  = "any kind of characters here #hashtag1 #stunning #hasthag2 !❤";
preg_match("/([a-z ]+)((#\w+ ))((#\w+ ))((#\w+ ))(!.)/", $str, $matches);
print_r($matches);
?>

Output:
Array ( 
[0] => any kind of characters here #hashtag1 #stunning #hasthag2 !â
[1] => any kind of characters here 
[2] => #hashtag1 
[3] => #hashtag1 
[4] => #stunning 
[5] => #stunning 
[6] => #hasthag2 
[7] => #hasthag2 
[8] => !â 
) 

我相信默认情况下preg_match会将完全匹配作为匹配数组中第一个索引的值。所以你必须删除这个索引,并在匹配和中提琴上运行array_unique!

答案 4 :(得分:-1)

我想这应该这样做:

(.*?)(#.*)\s(?!#)(.*)