Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/240.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 查找字符串中的hashtags和标记用户_Php - Fatal编程技术网

Php 查找字符串中的hashtags和标记用户

Php 查找字符串中的hashtags和标记用户,php,Php,我正在从事一个项目,并试图增加检测hashtags和标记用户的能力 问题是我不知道如何让它在达到符号或表情符号(下划线除外)时停止阅读,并且不让长度超过20个字符 用于哈希标记 $words = explode(" ", $body); foreach($words as $word){ if(substr($word, 0, 1) == "@"){ $tagged_user = DB::query('SELECT id

我正在从事一个项目,并试图增加检测hashtags和标记用户的能力

问题是我不知道如何让它在达到符号或表情符号(下划线除外)时停止阅读,并且不让长度超过20个字符

用于哈希标记

$words = explode(" ", $body);

        foreach($words as $word){
            if(substr($word, 0, 1) == "@"){
                $tagged_user = DB::query('SELECT id FROM users WHERE username=:username', array(':username' => ltrim($word, '@')))[0];
                $users .= $tagged_user,",";
            }
        }

        $users = rtrim($users, ',');
#HelloWorld->HelloWorld,#你好#你好#你好#你好#你好#你好#你好#你好#

也适用于标记用户(仅允许A-Z A-Z 0-9和_

@HelloWorld->HelloWorld,@Hello\u W0rl.d->Hello\u W0rl

我尝试的代码是 (对于用户或哈希标签基本相同)

它还会知道不要将
#%
保存为空白吗

编辑: 我更新到这个了,对吗

$postid = "test_id";
        $matches = [];
        preg_replace_callback("/#([a-z_0-9]+)/i", function($res) use(&$matches) {
            $matches[] = strtolower($res[1]);
        }, $body);

        $matches2 = [];

        $tagholder = array_fill(0, count($matches), "?");
        $tagholderString = implode(", ", $tagholder);

        foreach($matches as $tagstring){
            if(DB::query('SELECT * FROM tags WHERE tag=:tag', array(':tag' => $tagstring))){
                $tag = DB::query('SELECT * FROM tags WHERE tag=:tag', array(':tag' => $tagstring))[0];
                DB::query ( "INSERT INTO post_tags VALUES(:tagid, :postid)", array (':tagid' => $tag['id'], ':postid' => $postid) );
            }else{
                $id = hash(sha256, $tagstring);
                DB::query ( "INSERT INTO tags VALUES(:id, :tag, :mode)", array (':id' => $id, ':tag' => $tagstring, ':mode' => 0) );
                DB::query ( "INSERT INTO post_tags VALUES(:tagid, :postid)", array (':tagid' => $id, ':postid' => $postid) );
            }
        }

        preg_replace_callback("/@([a-z_0-9]+)/i", function($res) use(&$matches2) {
            $matches2[] = strtolower($res[1]);
        }, $body);

        $userholder = array_fill(0, count($matches2), "?");
        $userholderString = implode(", ", $userholder);
        $user_query = DB::query("SELECT * FROM users WHERE username IN (".$userholderString.")", $matches2);

        $users_result = "";
        foreach($user_query as $result){
            $users_result .= $result['id'].",";
        }
        $users_result = rtrim($users_result, ',');

        //User string result
        $users_result;

我刚刚编写的两个函数,希望对您有所帮助。使用regex提取hashtags和用户名。

您可以使用它将每个结果传递到。您需要创建一个模式,每个模式对应一个需求。对于hashtags:

/#([a-z_0-9]+)/i

对于标签:

/@([a-z_0-9]+)/i

对于每一个您要求以
@
#
开头的字符,然后出现一个或多个字母、数字或下划线,不区分大小写

生成的代码如下所示:

$matches = [];
$string = "#HelloWorld -> helloworld, #Hello_W0rld -> hello_w0rld, #Hello(World -> hello,";

preg_replace_callback("/#([a-z_0-9]+)/i", function($res) use(&$matches) {
    $matches[] = strtolower($res[1]);
}, $string);

var_dump($matches);

$matches2 = [];
$string2 = "@HelloWorld -> helloworld, @Hello_W0rl.d -> hello_w0rl,";

preg_replace_callback("/@([a-z_0-9]+)/i", function($res) use(&$matches2) {
    $matches2[] = strtolower($res[1]);
}, $string2);

var_dump($matches2);
$placeholders = array_fill(0, count($matches), "?"); // get a ? for each match
$placeholdersString = implode(", ", $placeholders); // make it a string
DB::query("SELECT id FROM users WHERE username IN (".$placeholderString.")", $matches); // bind each value

结果:

数组(大小=3)
0=>字符串“helloworld”(长度=10)
1=>字符串“hello_w0rld”(长度=11)
2=>字符串“hello”(长度=5)

数组(大小=2)
0=>字符串“helloworld”(长度=10)
1=>字符串“hello_w0rl”(长度=10)


作为补充说明,您不应该对找到的每个标记进行查询。这将很快失控,并可能严重影响数据库性能。由于所有标记都在一个数组中,因此只需使用
WHERE in
子句进行一次查询,如下所示:

$matches = [];
$string = "#HelloWorld -> helloworld, #Hello_W0rld -> hello_w0rld, #Hello(World -> hello,";

preg_replace_callback("/#([a-z_0-9]+)/i", function($res) use(&$matches) {
    $matches[] = strtolower($res[1]);
}, $string);

var_dump($matches);

$matches2 = [];
$string2 = "@HelloWorld -> helloworld, @Hello_W0rl.d -> hello_w0rl,";

preg_replace_callback("/@([a-z_0-9]+)/i", function($res) use(&$matches2) {
    $matches2[] = strtolower($res[1]);
}, $string2);

var_dump($matches2);
$placeholders = array_fill(0, count($matches), "?"); // get a ? for each match
$placeholdersString = implode(", ", $placeholders); // make it a string
DB::query("SELECT id FROM users WHERE username IN (".$placeholderString.")", $matches); // bind each value

可能是
[@#]\w{1,20}
preg#u match
匹配。这是
/
计入20的吗?百分比符号从何而来?我更新了我的帖子,尝试了你的代码,我做得对吗,也没有影响数据库性能?