jacklh has asked for the wisdom of the Perl Monks concerning the following question:
Results when hardcoded into script:my $s = "foo1bar"; $s =~ /(\w+)\d(\w+)/; print "var1: $1\tvar2: $2\n"; my $p = "$2$1"; # works and prints "p is barfoo" # call script as "perl pmtest.pl $2$1" #my $p = "$ARGV[0]"; # doesn't work, prints "p is $2$1" print "p is $p\n";
Results when using ARGV[0] method as "perl pmtest.pl $2$1":var1: foo var2: bar p is barfoo
Here is another conceptual version illustrating the issue we've run into.var1: foo var2: bar p is $2$1
The test.ini config fileuse strict; use warnings; use Config::IniFiles; my %args; my $global_ini_data = Config::IniFiles->new( -file => "test.ini" ); my $regex = $global_ini_data->val( 'client1', 'rename' ); my $filename = "201306051200foobar.dat"; print "REGEX: $regex\n"; print "BEFORE: $filename\n"; # Uncomment each method individually to test # Method 1: doesn't work #$filename =~ qr($regex); # Method 2: doesn't work #$filename =~ $regex ; # Method 3: doesn't work #$filename = modify($filename, sub { $_[0] =~ $regex }); # Method 4: doesn't work (not global) #my ($before, $after) = $regex =~ m{/(.*)/(.*)/}; #$filename = replace($filename, $before, sub { $after }, 0); # Method 5: doesn't work (global) #my ($before, $after) = $regex =~ m{/(.*)/(.*)/}; #$filename = replace($filename, $before, sub { $after }, 1); # Method 6: works, but hardcoded and not in INI; not scalable $filename =~ s/(\d{2})(\d{2})(\d{4})(.*)/$3$2\.$4/; # End Methods test print "AFTER: $filename\n"; exit; sub replace { my($string, $find, $replace, $global) = @_; unless($global) { $string =~ s($find){ $replace->() }e; } else { $string =~ s($find){ $replace->() }ge; } return $string; } sub modify { my($text, $code) = @_; $code->($text); return $text; }
The results: Methods 1 - 3 (not working)[client1] # PURPOSE: Convert YYYYMMDDhhmmss to MMDDYY.hhmmss rename=s/(\d{2})(\d{2})(\d{4})(.*)/$3$2\.$4/
Methods 4 - 5 (not working)BEFORE: 201306051200foobar.dat AFTER: 201306051200foobar.dat
Method 6 works, but hardcoded:BEFORE: 201306051200foobar.dat AFTER: $3$2\.$4
BEFORE: 201306051200foobar.dat AFTER: 060513.1200foobar.dat
Any ideas to make capture groups work when patterns defined in INI?
NOTE:
(1) I know the test.ini format leaves security risk of code injection--the above script is just for illustrative purposes. In the prod script, we actually just parse the before and after regex patterns from the INI and build the correct substitution regex.
(2) I consulted these posts, which provided valuable insight (and used in above methods) and ALMOST have the solution, but either don't work for capture groups defined in INI or when it does work, it's too rigid by hardcoding the number of capture groups in source code rather than allowing it to be dynamically defined in an INI, again necessary because we may potentially be holding hundreds of unique client configurations and need this to scale:
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Interpolation of capture buffers not working when regex stored in variable
by ikegami (Patriarch) on Jun 05, 2013 at 20:14 UTC | |
by jacklh (Initiate) on Jun 06, 2013 at 00:58 UTC | |
by jacklh (Initiate) on Jun 06, 2013 at 01:10 UTC | |
|
Re: Interpolation of capture buffers not working when regex stored in variable
by shmem (Chancellor) on Jun 05, 2013 at 20:15 UTC | |
by jacklh (Initiate) on Jun 06, 2013 at 01:01 UTC | |
|
Re: Interpolation of capture buffers not working when regex stored in variable
by rjt (Curate) on Jun 06, 2013 at 01:22 UTC |