┌───────┐
│perl超入門(4) │
│  2002/11/17 │
└───────┘

[▲Perl Home▲]

付録
・TXTファイルをHTMLファイルへ変換するperlスクリプト。
   →[Link]スクリプトソースのHTML表示
   →[Link]スクリプトソースのダウンロード

構成
・文字列操作
  + 文字列長
  + 文字列接続
  + インデックス位置
  + 部分文字列取得
  + 部分文字列置換
  + 文字毎置換
  + 文字列評価/実行
・リスト操作
  + リスト先頭から要素を取り出す
  + リスト先頭に要素を追加する
  + リスト末尾から要素を取り出す
  + リスト末尾に要素を追加する
  + リストの部分抽出/置換
  + リストと文字列の相互変換
  + リストを並べ替える
  + リスト中のパターン検索
・連想配列操作
  + 連想配列のデータ組合せ読み出し
  + 連想配列の要素削除
  + 連想配列の要素検索


文字列操作

 文字列長
 
  ・length()関数を使用する
    length(変数);
     or length 文字列変数;
  
  ・引数省略時は $_ が対象変数となる。

 ┌─────────────────────────────────────┐
  $str_a = '1234567890';
  $str_b = '1234567890';
  
  print 'str_a : ',length($str_a),"\n";
  print 'str_b : ',length($str_b),"\n";
 └─────────────────────────────────────┘
 ┌─────────────────────────────────────┐
  str_a : 10
  str_b : 20
 └─────────────────────────────────────┘


 文字列接続
 
  ・以下のように.(ドット)連結演算子を利用する。
    $str_c = $str_a.$str_b;
    
 ┌─────────────────────────────────────┐
  $str_a = '1234567890';
  $str_b = '1234567890';
  
  $str_c = $str_a.$str_b.'以上';
  
  print '$str_a=',"$str_a\n";
  print '$str_b=',"$str_b\n";
  print '$str_c=',"$str_c\n";
 └─────────────────────────────────────┘
 ┌─────────────────────────────────────┐
  $str_a=1234567890
  $str_b=1234567890
  $str_c=12345678901234567890以上
 └─────────────────────────────────────┘
 
  ・ここで
    $str_a = $str_a.$str_b;
   は以下のように省略表記できる。
    $str_a .= $str_b;

 ┌─────────────────────────────────────┐
  $str_a = '1234567890';
  $str_b = '1234567890';

  print 'pre :$str_a=',"$str_a\n";
  print '   $str_b=',"$str_b\n";
  
  $str_a .= $str_b;
  print 'post:$str_a=',"$str_a\n";
 └─────────────────────────────────────┘
 ┌─────────────────────────────────────┐
  pre :$str_a=1234567890
     $str_b=1234567890
  post:$str_a=12345678901234567890
 └─────────────────────────────────────┘


 インデックス位置
 
  ・指定文字列の位置はindex()関数で取得する。

 ┌─────────────────────────────────────┐
  $str_a = '1234567590';

  print "$str_a\n";
  print "01234567890123456789\n";
  
  $i_pos = index($str_a, '5');
  print '5の位置は :',"$i_pos\n";
 └─────────────────────────────────────┘
 ┌─────────────────────────────────────┐
  1234567590
  01234567890123456789
  5の位置は :8
 └─────────────────────────────────────┘
  
  ・この結果を見るとわかるように、index()関数が示す位置は「先頭から見た指定文
   字列の出現位置」
