0

I'm working on a small function which highlight keyword in text. Before I used regular expression to replace original text with the highlighted one which worked too, but recently I had time to rewrite this function. I need some assistance about performance vise or how can be improved. Anybody who have any ideas how to improve I would appreciate one help.

function highlight($search, $subject, $htmlTag = 'mark')
{
    if (empty($search) === true) {
        return $subject;
    }

    $searchParts = explode(' ', str_replace("'", '', iconv('UTF-8', 'ASCII//TRANSLIT', $search)));
    $subjectParts = explode(' ', str_replace("'", '', iconv('UTF-8', 'ASCII//TRANSLIT', $subject)));
    $originalSubject = explode(' ', $subject);
    $result = [];

    foreach ($subjectParts as $row => $subjectPart) {
        foreach ($searchParts as $searchPart) {
            if (false !== $pos = stripos($subjectPart, $searchPart)) {
                $result[] = mb_substr($originalSubject[$row], 0, $pos) . '<' . $htmlTag . '>' . mb_substr($originalSubject[$row], $pos, mb_strlen($searchPart)) . '</' . $htmlTag . '>' . mb_substr($originalSubject[$row], $pos + mb_strlen($searchPart));

                continue 2;
            }
        }

        $result[] = $originalSubject[$row];
    }

    return implode(' ', $result);
}

Edit: iconv needed because this function will replace text which contains accented characters.

Edit 2: example: highlight('prijimac HD815', 'Satelitný prijímač, Amiko HD8155'); result: "Satelitný prijímač, Amiko HD8155"

zsoro
  • 82
  • 1
  • 10
  • Please provide an example of what the `$search` and `$subject` contents might look like. I see you split it on space characters? – Scuzzy Dec 06 '18 at 00:42
  • By optimization do you mean purely speed? Because I doubt what you posted is faster than basic regular expression replacements. Also I still don't see the point of `iconv`. – Jeto Dec 06 '18 at 00:43
  • @Jeto to obliterate special characters, ofc. Like the one in his name. – Sammitch Dec 06 '18 at 01:06
  • @Scuzzy I edited my question and added an example. Thank you your response. – zsoro Dec 06 '18 at 08:06

1 Answers1

1

Here's what I would simply do:

function prepare($pattern)
{
  // Add any other accented character you wanna handle
  $replacements = [
    'a' => '[aáàäâ]',
    'c' => '[cč]',
    'e' => '[eéèëê]',
    'i' => '[ií]',
    'y' => '[yý]'
  ];

  return str_replace(array_keys($replacements), $replacements, $pattern);
}

function highlight($search, $subject, $htmlTag = 'mark')
{
  $pattern = '/' . preg_replace('/\s+/', '|', prepare(preg_quote(trim($search)))) . '/u';

  return preg_replace($pattern, "<$htmlTag>$0</$htmlTag>", $subject);
}

Demo: https://3v4l.org/MUX9b

Jeto
  • 14,596
  • 2
  • 32
  • 46
  • Thank you +Jeto I like your approach, my version was primitive. But it lacks of the feature to select partial match inside word, therefore the second version was born. But again I really like it. – zsoro Dec 06 '18 at 07:59
  • Oh, I see you've added some examples (edit 2). No time to edit my answer right now but when I'm back I'll try and make it closer to what you want. – Jeto Dec 06 '18 at 08:19
  • Removed the `\b` modifiers so it can now match word parts as well. The only thing it does differently from your initial question is that it doesn't ignore accented characters. – Jeto Dec 07 '18 at 08:51
  • Thank you +Jeto it definitely looks promising. Here at work they are freaked out because it doesn't highlight text when they enter non-accented words and the function does not highlight accented words, like this: https://drive.google.com/file/d/15iiJb9rj3ikk_xK8hYKb-8po7sUkN5XD/view?usp=sharing but on the other hands it is really promising, ... crazy requirements these things drive me crazy. – zsoro Dec 07 '18 at 09:29
  • 1
    See my last edit, this should handle accented characters as well. Only drawback is that you have to manually list accented characters you wanna handle. (Note: [this answer](https://stackoverflow.com/a/10477284/965834) helped.) – Jeto Dec 07 '18 at 10:21
  • I've made a little modification and it seems to work for my case https://3v4l.org/6BeNu – zsoro Dec 07 '18 at 10:35
  • 1
    Nice! If this suits your needs, you can mark the answer as accepted if you'd like. Good luck for the rest of your project. – Jeto Dec 07 '18 at 10:59
  • Thank you @Jeto you helped me a lot! Wish you all the best too. – zsoro Dec 07 '18 at 11:13