perlを使用すると、Set::IntSpan
数列を圧縮するためのモジュールを使用できます。
以下のソリューションは、混合および順序付けされていないサイトリストを処理できます。
infile
web3.maxi.com
web4.maxi.com
web5.maxi.com
mail1.mexi.com
web6.maxi.com
web9.maxi.com
web9.maxi.com
web11.maxi.com
mail3.mexi.com
web7.maxi.com
mail4.mexi.com
mail25.mexi.com
mail26.mexi.com
mail27.mexi.com
mail28.mexi.com
web8.maxi.com
mail29.mexi.com
mail110.mexi.com
web1.maxi.com
parse.pl
#!/usr/bin/perl -l
use Set::IntSpan;
use File::Slurp qw/slurp/;
$str = slurp(\*STDIN);
# Remove redundant whitespace
chop $str;
$str =~ s/^[\t ]+|[\t ]+$//gm;
$str =~ s/\R+/\n/g;
# Copy $str so we can match numbers in it without disturbing the loop
$nums = $str;
# Parse lines in $str in sequence
while($str =~ /^(.*)$/gm) {
$line = $1;
# Extract bits before and after number
($pre, $post) = $line =~ /([^\d]+)\d+(.*)$/m;
# Check if its been printed already
next if $seen{$pre . $post};
# If not, extract numbers
@numbers = $nums =~ /$pre(\d+)$post/g;
print $pre . "["
. Set::IntSpan->new(@numbers)->run_list()
. "]" . $post;
$seen{$pre . $post} = 1;
}
次のように実行します。
perl parse.pl < infile
出力:
web[1,3-9,11].maxi.com
mail[1,3-4,25-29,110].mexi.com
おそらく不可解な@numbers = $nums =~ /$pre(\d+)$post/g
ものは、正規表現に一致するアイテムの配列に展開され、それをに保存し@numbers
ます。
このソリューションは、ファイル全体をメモリにロードすることに注意してください。