use strict; use warnings; use Regexp::Common; my $str = "a< a>bca"; while ($str=~/\G(?:|$RE{balanced}{-parens=>'<>'}) ([^<]+) (?:|$RE{balanced}{-parens=>'<>'})/xg) { # Update: Oops, this uppercases everything except what # the OP wanted :) substr($str, $-[1],$+[1]-$-[1]) = uc $1; pos($str) = $+[1]; }