1

I've got a utility where I'm trying to enforce brand standards in an application where the function will wrap brand words in a span with a class.

public function filterBrandWords($text)
    {
        // look up the brand words from the config settings
        $filter_terms = ['brandword1', 'brandword2', 'brandword3'];
        $filtered_text = $text;

        foreach ($filter_terms as $word) {
            $match_count = preg_match_all('/' . $word . '/i', $text, $matches);

            for ($i = 0; $i < $match_count; $i++) {
                $brand_string = trim($matches[0][$i]);
                $lower = strtolower($brand_string);
                $new = '<span class="font-semibold">' . substr($lower, 0, 3) . '</span>' . substr($lower, 3);
                $filtered_text = preg_replace('/\b' . $brand_string . '\b/', $new, $filtered_text);
            }
        }

        return $filtered_text;
    }

This works but noticed that it's also filtering text that contains the brand URL when applied.

I tried amending $match_count = preg_match_all('/' . $word . '/i', $text, $matches); to $match_count = preg_match_all('/' . $word . 'com$' . '/i', $text, $matches); in the hope it would ignore matches with com in them.

What have I gotten wrong here the regex?

If I do

echo filterBrandWords('brandword1');

the output is

<span class="font-semibold">bra</span>ndword1

with a URL, the output is

<span class="font-semibold">bra</span>ndword1.com

In those instances, I want to ignore the filter and just give it straight.

5
  • Can you share with us some sample input and the output you expect? Commented Sep 10, 2020 at 18:28
  • just updated the post to reflect those Commented Sep 10, 2020 at 18:34
  • 1
    also @JayBlanchard I like your use of Charles Rennie Mackintosh font on your website :) Commented Sep 10, 2020 at 18:35
  • you keep talking about URLs but there are no URLs in what you've shown us here. Commented Sep 10, 2020 at 18:49
  • If I did brandword1.com - that's the output in the above Commented Sep 10, 2020 at 19:10

1 Answer 1

1

If you want to ignore anything like a URL you can use something like this as your regex:

(?|.*\.(com|net|org))

which is a Negative Lookahead assertion that matches URL's (broadly). Insert that into your function as I have done here:

function filterBrandWords($text)
    {
        // look up the brand words from the config settings
        $filter_terms = ['brandword1', 'brandword2', 'brandword3'];
        $filtered_text = $text;
        
        if(!preg_match('/(?|.*\.(com|net|org))/', $filtered_text)) { // if it resembles a URL, skip it
            
            foreach ($filter_terms as $word) {
                $match_count = preg_match_all('/' . $word . '/i', $text, $matches);
    
                for ($i = 0; $i < $match_count; $i++) {
                    $brand_string = trim($matches[0][$i]);
                    $lower = strtolower($brand_string);
                    $new = '<span class="font-semibold">' . substr($lower, 0, 3) . '</span>' . substr($lower, 3);
                    $filtered_text = preg_replace('/\b' . $brand_string . '\b/', $new, $filtered_text);
                }
            }
        }

        return $filtered_text;
    }

Now call the function with something resembling a URL:

echo filterBrandWords('brandword1.com');

And the entire URL is just returned:

brandword1.com

EXAMPLE

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

Comments

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.