3v4l.org

run code in 300+ PHP versions simultaneously
<?php $blacklist = ["subsp.", "var.", "f.", "(voir)", "hybride"]; $prepped = array_map('preg_quote', $blacklist); // escape special characters $prepped[] = "'\S+'"; // do not escape special characters $negLookAhead = '(?!' . implode('|', $prepped) . ')'; $firstTwoWords = '(?:^\S+\s\S+)'; $regex = '#' . $firstTwoWords . '|(?<=\s)' . $negLookAhead . '\S+(?=\s|$)#'; $names = [ "Androsace angrenica 'Angelica' subsp. Violaceae", 'Allium obliquum', 'Allium ostrowkianum (voir) A. oreophilum', 'Allium senescens subsp. glaucum', 'Allium sikkimense', 'Androsace × pedemontana', ]; // echo $regex; var_export( preg_replace($regex, '<em>$0</em>', $names) );
Output for 8.1.0 - 8.1.28, 8.2.0 - 8.2.19, 8.3.0 - 8.3.7
array ( 0 => '<em>Androsace angrenica</em> \'Angelica\' subsp. <em>Violaceae</em>', 1 => '<em>Allium obliquum</em>', 2 => '<em>Allium ostrowkianum</em> (voir) <em>A.</em> <em>oreophilum</em>', 3 => '<em>Allium senescens</em> subsp. <em>glaucum</em>', 4 => '<em>Allium sikkimense</em>', 5 => '<em>Androsace ×</em> <em>pedemontana</em>', )

preferences:
55.02 ms | 402 KiB | 62 Q