If your tags are proper, you could try parsing it as xml. This will work on your given example:
var input:String = "<p>Some text to extract</p>";
var xml:XML = new XML(input);
trace(xml.text().toString()); // traces "Some text to extract"
Edit
The following is not really a clean answer...I couldn't get it until I spent some time messing with it. You may not want to accept this as an answer, but I'm posting it as I did manage to get the result...maybe someone else can make it cleaner.
I had never really encountered a case where the node I'm interested in (the
node in this case) had text content AND a child node (same with CDATA in my xml). The code below is after some random guessing and checking the api. Learn something new everyday. =b
var inputString:String = "<caption><![CDATA[<p>Some text to extract.<span> -- Span text</span></p>]]></caption>";
var xml:XML = new XML(inputString);
// oddly this seems to filter out the caption and CDATA tag...but the resulting output is all in 1 element still
trace(xml); // traces out: <p>Some text to extract.<span> -- Span text</span></p>
xml = new XML(xml.toString()); // turn this into xml again
trace(xml); // this looks better now...traces out the expected xml
trace("{"+ xml.p +"}"); // traces out blank for some reason...
trace(xml.span); // traces out the expected span tag contents: "-- Span text"
trace(xml.descendants()[0]); // traces out "Some text to extract." -got it!
trace(xml.descendants()[1]); // traces out "-- Span text"