である。
  
  ・最後からの出現位置を調べるにはrindex()関数を使用する。

 ┌─────────────────────────────────────┐
  $str_a = '1234567590';

  print "$str_a\n";
  print "01234567890123456789\n";
  
  $i_pos = rindex($str_a, '5');
  print '5の位置は :',"$i_pos\n";
 └─────────────────────────────────────┘
 ┌─────────────────────────────────────┐
  1234567590
  01234567890123456789
  5の位置は :14
 └─────────────────────────────────────┘
 

 部分文字列取得
 
  ・substr()関数を使うことで、指定位置の部分文字列を取り出すことが出来る。
    (例)$str_extract = substr($str_a, 6, 4);
      $str_aの6文字目から4文字読み込んで、$str_extractへ代入

 ┌─────────────────────────────────────┐
  $str_a = '1234567890';

  print "$str_a\n";
  print "01234567890123456789\n";
  
  $str_extract = substr($str_a, 4, 4);
  print '4文字目から4文字は ',$str_extract;
 └─────────────────────────────────────┘
 ┌─────────────────────────────────────┐
  1234567890
  01234567890123456789
  4文字目から4文字は 34
 └─────────────────────────────────────┘


 部分文字列置換
 
  ・置換演算子「s///」により指定文字列を置換する
    (例)$str_a =~ s/4/A/
  
  ・「s///g」の場合、文字列中の合致部全てを置換する。
  
  ・「s///i」の場合、大文字/小文字の区別無く置換する。

 ┌─────────────────────────────────────┐
  $str_a = 'abcdefgABCDEFGabcdefg';
  $str_b = $str_a;
  $str_c = 'aAaBCDEFG';
  
  $str_a =~ s/a/Z/;
  print "$str_a\n";
  
  $str_b =~ s/a/Z/g;
  print "$str_b\n";
  
  $str_c =~ s/a/z/i;
  print "$str_c\n";

  $str_c =~ s/a/z/ig;
  print "$str_c\n";
 └─────────────────────────────────────┘
 ┌─────────────────────────────────────┐
  ZbcdefgABCDEFGabcdefg
  ZbcdefgABCDEFGZbcdefg
  zAaBCDEFG
  zzzBCDEFG
 └─────────────────────────────────────┘


 文字毎置換
 
  ・変換演算子「tr///」により、指定文字(組合せ)の変換を指定できる。
    (例) $str_a =~ tr/あいう/ぁぃぅ/;
        あ → ぁ
        い → ぃ
        う → ぅ

 ┌─────────────────────────────────────┐
  $str_a = 'あいうえお';
  $str_b = 'ABCDEFG';
  
  $str_a =~ tr/あいう/ぁぃぅ/;
  print "$str_a\n";
  
  $str_b =~ tr/A-Z/a-z/;
  print "$str_b\n";
 └─────────────────────────────────────┘
 ┌─────────────────────────────────────┐
  ぁぃぅえお
  abcdefg
 └─────────────────────────────────────┘


 文字列評価/実行
 
  ・eval()関数を使用すると、受け取った文字列を式として評価/実行する。
    (例)$str_eq = '2*3';
      $v_result = eval($str_eq);

 ┌─────────────────────────────────────┐
  while () {
    print '> ';
    $str_eq = <STDIN>;

    last if ($str_eq eq "\n");
    
    $v_result = eval($str_eq);
    print "$v_result\n";
  }
 └─────────────────────────────────────┘
 ┌─────────────────────────────────────┐
  Calc > 10 + 5 * 3
  25
  Calc > (10 + 5) * 3
  45
  Calc > (3 + 5) / (2 + 4) * 2
  2.66666666666667
  Calc >  ←ここで[Enter]を入力
 └─────────────────────────────────────┘
 
  ・尚、サンプルコード中で使用している「last」ステートメントはループ中から抜け
   る
ことを意味している。
  
  ・while () で無限ループを作っているが、[Enter]のみ入力されたときプログラムを
   終了させるために用いた。


リスト操作

 リスト先頭から要素を取り出す
 
  ・リストの先頭から要素を取り出す操作を考える。参照ではなく取り出しなので先頭
   要素が消失し、各要素のインデックス番号はデクリメントされる。
  
  ・尚、ここから今まで「配列」と呼んでいたのものを「リスト」と表記する(*1)。
  
  ・上記操作を行うには shift() 関数を用いる。
    (例)$ele_val = shift(@datas);

 ┌─────────────────────────────────────┐
  @datas = ('ABC', 'DEF', 'GHI');
  
  $v_index = 0;
  foreach (@datas) {
   print "$v_index : $_\n";
   $v_index++;
  }
  
  $str_a = shift(@datas);
  
  print '-' x 3, "\n";
  print "$str_a\n";
  print '-' x 3, "\n";
  
  $v_index = 0;
  foreach (@datas) {
   print "$v_index : $_\n";
   $v_index++;
  }
 └─────────────────────────────────────┘
 ┌─────────────────────────────────────┐
  0 : ABC
  1 : DEF
  2 : GHI
  ---
  ABC
  ---
  0 : DEF
  1 : GHI
 └─────────────────────────────────────┘
 
  ・サンプルコード中で使用している「x 3」繰り返し演算子と呼ばれる。繰り返し
   演算子の左側に置いた文字列orリストを指定回数展開する。


 リスト先頭に要素を追加する
 
  ・要素をリスト先頭へ追加したい場合 unshift()関数を用いる。ただし追加できる要
   素は「リスト」のみ
