You want a parser, not a regex. But I am in a weird mood ...
my $test = "< a> a "; for ($test) { my $count = 0; s{(.)}{ $count++ if $1 eq '<'; $count-- if $1 eq '>'; $count ? uc $1 : $1; }ge; } print $test;
print "Just another Perl ${\(trickster and hacker)},"
The Sidhekin proves Sidhe did it!
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]; }Update: I should read the OP again. This seems to match, but doesn't change the case like the OP wants. Nevermind (for now) :(
Update: Fixed. Though I'm still not sure if it's absolutely correct :)
Update (simplified solution below):
$str =~ s/(^|\G$RE{balanced}{-parens=>'<>'})([^<]+)/\U$1\E$2/g;
# Again? (and now I feel a DUH! coming on (:
$str =~ s/($RE{balanced}{-parens=>'<>'})/\U$1/g;
Here's a simple sed-like solution. This is probably not the fastest way, though.
$string = "< a> a \n"; { $string=~s/<([^<]*)>/\U$1/g and redo; } print $string;
#!/usr/bin/perl
my $qr;
$qr = qr!(?:\<(?:(?>[^\<\>]+)|(??{$qr}))*\>)!;
$_ = "< a> a ";
s/($qr)/\U$1/g;
print;
An uglier solution, just to be complete:
$k = 0; $string=~s@(?:<(?{++$k})|>(?{--$k}))*([^<>]*)@$k?uc($1):$1@ge;
s/([<>]+[^<>]+)/($k+=($1=~y#<##)-($1=~y#>##)) ? uc $1 : $1/ge;
perlmonks.org content © perlmonks.org and ambrus, borisz, bsb, danderson, orderthruchaos, Roy Johnson, runrig, Sidhekin
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03