Reputation: 37
I have the following string:
{"name":"db-mysql","authenticate":false,"remove":false,"skip":false,"options":{"create":{"Image":"mysql:5.6/image-name:0.3.44","Env":{"MYSQL_ROOT_PASSWORD":"dummy_pass","MYSQL_DATABASE":"dev_db"}}}}
I need to get the version: 0.3.44
The pattern will always be "Image":"XXX:YYY/ZZZ:VVV"
Any help would be greatly appreciated
Upvotes: 1
Views: 64
Reputation: 180201
This regular expression will reliably match the given "pattern" in any string and capture the group designated VVV
:
/"Image":"[^:"]+:[^"\/]+\/[^":]+:([^"]+)"/
where the pattern is understood to express the following characteristics of the input to be matched:
"Image"
and the following "
(though that could be matched with a small tweak);XXX
and ZZZ
substrings do contain any colons;YYY
substring does not contain a forward slash (/
); andXXX
, YYY
, ZZZ
, or VVV
contains a literal double-quote ("
), whether or not escaped.Inasmuch as those constraints are stronger than JSON or YAML requires to express the given data, you'd probably be better off using using a bona fide JSON / YAML parser. A real parser will cope with semantically equivalent inputs that do not satisfy the constraints, and it will recognize invalid (in the JSON or YAML sense) inputs that contain the pattern. If none of that is a concern to you, however, then the regex will do the job.
Upvotes: 2
Reputation: 385809
This is extremely hard to do correctly using just a regular expression, and it would require an regex engine capable of recursion. Rather than writing a 50 line regexp, I'd simply use an existing JSON parser.
$ perl -MJSON::PP -E'
use open ":std", ":encoding(UTF-8)";
my $json = <>;
my $data = JSON::PP->new->decode($json);
my $image = $data->{options}{create}{Image};
my %versions = map { split(/:/, $_, 2) } split(/\//, $image);
say $versions{"image-name"};
' my.json
0.3.44
Upvotes: 1