である。リストのデータ管理方法(*1)を考えれば当然。
     (例)@add = ('uvw','xyz');
       @source = ('ABC', 'DEF', 'GHI');
       $v_elenum = unshift(@source, @add);
  
  ・unshift()関数の戻り値は追加後の要素数である。

 ┌─────────────────────────────────────┐
  @add = ('uvw','xyz');
  @source = ('ABC', 'DEF', 'GHI');
  
  $v_index = 0;
  foreach (@source) {
   print "$v_index : $_\n";
   $v_index++;
  }
  
  $v_elenum = unshift(@source, @add);
  print '$v_elenum=',$v_elenum, ' $#source=',$#source,"\n";
  
  $v_index = 0;
  foreach (@source) {
   print "$v_index : $_\n";
   $v_index++;
  }
 └─────────────────────────────────────┘
 ┌─────────────────────────────────────┐
  0 : ABC
  1 : DEF
  2 : GHI
  $v_elenum=5 $#source=4
  0 : uvw
  1 : xyz
  2 : ABC
  3 : DEF
  4 : GHI
 └─────────────────────────────────────┘
 

 リスト末尾から要素を取り出す
 
  ・要素をリスト末尾へ追加するには pop()関数を使用する。pop()で取り出された要
   素はリストから消える。
     (例)$v_popval = pop(@datas);
  
 ┌─────────────────────────────────────┐
  @datas = ('ABC', 'DEF', 'GHI');
  
  $v_index = 0;
  foreach (@datas) {
   print "$v_index : $_\n";
   $v_index++;
  }
  
  $str_a = pop(@datas);
  
  print '-' x 3, "\n";
  print "$str_a\n";
  print '-' x 3, "\n";
  
  $v_index = 0;
  foreach (@datas) {
   print "$v_index : $_\n";
   $v_index++;
  }
 └─────────────────────────────────────┘
 ┌─────────────────────────────────────┐
  0 : ABC
  1 : DEF
  2 : GHI
  ---
  GHI
  ---
  0 : ABC
  1 : DEF
 └─────────────────────────────────────┘

 
 リスト末尾に要素を追加する
 
  ・要素をリスト末尾へ追加したい場合 push()関数を用いる。追加できる要素は「リ
   スト」のみである。
     (例)@add = ('uvw','xyz');
       @source = ('ABC', 'DEF', 'GHI');
       $v_elenum = push(@source, @add);
  
  ・push()関数の戻り値は追加後の要素数である。

 ┌─────────────────────────────────────┐
  @add = ('uvw','xyz');
  @source = ('ABC', 'DEF', 'GHI');
  
  $v_index = 0;
  foreach (@source) {
   print "$v_index : $_\n";
   $v_index++;
  }
  
  $v_elenum = push(@source, @add);
  print '$v_elenum=',$v_elenum, ' $#source=',$#source,"\n";
  
  $v_index = 0;
  foreach (@source) {
   print "$v_index : $_\n";
   $v_index++;
  }
 └─────────────────────────────────────┘
 ┌─────────────────────────────────────┐
  0 : ABC
  1 : DEF
  2 : GHI
  $v_elenum=5 $#source=4
  0 : ABC
  1 : DEF
  2 : GHI
  3 : uvw
  4 : xyz
 └─────────────────────────────────────┘


 リストの部分抽出/置換
 
  ・リストの指定位置要素を処理するには、splice()関数を使用する。尚、抽出後のリ
   ストデータは短くなる。
    (例)@data = splice(@source, 2);  # 要素[2]を抽出
      @data = splice(@source, 2, 3); # 要素[2]を先頭に3個の要素を抽出
      @data = splice(@source, 2, 3, ('a','b'));
                      # 要素[2]を先頭に3この要素をリスト
                      # ('a','b')に置換
  
  ・例に示すように戻り値は抽出データ又は操作後のリストになる。抽出データもリス
   トで受ける。

 ┌─────────────────────────────────────┐
  @source = ('ABC', 'DEF', 'GHI');
  
  @data = splice(@source,1,1);
  print "case1 - source : @source\n";
  print "    data  : @data\n";
  
  @source = ('ABC', 'DEF', 'GHI');
  @data = splice(@source,1,2);
  print "case2 - source : @source\n";
  print "    data  : @data\n";

  @source = ('ABC', 'DEF', 'GHI');
  @data = splice(@source,1,2,('abc','def','ghi'));
  print "case3 - source : @source\n";
  print "    data  : @data\n";
 └─────────────────────────────────────┘
 ┌─────────────────────────────────────┐
  case1 - source : ABC GHI
      data  : DEF
  case2 - source : ABC
      data  : DEF GHI
  case3 - source : ABC abc def ghi
      data  : DEF GHI
 └─────────────────────────────────────┘


 リストと文字列の相互変換
 
  ・リスト要素を連結して文字列変数へ代入するにはjoin()関数を用いる。1番目の引
   数は、セパレータ文字である。
     (例)$str_a = join("\t",@datas);
  
  ・逆に文字列をリスト化する場合はsplit()関数を用いる。
     (例)@datas = split(/\t/, $str_a);
  
  ・尚split()の戻り値を変数で受けた場合要素数が得られ、「@_」リストに結果が代
   入
