====== 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に含まれない文字をHHHH;形式に変換してくれる。
===== マッチした語句を強調する =====
**サンプルソース:**
my $string = "AAABBBCCC
DDDEEEFFF
GGGHHHIII";
my @keyWords = ("AAA","EEE","III");
$string =~ s/</<<>/g;
$string =~ s/>/<>>/g;
$string =~ s/&/<&>/g;
$string =~ s/"/<">/g;
$string =~ s/'/<'>/g;
foreach my $keyWord (@keyWords) {
my @strings = split /(<.*?>)/, $string;
foreach my $str (@strings) {
next if ($str =~ /^<.*?>$/);
$str =~ s/($keyWord)/$1<\/b>/gi;
}
$string = join "", @strings;
}
$string =~ s/<<>/</g;
$string =~ s/<>>/>/g;
$string =~ s/<&>/&/g;
$string =~ s/<">/"/g;
$string =~ s/<'>/'/g;
print $string;
**処理結果:**
AAABBBCCC
DDDEEEFFF
GGGHHHIII
**備考:**
このように//split//のパターンを括弧で囲むと、パターンそのものも配列要素に含まれるようになる。
my $string = "AAABBBCCC
DDDEEEFFF
GGGHHHIII";
my @strings = split /(<.*?>)/, $string;
foreach (@strings) {
print "-> $_\n";
}
**処理結果:**
AAABBBCCC
DDDEEEFFF
GGGHHHIII