おはようございます。
若林(@nqounet)です。

この記事は、Perl 5 Advent Calendar 2016 - Qiitaの2日目の記事です。

昨日も私が書きました。-> MacBook Pro (13-inch, Late 2016, Four Thunderbolt 3 Ports) の system perl のバージョンを調べた | IT Office Nishimiyahara

何かネタがないかな〜、と物色していたら、以下の記事を見つけました。

Perl5がない!!!

ということでネタができました。ありがとうございます。

Perlでの文字列操作

ズバッと回答のソースコードをば。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';
use List::Util qw(reduce);

sub str_test {

# 文字列定義
my $str_text = '2$4$8$16';
say $str_text;

# 文字列置換
$str_text =~ s/\$/#/g;
say $str_text;

# 配列分割
my @str_list = split /#/, $str_text;
say scalar @str_list;

# 配列要素追加
push @str_list, '32';
say scalar @str_list;

# 足し合わせ
my $sum = reduce { $a + $b } @str_list;
say $sum;

# 配列結合
$str_text = join '++', @str_list;
say $str_text;

# 文字列連結
$str_text = 'Hoge->' . $str_text;
say $str_text;

# 文字列切り取り左
$str_text = substr $str_text, 0, 10;
say $str_text;

# 文字列切り取り右
$str_text = substr $str_text, -5;
say $str_text;
}

str_test();

コメント

せっかくなので、一つ一つにコメントしていきましょう。

文字列定義

なんだかいきなりですが、シングルクォートで括らないと定義(代入)すらできません。

「$」はPerlではスカラ変数の頭につけるのですが、ダブルクォーテーションの中では変数が展開されるので、それを防ぐにはエスケープしないといけません。

まあ、そういうのは面倒なので、シングルクォートでくくりましょう。つまり、シングルクォートの中では変数が展開されない、ということです。

文字列置換

正規表現内では「$」はエスケープしないと動かないです。

正規表現の中では「$」は行末にマッチする(厳密には色々違いますが)ので、文字扱いするにはエスケープする必要があります。

置換を実行すると、変数の値が変わります。参考記事で言うところの「破壊」です。

配列分割

「#」があるとエディタ(Atom)だとコメント扱いされますが、特にエスケープする必要はありません。

参考記事では要素数を出していますが、Perlでは、配列の要素数を出すためには、配列の変数をスカラコンテキストで評価する必要があります。

ということで、表示するときは「scalar」を使います。つまり、表示する「say」はリストコンテキストで評価される、ということです。

なお、「say」は、最後に改行を付けて出力してくれるので、簡単なスクリプトには便利です。

「scalar」なしだとどうなるんだろう?と思ったあなた。センスありますよ。試してみてください。

配列要素追加

一応、文字列リテラルで追加します。

「push」を実行すると、変数の値が変わります。参考記事で言うところの「破壊」です。

足し合わせ

reduce は標準モジュールの List::Util に含まれているのでそれを使います。

どうせモジュールを使うのなら「sum @str_list」でいいのですが、参考記事に合わせてみました。

$a, $b は突然見ると気持ち悪い、と言われても仕方ないような気がします。なので、ますます「sum」使おうよ、って感じですね。

なお、文字列->数値の変換は不要です。Perlの場合は、値が文字列でも「+」演算子を使うと、数値として足し算ができるのです。

配列結合

join でリストを任意の文字列で結合できます。

文字列連結

文字列の連結は「.」(ドット)を使います。

文字列切り取り左

文字列を切り取るには「substr」を使います。

2つの引数の意味は、「場所」と「文字数」です。

最初の引数に「0」を入れるのが、左を切り取るときのポイントです。

文字列切り取り右

右を切り取るには、最初の引数に負の数を入れます。

最初の引数に負の数を入れると「後ろから何番目の文字」となります。

二つ目の引数を省略すると、最後までが対象になります。

感想

ついカッとなって書いてみましたが、色々と思うところがありました。

とりあえず関数名やファイル名はスネークケースで書いています。

Perl5というとラクダのイメージですが、キャメルケースはあまり推奨されてないような気がします。わかりませんが。

ネイティブなオブジェクト指向言語ではないので、全体的に関数を使う感じになってしまいますね。
参考記事だと、 VBScript とか HSP くらいですかね…。

正規表現、置換なども見た感じでは意味不明です。

reduce は、個人的には使ったことないレベルです。
言い訳をすれば、List::Utilで sum などの関数は使えるので、あえて reduce を使うことはないような気がします。

しかし、突然の$a,$bは気持ち悪いですね。
まあ、 sort でも出てくるんですけどね。

よく見てみると、 reduce ではなく普通にループで足してるのもありました。
モジュールを使わずにループにするとこんな感じですね。

1
2
3
4
5
my $sum = 0;
for my $elm (@str_list) {
$sum += $elm;
}
say $sum;

まあ、言語仕様としてはこっちで書くほうが正解ですね。

こうしてみると、オブジェクト指向プログラミングを学びたい人にとっては不向きな言語であることがよくわかりますね。

まあ、それはそれ、ってことで。

Perl 5 Advent Calendar 2016

明日は、sago35さんです。

Perl 5 Advent Calendar 2016はまだまだ参加者を募集してまーす。