される

 ┌─────────────────────────────────────┐
  @datas = ('ABC','DEF','GHI');
  
  $str_a = join("\t",@datas);
  $str_b = join(':',@datas);
  
  @datas2 = split(/\t/, $str_a);
  
  print "$str_a\n";
  print "$str_b\n";
  print "@datas2\n";
 └─────────────────────────────────────┘
 ┌─────────────────────────────────────┐
  ABC   DEF   GHI ← デリミタはタブになっている
  ABC:DEF:GHI
  ABC DEF GHI
 └─────────────────────────────────────┘


 リストを並べ替える
 
  ・リストをソートする。昇順にはsort()関数、逆順(*2)にはreverse()関数を用いる。
     (例)@datas2 = sort(@datas);
       @datas2 = reverse(@datas);

 ┌─────────────────────────────────────┐
  @datas = ('GHI','DEF','ABC');
  
  @datas2 = sort(@datas);
  @datas3 = reverse(@datas2);
  
  @datas4 = reverse(sort(@datas));
  
  print "@datas2\n";
  print "@datas3\n";
  print "@datas4\n";
 └─────────────────────────────────────┘
 ┌─────────────────────────────────────┐
  ABC DEF GHI
  GHI DEF ABC
  GHI DEF ABC
 └─────────────────────────────────────┘


 リスト中のパターン検索
 
  ・リスト中で指定パターンと合致した要素を探すにはgrep()関数を使用する。shift()
   関数やpop()関数と異なり、ソースとなるリストのデータは変わらない。
  
  ・grep()関数は戻り値を2種類(リスト,スカラー)取り得る。
    (例)@extract = grep(/ab/, @datas); //リストには一致要素が入る
      $extract_num = grep(/ab/, @datas); //リストには一致要素数が入る
  
 ┌─────────────────────────────────────┐
  @datas = ('abABC','cdDEF','abGHI','JKLab','cdMNO');
  
  @datas2 = grep(/ab/, @datas);
  print "@datas2\n";
  
  $datas3_num = grep(/cd/, @datas);
  @datas3 = grep(/cd/, @datas);
  print "$datas3_num\n";
  print "@datas3\n";
 └─────────────────────────────────────┘
 ┌─────────────────────────────────────┐
  abABC abGHI JKLab
  2
  cdDEF cdMNO
 └─────────────────────────────────────┘


