After thinking out loud in my last post, here is some new code that illustrates how to do generic replacement processing with on-the-fly formatting... It is a quick perl script but is basically the guts for a my:sub XMLSubs-type function... #! /bin/perl my $body = << "EOF"; <fmt>PRICE:%.2f,AGE:%3d,STATE:%uc2</fmt> Price \$__PRICE__ - You must be __AGE__ years old to buy in __STATE__. EOF my %hash = ( price => 12, age => 18, state => 'va', ); my %fmt = (); # for format view ## extract format (if any) - what's left becomes template string $body =~ s/<fmt>(.*?)<\/fmt>//i; $fmt = $1; ## scoop-up formats into a convenient hash foreach (split(/,/, $fmt)) { my ($key, $val) = split(/:/, $_); $fmt{uc(eatwhite($key))} = eatwhite($val); } ## render hash using template string and format hash render($body, \%hash, \%fmt); sub render { ## process template using data in hash and formatting info my $tmpl = shift; my $hash = shift; my $fmt = shift; foreach (keys %$hash) { my $key = uc($_); if ($$fmt{$key} ne undef) { my $fmt = $$fmt{$key}; if ($fmt =~ /^%uc/i) { # to-uppercase $fmt =~ s/[^0-9]//g; $$hash{$_} = uc(substr($$hash{$_}, 0, $fmt || length($$hash{$_}))); } elsif ($fmt =~ /^%lc/i) { # to-lowercase $fmt =~ s/[^0-9]//g; $$hash{$_} = lc(substr($$hash{$_}, 0, $fmt || length($$hash{$_}))); } else { # picture $$hash{$_} = sprintf($fmt, $$hash{$_}); } } $tmpl =~ s/__${key}__/$$hash{$_}/gie; } print "$tmpl\n"; } ## convenience function sub eatwhite { $_[0] =~ s/^\s*(.*?)\s*$/$1/; return $_[0] }; __END__ This script simulates the guts of the following XMLSubs scenario: <my:sub ...> <fmt>PRICE:%.2f,AGE:%3d,STATE:%uc2</fmt> Price \$__PRICE__ - You must be __AGE__ years old to buy in __STATE__. </my:sub> The format info is scooped-up into the %fmt hash and each item in the hash is processed according to its format data, if available. Otherwise its just directly replaced. Two pseudo formats are also available: %lcN and %ucN (where N is a positive integer representing the max chars to return -- N can also be left off in which case the entire string will be processed and returned). This type of processing would simplify _many_ chores-- for example, consider this hypothetical example in which "my:sub" retrieves one or more rows of data and then renders them according to the body info: <table> <my:sub search="search_string" > <fmt>COST:%.2f,PRICE:%.2f</fmt> <tr><td>__PART__</td><td>__NAME__</td><td>__DESCR__</td><td>__COST__</td><td>__PRICE__</td></tr> </my:sub> </table> And that would be pretty much the WHOLE html file. All of the nasty bits are hidden away in the 'my:sub' functionality. Another interesting way to process vars, and more in keeping with the JSP Taglib stuff you mentioned (I did some reading today ;) would be a script similar to this: #! /bin/perl ## script to test matching parameters my $str1 = "NAME: John AGE: 40 SEX: M"; my $str2 = "NAME: Wendy AGE: 42 SEX: F"; my $str3 = "NAME: Scott SSN: 36 SEX: M"; my $str4 = "NAME: Beck AGE: 30 SEX: F"; my @fields = qw(name age sex); my $pat = 'NAME: (.*?) AGE: (\d+) SEX: (.*)$'; print "STR: '$str'\n"; print "PAT: /$pat/\n"; print "\n"; foreach ($str1, $str2, $str3, $str4) { my $hash = extractData($_, $pat, \@fields); if ($hash eq undef) { print "WARNING - Encountered bad data\n" } else { foreach (keys %$hash) { print "KEY = $_, VAL = $$hash{$_}\n" }} print "-"x72, "\n"; } sub extractData { my $str = shift; my $pat = shift; my $fields = shift; my $count = 0; my %h = (); $str =~ /$pat/; while (${++$count} ne undef) { $h{$$fields[$count-1]} = ${$count} } return \%h if ($count-1 == scalar @$fields); # correct field count return undef; # bad field count } __END__ This script simulates the $1, $2, $3 functionality of pattern matching but in such a way that any number of pattern-tokens can be matched and returned without knowing the exact number beforehand-- this way a generic pattern processor can be used to apply a pattern against a string and return the matched data. This script does not use the exact %1, %2, %3 syntax that Taglibs calls for, but that's a minor issue and could be worked in. The harder part was coming up with a way to work iterate the $1, $2.. vars which don't like to be iterated. This code snippet was not actually originally for an ASP script, but when Josh mentioned that bit about the JSP Taglibs and I read up on it, this snippet immediately came to mind. I can't imagine that it would be that hard to adapt to the concept. As always, I hope someone might find some of this stuff useful, informative, or at least interesting ;) John Whitten [EMAIL PROTECTED] Wizard.Org, Inc. -- -------------------------------------------------------------------------------- Check out http://www.Wizard.Org for great deals on Electronic Parts *NEW* Computer Parts & Accessories - Drives - LCD - Systems - Linux -------------------------------------------------------------------------------- ** Affordable Online Store w/Merchant Card Processing & Paypal ** Write to us: [EMAIL PROTECTED] -- Get your Store Online Today! -------------------------------------------------------------------------------- --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]