To match every line with schema in the example and return only desired strings, you can use only one pattern:
$pattern = '
~
^ # start of line
{\w+} # any word character wrapped by curly brackets
\s\S+ # space followed by one or more Not-spaces
\s\S+ # space followed by one or more Not-spaces
\s-\s # space-dash-space
( # --First match group:
New\s\w+ # ‘New’ followed by space and one or more word chars
\s-\s # space-dash-space
New\s\w+ # ‘New’ followed by space and one or more word chars
) # --END First match group
\s* # one-or-more spaces (you can remove this, I think)
$ # end of line
~mx
';
/* Usage: */
preg_match_all( $pattern, $string, $matches );
echo implode( PHP_EOL, $matches[1] ) . PHP_EOL;
Will print:
New look - New Design
New look - New Design
New link - New Creation
regex101 demo
Instead, if you want retrieve any occurrence of ‘New something’, independently of your position in the line, you can use this:
$pattern = '
~
( # --First match group:
( # --Second match group:
(New\s\w+) # --3rd match group: ‘New’ followed by space and one-or-more word chars
(\s-\s)? # --4st match group: optional space-dash-space
)+ # --END Second match group (repeating one-or-more)
) # --END First match group
~mx
';
/* Usage: */
preg_match_all( $pattern, $string, $matches );
echo implode( PHP_EOL, $matches[0] ) . PHP_EOL;
Probably you want search for a variable, not for a fixed string. For this, simply replace New with your {$variable}, like in this example:
$find = 'Old';
$pattern = "~^{\w+}\s\S+\s\S+\s-\s({$find}\s\w+\s-\s{$find}\s\w+)\s*$~m";
// ------- -------
(The pattern above is the same of first example, in one line).
Edit:
To apply above pattern to each line inside your original foreach, simply remove first match group and your preg_replace will work:
$pattern = '~^{\w+}\s\S+\s\S+\s-\s+~'; // no multiline option needed
echo preg_replace( $pattern, '', $line ) . '<br><br>;