連想配列操作

 連想配列のデータ組合せ読み出し
 
  ・連想配列からキー値とバリュー値を読み出すには、以下の関数を利用する。
    キー値読み出し    →リスト代入 : keys()関数
    バリュー値読み出し  →リスト代入 : values()関数
    キー&バリュー読み出し→リスト代入 : each()関数

 ┌─────────────────────────────────────┐
  %teams = ( 'G'=>'Giants', 'T'=>'Tigers',
        'D'=>'Dragons', 'S'=>'Swallows',
        'C'=>'Carp',  'B'=>'Baystars');
  
  @key_list = keys(%teams);
  print "@key_list\n";
  
  @val_list = values(%teams);
  print "@val_list\n";
  
  while (@key_value = each(%teams)){
    print "@key_value\n";
  }
 └─────────────────────────────────────┘
 ┌─────────────────────────────────────┐
  B C S D T G
  Baystars Carp Swallows Dragons Tigers Giants
  B Baystars
  C Carp
  S Swallows
  D Dragons
  T Tigers
  G Giants
 └─────────────────────────────────────┘
 
  ・サンプルの実行結果でわかるようにキー値の順番は連想配列の初期定義とは異なる
   順番となっている。連想配列の要素順はキー値の中身で決まるためである。
  
  ・ただし、keys()関数で読み出した順番とvalues()関数で読み出した順番は対応して
   いる。
  
  ・each()関数の結果はリストに入る。リストの[0]要素にキー値。[1]要素にバリュー
   値が代入される。


 連想配列の要素削除
 
  ・指定キーの要素を削除するには delete()関数を使用する。
     (例)$str_a = delete($teams{'T'});
  
  ・delete()関数の戻り値は削除した要素のバリュー値

 ┌─────────────────────────────────────┐
  %teams = ( 'G'=>'Giants', 'T'=>'Tigers',
        'D'=>'Dragons', 'S'=>'Swallows',
        'C'=>'Carp',  'B'=>'Baystars');
  
  $del_val = delete($temas{'T'});
  
  print "$del_val\n";
  while (@key_value = each(%teams)){
    print "@key_value\n";
  }
 └─────────────────────────────────────┘
 ┌─────────────────────────────────────┐
  Tigers
  B Baystars
  C Carp
  S Swallows
  D Dragons
  G Giants
 └─────────────────────────────────────┘
 
 
 連想配列の要素検索
 
  ・exists()関数は指定したキー値要素があるかどうかを調べる。結果はtrue/falseで
   返される。

 ┌─────────────────────────────────────┐
  %teams = ( 'G'=>'Giants', 'T'=>'Tigers',
        'D'=>'Dragons', 'S'=>'Swallows',
        'C'=>'Carp',  'B'=>'Baystars');
  
  while () {
    print "頭文字は? : ";
    $key_val = <STDIN>;
    
    last if ($key_val eq "\n");
    
    chop($key_val);
    if ( exists($teams{$key_val}) ) {
      print "YES : $teams{$key_val}\n";
    } else {
      print "No\n";
    }
  }
 └─────────────────────────────────────┘
 ┌─────────────────────────────────────┐
  頭文字は? : G
  YES : Giants
  頭文字は? : L
  No
  頭文字は? : B
  YES : Baystars
  頭文字は? :
 └─────────────────────────────────────┘

以上

注意
 (*1)配列は同一サイズのデータが連続に並んだものであり、リストは様々なサイズのデ
   ータが何らか(例えばポインタ等)の方法により結び付けられたもの
である。従って
   本来であれば下記をベースに考える。

 ┌─────────────────────────────────────┐
                  ┌─┐
    変数  : $v_a = 10; .......│10│
                  └─┘
                  ┌─┬─┬─┐
    配列  : $str_a = 'ABC'; ...│A │B │C │
                  └─┴─┴─┘
    リスト : @str_datas = ('AB','CDE', 'FG');
                  ┌─┐ ┌→┌─┐ ┌→┌─┐
                  │A │ │ │C │ │ │F │
                  ├─┤ │ ├─┤ │ ├─┤
                  │B │ │ │D │ │ │G │
                  └─┘→┘ ├─┤ │ └─┘
                        │E │ │
                        └─┘→┘
 └─────────────────────────────────────┘

 (*2)あくまで逆順であり、降順ではない。

[▲Perl Home▲]