Ich würde folgende Regex verwenden:
<span\b[^>]*>([^<]*?)</span>
Die hintere Änderung * statt + wurde schon erklärt.
Die vordere Änderung (
\b[^>]* statt
\s+[^>]+) bewirkt, dass auch <span> ohne Attribute gematcht wird. Das ist bei <span> zwar selten, kann aber vorkommen.
(Die Details: \b matcht das Ende eines Wortes [zero width], hinter span muss also etwas kommen, dass auf \W matcht, [^>]* matcht alles bis zum nächsten >)
Allgemein hat der Ansatz mit der Regex aber das Problem, dass er nicht funktioniert, wenn innerhalb des <span>...</span> noch anderes Markup vorkommt, z.B. <b>...</b> oder <br>. Sicherer ist ein Ansatz, der einen richtigen HTML-Parser verwendet, z.B. mit
HTML::TreeBuilder.