ユーザ用ツール

サイト用ツール


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

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.1529890849.txt.gz · 最終更新: 2018/06/25 10:40 by 127.0.0.1