Reputation: 57
I am searching how to get tokens values in properties file with Perl.
Given the source property:
my $source="application.1.hostname={{DNS_APP}}:{{PORT_APP}}/WHATEVER";
And given the target property:
my $target="application.1.hostname=test.test.com:8080/WHATEVER";
I would like to get the following result:
{{DNS_APP}}=test.test.com
{{PORT_APP}}=8080
I have no trouble to get the tokens with :
my @matches= ( $source =~ /({{.*?}})/g );
But then, how to match with their values ? Is there an easy way, with perl regexps to get these substitutions ?
Another difficulty (but they are execption, so it is not a big deal if this problem is not addressed) is that, sometimes, $target can be
my $target="application.1.hostname=test.test.com/WHATEVER";
Or
my $target="application.1.hostname=test.test.com:8080/SOMETHINGELSE";
Or even
my $target="application.1.hostname=test.test.com/SOMETHINGELSE";
How to deal with that ?
I thank you in advance for you answers.
Regards.
Upvotes: 0
Views: 262
Reputation: 53488
OK, at a basic level, you can turn your thing into a named capture for a regex. There's a caveat though - you might need to restrict character sets.
But something like this might work:
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
my $source = "application.1.hostname={{DNS_APP}}:{{PORT_APP}}/WHATEVER";
my $target = "application.1.hostname=test.test.com:8080/WHATEVER";
$source =~ s|\Q{{\E(\w+)\Q}}\E|(?<$1>.*)|g;
$source = qr/$source/;
print "Using Regex:", $source,"\n";
$target =~ m/$source/;
#%+ is the special named-capture hash. You can access $+{DNS_APP} for example
print Dumper \%+;
Note though - that .*
is a greedy match, and that will mean without delimitors/anchors between patterns, this will break. You could perhaps define a more narrow character class - I would think \w
normally, but you also have .
so perhaps [\w.]+
- or maybe even .*?
for non greedy matching instead. This depends rather on what would 'fit' with the types of patterns you're trying to match. If you need to do so with arbitrary patterns, I think you're going to need to need ... something like regex
to define the match criteria in the first place.
If your 'targets' are purely that pattern - e.g. trailing static words - you can trim you initial pattern with s/\w+$//
which will reduce it to:
application.1.hostname={{DNS_APP}}:{{PORT_APP}}/
Which you then regex transform to:
(?^:application.1.hostname=(?<DNS_APP>.*):(?<PORT_APP>.*)/)
And then get %+
of:
$VAR1 = {
'DNS_APP' => 'test.test.com',
'PORT_APP' => '8080'
};
As you're on 5.8.8
- my first advice is upgrade it, because it's 7 year old software, and is long since end of life.
This variable was added in Perl v5.10.0.
However you should be able to work around by:
my @match_names = $source =~ m|\Q{{\E(\w+)\Q}}\E|g; #capture 'names' of matches
$source =~ s|\Q{{\E(\w+)\Q}}\E|(.*)|g;
$source = qr/$source/;
print "Using Regex:", $source, "\n";
my %results;
my @matches = $target =~ m/$source/;
@results{@match_names} = @matches;
print Dumper \%results;
I'm pretty sure there's a way of capturing what matched from the s
pattern replacement. If I figure out what it was, I'll update.
(As it stands:
my ( @match_names ) = $source =~ s|\Q{{\E(\w+)\Q}}\E|\(.*\)|g;
doesn't seem to work as I want - @match_names
contains the number of replacements. )
Upvotes: 1