【问题标题】:Swapping a string where space is found in php交换在php中找到空格的字符串
【发布时间】:2009-12-03 10:28:39
【问题描述】:

我需要实现以下功能:

我有一个包含姓名和姓氏的姓名字段。这存储在数据库中,并按“姓氏”的顺序排列。

我正在实现一个搜索这些记录的脚本。目前,我设法检查一个字符串是否包含一个空格,如果它包含一个空格,则意味着它是一个名字而不是一个 ID 卡号。代码如下:

$query = "John Doe";

$checkIfSpaceExists = strpos($query, " ");

if ($checkIfSpaceExists == "")
{
    //No Space therefore it is not a name
}
else
{
    //Contains space
   $queryExploded = explode(" ", $query);
   foreach ($queryExploded as $q)
   {
      //Here I need the functionality so that if someone entered John Doe
      //2 different strings are saved, which are
      //$string1 = John Doe
      //$string2 = Doe Johns

      //If the name consists of 3 parts, strings for every combination is saved
}

然后我将这些字符串插入到带有 LIKE 属性的 SQL 语句中,JOHN DOE 和 DOE JOHN 都会有一个 LIKE。因此,如果用户可以输入 John Doe 或 Doe John 来查找结果。

关于如何做到这一点的任何建议?

非常感谢

克里斯

【问题讨论】:

    标签: php string


    【解决方案1】:

    好的,从头开始 - 请务必仔细阅读the manualstrpos 并没有完全按照你的想法做。以下是检查空格的方法:

    if (strpos($query, ' ') === false)  // the triple-equals is important!
    

    之后,这只是permutations and combinations 的问题。这是 Stack Overflow 上的另一个答案,它向您展示了如何做到这一点:algorithm that will take number or words and find all possible combinations

    【讨论】:

    • 如果我像你说的那样使用它,脚本就不能正常工作。相反,如果我使用原始版本,则效果很好。我将更新我的帖子,因为我已成功实施。
    • 你能告诉我我使用它的方式有什么问题吗?谢谢
    • 手册中有一个以红色突出显示的部分,带有一个非常大的警告标志,内容为:This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE, such as 0 or "". Please read the section on Booleans for more information. Use the === operator for testing the return value of this function.
    【解决方案2】:

    如何在单独的 AND 组合的 LIKE 约束中使用这些爆炸的 3 个字符串?

    类似

    "... WHERE name LIKE '%$name[0]%' AND name LIKE '%$name[1]%' AND name LIKE '%$name[2]%'"
    

    您可以在 foreach 循环中构建此字符串。

    【讨论】:

    • 取决于您是否要查找“Johnathon Doe”和“John Henry Doe”。它也不会在字符串开头使用带有通配符的索引。
    【解决方案3】:
    echo preg_replace('/^(\w+) (\w+)$/', '$2 $1', "John Doe");
    

    杜约翰

    【讨论】:

    • 这不能处理多个空格(3 个或更多单词)
    • preg_replace('/^(\w+) (\w+) (\w+)$/', '$3 $2 $1', "John Jay Doe"); preg_replace('/^(\w+) (\w+) (\w+)$/', '$3 $1 $2', "Jay John Doe");快乐的? 3 部分,这就是他要求的全部......
    【解决方案4】:

    我猜你不能把这个字段分成名字和姓氏?我建议在数据库中创建新表和标签。标签可以是任何单词 - 可能是姓氏,可能是名字,可能是 ID 号......然后使用 record_id 和 tag_id 建立连接 record_tags。然后查询看起来像

    SELECT record.* FROM record
    INNER JOIN record_tags rt1 ON rt1.record_id = record.id
    INNER JOIN tag t1 ON t1.id = rt1.tag_id
    INNER JOIN record_tags rt2 ON rt2.record_id = record.id
    INNER JOIN tag t2 ON t2.id = rt2.tag_id
    WHERE
    t1.name = "John"
    AND t2.name = "Doe"
    

    这将是更好的搜索方法,因为您可以使用任意数量的单词/标签。我认为SQL可以更容易。 multi-like 方法我认为要慢得多,尤其是随着数据库的增长。

    【讨论】:

    • 不,我不能拆分字段。该数据库每两个月更新一次。它是一个未规范化的表,包含各种个人信息,例如姓名等......当数据库更新时,会创建一个包含所有信息的新表。之前的表格仅用于备份目的。前端程序(用 ExtJs 实现)只从最后创建的表中搜索。它忽略了所有其他的。有数千条记录,而且速度非常快......
    【解决方案5】:

    通过一些循环和字符串操作,我设法实现了这个脚本。

    这是我所做的:

    我使用 strpos 检查了查询是否包含空格。如果它包含一个空格,那么它意味着它的名字有名字和姓氏所以我进入一个循环,以便输出一个带有'name surname'的字符串和另一个带有'surname name'的字符串

    代码如下:

       $like = ""; //This is the LIKE sql command.
       foreach ($selectedFields as $field)
       {
                $checkIfSpaceExists = strpos($query," ");
    
        if ($checkIfSpaceExists != "")
        {
            $query1 = $query; //No space, so query1 is equal ta original query
    
            $queryExploded = explode(" ", $query);
    
            for ($i=0; $i<count($queryExploded); $i++) //First loop (name surname)
            {
                $tmp1 = $tmp1 . " " . $queryExploded[$i];
            }
    
            for ($i=count($queryExploded); $i>=0; $i--) //Second loop (surname name)
            {
                $tmp2 = $tmp2 . " " . $queryExploded[$i];
    
            }
            $query2 = $tmp2;
            $query2 = trim($query2);
    
            $like = $like . $field . " LIKE '%" . $query1 . "%' or " . $field . " LIKE '%" . $query2 . "%' or ";
    

    我希望这可以帮助其他有需要的人:)

    【讨论】:

      猜你喜欢
      • 2019-11-01
      • 2018-05-05
      • 2011-05-03
      • 2018-07-09
      • 2019-12-09
      • 2011-07-31
      • 1970-01-01
      • 2023-03-08
      • 2019-05-16
      相关资源
      最近更新 更多