It's now 2 days later than my original question, and I've had the chance to think it over a little. As a result, I've come up with a few approaches I hadn't even thought of at the time.

Note: the format for the Progress database must be compatible with the target format for PL/SQL. Actually, the former is just less specific. All you need is a format description for PL/SQL, and by replacing every \w character with a "9", you get the format for Progress. Otherwise, it simply wouldn't work. And by deriving the former from the latter, you can make sure that you din't make a mistake in this regard.

First, I think you have to generalise the Progress formats into (regex) patterns. When you find a pattern that matches, you can turn the input pattern into the customised output pattern in several way, of which I've implementend a few in a separate sub, with a flag to switch what implementation to use. See the comments there to what each does.

Apart from the implementation of the actual replacement, one can make good use of memoization: there's no need to recalculate the target format again and again for the same input format string. So here's a demo of such memoized calculation.

#! perl -w use strict; my %dateformat; # memoization hash my @rule; foreach my $target (qw(DD/MM/YYYY DD/MM/RR YYYY/MM/DD)) { (my $input = $target) =~ s/\w/9/g; if(exists $dateformat{$input}) { die "Clashing target formats: $dateformat{$input} <-> $target" +; } $dateformat{$input} = $target; (my $pattern = $input) =~ s/\W/\\W/g; push @rule, [ qr/^$pattern$/, $input, $target ]; } # memoized calculation: use Carp; sub convert { my $input = shift; return $dateformat{$input} ||= do { my $target; foreach my $ar (@rule) { my $re = $ar->[0]; if($input =~ /$re/) { # pattern matches, now apply differences $target = alter($input, @$ar); last; } } $target; } or croak "No format pattern found for $input"; } our $how; # 5 alternative ways to do the same thing sub alter { my($input, $re, $from, $to) = @_; if($how eq 'SPLIT') { # split into ('99', '-', '99', '-', '9999') # insert ('DD', 'MM', 'YYYY') into the even numbered positions + (0, 2, 4) # and join again my @parts = split /(\W+)/, $input; @parts[grep !($_%2), 0 .. $#parts] = $to =~ /(\w+)/g; return join '', @parts; } elsif($how eq 'REPLACE_SUBSTR') { # replace each "9" with the character at the same position in +the original target string $input =~ s(9){ substr $to, $-[0], 1 }ge; return $input; } elsif($how eq 'REPLACE_9') { # inject ('D', 'D', 'M', 'M', 'Y', 'Y', 'Y', 'Y') via s/// eac +h replacing a "9" my @subst = $to =~ /(\w)/g; $input =~ s(9){ shift @subst }ge; return $input; } elsif($how eq 'REPLACE_9S') { # ditto but now replacing groups of nines # inject ('DD', 'MM', 'YYYY') via s/// my @subst = $to =~ /(\w+)/g; $input =~ s(9+){ shift @subst }ge; return $input; } elsif($how eq 'XOR') { # stringwise XOR with '9'^'D' for example # this will replace '9' with 'D' # XOR '-' with ('/'^'/') which is "\0", yields '-' # thus, only the nines will be affected my $xor = "$from" ^ "$to"; return "$input" ^ $xor; } else { die "Huh? What did you want me to do? '$how'?"; } } foreach $how (qw(REPLACE_SUBSTR SPLIT REPLACE_9 REPLACE_9S XOR)) { delete $dateformat{'99-99-9999'}; # kill memoized value; printf "%s: %s\n", $how, convert('99-99-9999'); }

In reply to Re: Generating a format template for a date by bart
in thread Generating a format template for a date by bart

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.