Preg_replace improvement
Maybe this one : #^[^-=+*\w]{2}\s*#um (that is ~500% faster than yours):

&lt;?php
$list = '
== Category one
→ feature 1
++ feature 2
-- feature 3
==-
! feature 4
% feature 5
** feature 6
feature 7';

$list = preg_replace('#^[^-=+*\w]{2}\s*#um', '', $list);
print_r($list);


Whose output is:

== Category one
feature 1
++ feature 2
-- feature 3
==-
feature 4
feature 5
** feature 6
feature 7


Subsidiary question

You can complete the regexp #^[^-=+*\w]{2}\s*#um by the regexp
#^([-=+*])(?!\1|\s)#um to refuse +|-|=|* without whitespace after.

It is possible to combine the two regexps but at the expense of performance.

&lt;?php
function printResult($label, $list, $start, $end) {
  printf(
    "%s: %F s\n%s\n\n",
    $label,
    $end - $start,
    print_r($list, true)
  );
}

$list = '== Category one
→ feature 1
++ feature 2
-- feature 3
==-
! feature 4
% feature 5
** feature 6
feature 7
-line1
-- line2';

// Case 1: regrouping the regexps
$time_start = microtime(true);
$list = preg_replace('#^[^-=+*\w]{2}\s*|^([-=+*])(?!\1|\s)#um', '', $list);
$time_end = microtime(true);
printResult('With one regexp', $list, $time_start, $time_end);

// Case 2: a faster way
$time_start = microtime(true);
$list = preg_replace('#^[^-=+*\w]{2}\s*#um', '', $list);
$list = preg_replace('#^([-=+*])(?!\1|\s)#um', '', $list);
$time_end = microtime(true);
printResult('In two pass, a faster way', $list, $time_start, $time_end);


Whose output is:

With one regexp: 0.000151 s
== Category one
feature 1
++ feature 2
-- feature 3
==-
feature 4
feature 5
** feature 6
feature 7
line1
-- line2

In two pass, a faster way: 0.000024 s
== Category one
feature 1
++ feature 2
-- feature 3
==-
feature 4
feature 5
** feature 6
feature 7
line1
-- line2




Note: preg_replace replaces the overall catch, therefore it is useless to try to capture the full line.