Ahmad Issa
Ahmad Issa

Reputation: 323

Matching a longest word using Regex only

I need to match longest word of given string using regex: for example given string

I need to get only one word that match 2 constriants, all the word should contain characters from one set only and the chosen word should be the longest, I tried to solve this using php regex such as:

preg_match("/\b[abcdexy]+/",$s, $match1);
preg_match("/\b[mnrpo]+/",$s, $match2);
if(strlen($match1[0]) > strlen($match2[0]))
{
  //output match1[0];
}
else
{
 //output match2[0]
}

The expected output should be axbxbxx since it contain only characters from set 1 and it is the longest between words that belong to one of the two sets.

My question is, can I make this work using only regex without need for strlen() testing?

Upvotes: 0

Views: 498

Answers (1)

mickmackusa
mickmackusa

Reputation: 47894

You can write a single regex expression that uses a pipe to match both character ranges, then sort the matched values by descending length and access the first element's value.

Code: (Demo)

$string='hello proxy night pom-pom-mop axe prom etc decayed';
if (preg_match_all('~\b(?:[a-exy]+|[m-pr]+)\b~', $string, $out)) {
    usort($out[0], function($a, $b) {return strlen($b) - strlen($a);});  // or spaceship operator if you like
    echo $out[0][0];
} else {
    echo "no matches";
}

Output:

decayed

The above method is not "tie-aware" so if you have two values or more values that share the highest length, you will only get one value in the output. I think you need to build in some additional logic to handle these fringe cases like:

  • Output all highest length values or
  • Set a secondary criteria to break ties on length

I'll not bother coding up these solution extensions since I prefer not to go down rabbit holes.

Upvotes: 1

Related Questions