in reply to Clarification on greediness

/(<first>((?!<first>).*?))<content>maps<\/content>/
means: "<first>" not immediately followed by "<first>" followed by ...

It works if you move the paren:
/(<first>((?!<first>).)*?)<content>maps<\/content>/

The ? is not necessary because of the negative lookahead, but I bet it's more efficient to leave it in (less backtracking).

There's also something screwy with your captures. Why do you have two? The following does more or less what you want:

$str =~ m% <first> # "<first>" ((?:(?!</first>).)*?) # Capture the text in between. </first> # "</first>" (?:(?!<first>).)*? # In the same record, <content>maps</content> # "content" must be "maps". %xgsi;

I said it "does more or less what you want" because...

Use an XML module. No, really, use an XML module.