#!/usr/bin/perl -ln use strict; use warnings; sub expand; sub doit; print for expand $_; sub expand { doit split /\[(.*?)\]/, shift, -1; } sub doit { return @_ if @_ == 1; my ($pre,$pat,$post)=splice @_, 0, 3; map { doit $pre . $_ . $post, @_ } map { /(\w+):(\w+)/ ? $1..$2 : $_ } split /,/, $pat; } __END__ #### echo pre_[aa,01:03,bb]_[x,y]_post | ./xstr.pl pre_aa_x_post pre_aa_y_post pre_01_x_post pre_01_y_post pre_02_x_post pre_02_y_post pre_03_x_post pre_03_y_post pre_bb_x_post pre_bb_y_post #### sub expand { doit split / (?## sub expand { doit split //, shift, -1; }