【问题标题】:PHP search string with exceptionsPHP 搜索字符串有异常
【发布时间】:2015-08-01 11:26:05
【问题描述】:

我正在尝试使用 PHP 在字符串中搜索单个字母并将其替换为粗体字母。我创建了一个函数来执行此操作,如下所示:

function matchText($key,$before){
  $search = str_split($key);
  $after = $before;
  foreach($search as $s){
    $s1 = strtolower($s);
    $r1 = "<b>".$s1."</b>";
    $s2 = strtoupper($s);
    $r2 = "<b>".$s2."</b>";
    $after = str_replace($s1, $r1, $after);
    $after = str_replace($s2, $r2, $after);
    $after = str_replace("</b><b>","",$after);
  }
  return $after;
}

我传入搜索字符串 ($key) 和要搜索的完整字符串 ($before)。 它将搜索字符串拆分为单个字符以进行搜索,并且对于每个字符,它都会检查小写和大写版本并将其替换为粗体版本。最后它摆脱了任何连接的 HTML 标签,所以我不会得到一个充满标签的字符串。

问题是当搜索字符串包含“b”时,它会替换所有“b”,包括 HTML 标记中的那些,这会创建混乱的字符串。

例如,我正在搜索 Fred Campbell 的姓名列表,并使用搜索字符串“campb”得到以下结果字符串:

当我想要得到的结果是“Fred Campbell”时

如果字母“b”被或 >包围,有没有办法在搜索中创建一个例外来不替换字母“b”?

或者也许是另一种方式?

编辑:

这是 ajax 调用的一部分,该调用在用户在文本字段中键入时查询名称数据库。当他们键入最多 10 个结果的下拉列表时,会给出原始字符串中突出显示的搜索字符串。 例如,我的数据库有 2 个名称“Fred Campbell”和“Andrew Flycamp”(随机名称:P)。如果用户键入“camp”,则下拉列表将包含两个名称,搜索字符串的每个字符都以粗体显示并以其原始大小写。

所以“Fred Campbell”变成了“Fred Campbell”,“Andrew Flycamp”变成了“Andrew Flycamp

注意“Campbell”中的大写字母和“Flycamp”中的小写字母。即使我搜索“CAMP”或“Camp”或“camp”,这也会发生。

在搜索字符串中添加“b”之前,我的代码可以正常工作,然后事情变得奇怪,粗体标签被弄得面目全非。

【问题讨论】:

  • 是的,preg_replace() 与正则表达式一起使用

标签: php string search str-replace


【解决方案1】:

您必须创建一个字符类并通过引用 \0 替换匹配的字符。

<?php

function matchText($text, $key) {
  return preg_replace('/['.$key.']/i', '<b>\0</b>', $text);
}

$text = 'Andrew Flycamp';

//<b>A</b>ndrew Fly<b>c</b><b>a</b><b>m</b><b>p</b>
echo matchText($text, 'camp');

https://eval.in/367653

【讨论】:

  • 非常感谢您的宝贵时间,这解决了我的问题。
【解决方案2】:

虽然this answer 很好,但它的缺陷在于不能将其用于单词,因为它会将部分单词替换为粗体文本。

我建议进行以下更改。

function matchText($text, $key, $blFullWord = TRUE) {
  if( $blFullWord ) {
     //We want to match the full word and not part-word
     return preg_replace('#\b('.$key.')\b#i', '<b>\1</b>',$text);
  }
  return preg_replace('#('.$key.')#i', '<b>\1</b>',$text);
}

$text = 'Fred Campbell was camping in a camp during the night';

//Fred Campbell was camping in a <b>camp</b> during the night
echo matchText($text, 'camp');
//Fred <b>Camp</b>bell was <b>camp</b>ing in a <b>camp</b> during the night
echo matchText($text, 'camp', FALSE);

https://eval.in/367640

注意两件事;

  • 我们要替换的单词的捕获组允许我们在替换中引用它 - 这意味着我们保留大小写。
  • 单词边界。这意味着它将匹配整个单词,而不是子单词,例如 &lt;b&gt;Camp&lt;/b&gt;ing

【讨论】:

  • 嗯,我应该提供一些背景知识。请参阅这是 ajax 调用的一部分,该调用使用字符串查询名称数据库并在下拉菜单中返回最多 10 个结果。菜单包含带有粗体搜索字符串的名称。用户可能只知道名称的一部分,“campb”,当他们键入下拉列表时,应该列出结果并突出显示完整原始字符串中的搜索字符(如果你知道我的意思的话)。我将编辑我的问题以包含此
  • 编辑了我的原始问题以包含更多背景。请参阅我需要它来替换粗体文本中的部分和完整单词。我认为我的问题无法通过 pre_replace 解决,而是如果在搜索字符串中找到字母“b”,则可以进行自定义更改。
  • 我已经added another answer 来处理您的编辑问题。
  • 刚刚注意到您对另一个答案的评论,这似乎是我正在寻找的解决方案。
  • @jakecfc1992 好消息 :) 干杯!
【解决方案3】:

有一种更简单的方法:

function matchText($text, $key) {
  return preg_replace('#'.$key.'#i', '<b>'.$key.'</b>',$text);
}

$text = 'Fred Campbell';

echo matchText($text, 'camp');

这将返回:

Fred <b>Camp</b>bell

【讨论】:

  • g 修饰符对 php 无效 preg_replace
  • 我的错。不知道(但这是合乎逻辑的)。
  • @ʰᵈˑ 表示 2 个人在对代码一无所知的情况下升级它
  • 虽然是一个小错误,但答案应该合乎逻辑并提供正确的代码。我是第二个赞成票,因为这是一个简单的错误并很快得到了修正。
  • @jakecfc1992 将preg_replace 更改为preg_replace('#('.$key.')#i', '&lt;b&gt;\1&lt;/b&gt;',$text);。这将创建一个捕获组,以便您可以在替换中引用它。 - eval.in/367638
猜你喜欢
  • 2019-04-25
  • 1970-01-01
  • 2012-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-19
  • 2012-07-21
相关资源
最近更新 更多