ユーザ用ツール

サイト用ツール


perl:tips

Perl - Tips

ユニコードハイフンの文字リスト

厳密には「ハイフン」ではないけど、「ハイフンっぽい」文字は種類が多く、一目では判別がつきにくい。
WindowsとMacでもデフォルトで使われるハイフンが違ったりする。
統一したい場合はこのリストを参考に一括置換してやると便利かも:-P

文字 コード 備考
- \x{002D} 通常使われる半角ハイフン
\x{00AD}
˗ \x{02D7­}
\x{2010}
\x{2011}
\x{2012}
\x{2013}
\x{2014}
\x{2015}
\x{2212}
\x{2500}
\x{2501}
\x{30FC} 全角音引
\x{FE63}
\x{FF0D}
\x{FF70} 半角音引

スクリプトの設置場所をカレントディレクトリにする

BEGIN {
  use File::Basename;
  chdir dirname($0);
}

use lib qw(./hoge/) などとuse libを使う場合はコンパイル時に変更する必要があるためBEGINで括る。

Dumperで日本語を出力する

use Data::Dumper; 

my $dump = Dumper(\%hash);
$dump =~ s/\\x{([0-9a-z]+)}/chr(hex($1))/ge;

print $dump;

コマンドラインにカッコよく出力する

my $ind = sprintf("%3.3d",$number);

print "\b\b\b$ind" if $number != $current_page;

文字を上書きしながら出力する。

実行環境のIPアドレスを取得する

use Socket;

socket SOCKET, PF_INET, SOCK_DGRAM, 0;

my $host_addr = pack_sockaddr_in(9999,inet_aton("111.222.333.444"));
connect SOCKET, $host_addr; 

my @sock_addr = unpack_sockaddr_in(getsockname(SOCKET));
my $local_ip = inet_ntoa($sock_addr[1]);

print $local_ip,"\n";

close SOCKET;

ダミーのUDPソケットを作り、それを相手ホストにconnect()し、getsockname()で自分のアドレスを得る。
IPアドレスやポート番号はダミーなので、必要な場合は適切なものに置き換える。

小数点を含む数字の計算

Perlで小数点以下を扱うとコンピュータの性質上期待通りの結果が得られないことがある。
これを回避するために、一旦小数点以下を含む数字を整数に戻して計算し、再度少数点以下に戻すという回避策がある。
以下のサンプルコードはその流れをサブルーチンにしたものであり、引数を2つとり引き算を行う。

sub float {
  my ($a,$b,$c,$x1,$x2);

  $a = shift;
  $b = shift;

  $a =~ s/0+$//;
  $a =~ s/\.$//;
  $b =~ s/0+$//;
  $b =~ s/\.$//;

  $a =~ /\d*\.(\d*)/;
  $x1 = $1;
  $b =~ /\d*\.(\d*)/;
  $x2 = $1;

  foreach (length($x1)) {$a *= 10;}
  foreach (length($x2)) {$b *= 10;}

  $c = ( $a - $b );

  foreach ((length($x1) + length($x2))) {$d /= 10;}

  return $c;
}

小数点を含む数字の四捨五入、切り上げ、切り捨て処理

小数点を含む数字の四捨五入(ROUND)、切り上げ(ROUNDUP)、切り捨て(ROUNDDOWN)を行う場合のサブルーチン。
これも 小数点を含む数字の計算 と同様に浮動小数点以下の誤差を極力抑えるよう配慮している。
ポイントとしては一旦数値を文字列として格納するところにある。
第一引数に解析したい数字、第二引数に小数点以下の数、第三引数にround,roundup,rounddownのいずれかを指定する。

use POSIX;

sub roundNumber{
  my $data = shift;
  my $rate = shift;
  my $mode = shift;

  my $rate  = 10 ** $rate;
  my $temp .= $data * $rate;
	
  if ($mode eq "round") {
    my $st_temp = $temp + 0.5;
    $data = floor("$st_temp") / $rate;
  }
  elsif ($mode eq "roundup") {
    $data = ceil("$temp") / $rate;
  }
  elsif ($mode eq "rounddown") {
    $data = floor("$temp") / $rate;
  }

  return $data;
}

UTF-8なプログラムでUTF-8以外のテキストファイルを出力する

スタンダード入出力のUTF8指定をオフにする。

use utf8;
#use open ":utf8";
#use open ":std";

my $data = "この文字列をCP932で出力したい。\n";

open FILE, ">./hoge.txt";
utf8::encode( $data );
Encode::from_to($data,"UTF8","CP932",Encode::XMLCREF);
print FILE $data . "\r\n";
close FILE;

Memo1

CP932はマイクロソフトがShift-JISを拡張したもの。
Shift-JISの中でも文字範囲が広い。

Memo2

Encode::XMLCREFを指定すると、CP932に含まれない文字を&#xHHHH;形式に変換してくれる。

マッチした語句を強調する

サンプルソース:

my $string    = "AAABBBCCC<br>DDDEEEFFF<br>GGGHHHIII";
my @keyWords = ("AAA","EEE","III");

$string =~ s/&lt;/<&lt;>/g;
$string =~ s/&gt;/<&gt;>/g;
$string =~ s/&amp;/<&amp;>/g;
$string =~ s/&quot;/<&quot;>/g;
$string =~ s/&apos;/<&apos;>/g;

foreach my $keyWord (@keyWords) {
  my @strings = split /(<.*?>)/, $string;

  foreach my $str (@strings) {
    next if ($str =~ /^<.*?>$/);
    $str =~ s/($keyWord)/<b>$1<\/b>/gi;
  }

  $string = join "", @strings;
}

$string =~ s/<&lt;>/&lt;/g;
$string =~ s/<&gt;>/&gt;/g;
$string =~ s/<&amp;>/&amp;/g;
$string =~ s/<&quot;>/&quot;/g;
$string =~ s/<&apos;>/&apos;/g;

print $string;

処理結果:

<b>AAA</b>BBBCCC<br>DDD<b>EEE</b>FFF<br>GGGHHH<b>III</b>

備考:

このようにsplitのパターンを括弧で囲むと、パターンそのものも配列要素に含まれるようになる。

my $string  = "AAABBBCCC<br>DDDEEEFFF<br>GGGHHHIII";
my @strings = split /(<.*?>)/, $string;

foreach (@strings) {
  print "-> $_\n";
}

処理結果:

AAABBBCCC<br>DDDEEEFFF<br>GGGHHHIII
perl/tips.txt · 最終更新: 2018/07/20 14:06 by taka