-1

I want to highlight my search query on a formatted number.

For example:

$search_query = '1234'; // or $search_query = '7800';
$formatted_numeber = '12,345,678.00';

Currently my code is:

preg_replace('/(' . $search_query . ')/i', "<span style='background: yellow'>$1</span>", $formatted_numeber);

But this code fails to highlight search clause like '1234' , '7800' due to presence of commas (,) and decimal (.)

Also i want this to work with the presence of commas and decimals in the search query.

For example:

$search_query = '3,456';
$formatted_numeber = '12,345,678.00';

I want to highlight the part "345,6" on my formatted number.

Or:

$search_query = '7.80';
$formatted_numeber = '12,345,678.00';

I want to highlight the part "78.0" on my formatted number.

2
  • 2
    Did you check the code in your question? I think the $formatted_numeber needs to be a string? Commented Sep 7, 2024 at 10:07
  • Yes. thanks for mentioning it @KIKOSoftware Commented Sep 7, 2024 at 10:14

1 Answer 1

1

Given how long is takes to get an answer, I think we can conclude that this isn't a trivial problem.

I assume, although you don't explicitly say so, that you actually only want to highlight formatted numbers, and that these numbers aren't embedded in a bigger text. I also assume you only want to highlight one part of the number, not multiple parts. So in 12,341,234.00 only the first 1234 will be highlighted.

My solution is a real algorithm, and not based on complex build-in functions or regular expressions. That would be possible of course, but I avoided them.

function highlight(string $search, string $number): string
{
    $searchBegin = NULL;
    $searchIndex = 0;
    $search      = str_replace([',', '.'], '', $search);
    foreach (str_split($number) as $numberIndex => $character) {
        if ($character == $search[$searchIndex]) {
            if (is_null($searchBegin)) {
                $searchBegin = $numberIndex;
            }    
            $searchIndex++;
            if ($searchIndex == strlen($search)) {
               return substr($number, 0, $searchBegin) .
                      '<span style="background: yellow">' .
                      substr($number, $searchBegin, $numberIndex - $searchBegin + 1) .
                      '</span>' .
                      substr($number, $numberIndex + 1);                
            }
        } elseif (!in_array($character, [',', '.']))  {
            $searchBegin = NULL;
            $searchIndex = 0;
        }
    }
    return $number;
}

Live demo: https://3v4l.org/StFn7

I think the code is quite self-explanatory. Just follow what it does and you'll understand it. There's nothing mysterious about it.

This code isn't optimized, and doesn't check for errors. It is intended as a starting point for further optimization. str_split() is handy, but not very fast, you can easily make this algorithm faster by using a for loop and a string index. Being able to highlight multiple sections would be the first thing I would do. You could do this recursively on the part of the $number after the match. Like so: https://3v4l.org/aRZtN

This code might be longer than you expect, but that doesn't make it bad or slow code. Sometimes a good old-fashioned algorithm wins the day.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot @KIKOSoftware. This solution works. Although there is a bug for empty search string so i fixed it. ` if ($search != '' && $search != null && $search != []){ //execute code; } `

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.