【问题标题】:extract part of a string before and after a word在单词之前和之后提取字符串的一部分
【发布时间】:2012-09-19 16:38:41
【问题描述】:

我需要提取并显示一些beforeafter一个查询词,比如谷歌搜索结果,例如:

$str = "hi user! welcome to new php open source world, we are trying to learn you something!";
$query = "new php";
$result = "... welcome to new php open source ...";

我在 google 上搜索了一个 SO,但没有找到明确的答案,或者我的 php 知识还不够! 是否有一个可行且易于使用的功能来完成这项工作?

【问题讨论】:

  • 嗯,这有点模糊。 “一些话”是多少?每边总是 2 个?
  • 最好是动态的,静态的词也好,比如每边10个词。

标签: php regex string search


【解决方案1】:
function yourFuncName($str, $query, $numOfWordToAdd) {
    list($before, $after) = explode($query, $str);

    $before = rtrim($before);
    $after  = ltrim($after);

    $beforeArray = array_reverse(explode(" ", $before));
    $afterArray  = explode(" ", $after);

    $countBeforeArray = count($beforeArray);
    $countAfterArray  = count($afterArray);

    $beforeString = "";
    if($countBeforeArray < $numOfWordToAdd) {
        $beforeString = implode(' ', $beforeArray);
    }
    else {
        for($i = 0; $i < $numOfWordToAdd; $i++) {
            $beforeString = $beforeArray[$i] . ' ' . $beforeString; 
        }
    }

    $afterString = "";
    if($countAfterArray < $numOfWordToAdd) {
        $afterString = implode(' ', $afterArray);
    }
    else {
        for($i = 0; $i < $numOfWordToAdd; $i++) {
            $afterString = $afterString . $afterArray[$i] . ' '; 
        }
    }

    $string = $beforeString . $query . ' ' . $afterString;

    return $string;
}

输出为: user! welcome to new php open source world, ($numOfWordToAdd = 3)

【讨论】:

  • 为什么要使用 rtrim 和 ltrim?它只是删除必要的空格,例如如果你在“bob has a book”中搜索“bob”,结果会是“''bob''has a book
【解决方案2】:

这是一个工作示例,我很清楚我做了什么以及如何做:

<?php

$str = "hi user! welcome to new php open source world, we are trying to learn you something!";
$query = "new php";    

$expl = explode($query, $str);

    // items on the left side of middle string
    $expl_left = explode(" ", $expl[0]);

    $left_cnt = count($expl_left);

    $new_left = $expl_left[$left_cnt-3] . " " . $expl_left[$left_cnt-2];

    // items on the right side of middle string
    $expl_right = explode(" ", $expl[1]);

    $new_right = $expl_right[1] . " " . $expl_right[2];

    // new string formated
    $new = "... " . $new_left . " " . $query . " " . $new_right . " ...";

print $new;

?>

如果您有任何问题,请随时提出......

【讨论】:

  • 我怎样才能让它动态工作?我的意思是根据我的字数在每一边返回单词?
  • 它是动态工作的,只需将 $str 更改为您需要的任何内容和 $query 并运行代码,您将看到它是动态的...
  • Dusan 我是根据我的字数说的:)
  • 这个代码一切正常,即使你在 $query 之前和之后只有 1 个单词。但是如果你想改变之前和之后显示的单词数,那么你需要修改这个脚本,根据当前状态,它会返回前后 2 个单词。如果只有一个,则为 1,如果没有则无。
【解决方案3】:
$result = preg_replace('/(.+)?([^\s]+.{10}'.$query.'.{10}[^\s]+)(.+)?/', '... $2 ...', $str);

这将从您提供的相同字符串和查询返回相同的结果。如果 before 或 after 长度(分别)在单词的中间开始或结束,它将继续直到它在停止之前完成该单词。

【讨论】:

  • 好;但仍然是一个问题,例如对于“我们”这个返回:... rce 世界,我们正在尝试... 有没有更聪明的方法,或者你可以让它更聪明,拜托。
【解决方案4】:

假设“单词”是任何一系列非空白字符,以下将从字符串$subject 中提取new php 两侧的3 个单词,但如果需要则接受更少:

if (preg_match('/(?:\S+\s+){1,3}new php(?:\s+\S+){1,3}/', $subject, $regs)) {
    $result = $regs[0];
}

3s 更改为您喜欢的任何数字。

【讨论】:

  • thanx,但我认为您的代码需要 preg_quote 才能工作?我以前测试过类似的东西!
  • 它需要如果你的针可能包含正则表达式元字符,是的。
【解决方案5】:

我在explode中使用了以下函数:

public static function returnSearch($query, $str, $wordcount) {
    $explode = explode($query, $str);
    $result = null;
    //if explode count is one the query was not found
    if (count($explode) == 1) {
        $result = implode(' ', array_slice(str_word_count($explode[0], 2), -$wordcount, $wordcount)) . " ";
    }
    //if explode count is more than one the query was found at least one time
    if (count($explode) > 1) {
        //check for if the string begins with the query
        if (!empty($explode[0])) {
            $result =  "..." . implode(' ', array_slice(str_word_count($explode[0], 2), -$wordcount, $wordcount)) . " ";
        }
        $result = $result . $query;
        if (!empty($explode[1])) {
            $result = $result . " " . implode(' ', array_slice(str_word_count($explode[1], 2), 0, $wordcount)) . "...";
        }
    }
    //return result
    return $result;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-27
    • 2015-06-06
    • 2022-09-24
    相关资源
    最近更新 更多