2014年6月22日

漢数字を無思慮に洋数字に変える

縦組みだからとせっかく漢数字に直したけど、Blogで公開するときは横組み。漢数字のままでもいいんだけど、世間に迎合して洋数字に書き換えよう。

ということで、またまたperlスクリプトを書いてみた。ただ単純に置換しているだけだから、数字の入った漢字熟語まで無思慮に変換してしまうのでご注意を。

(『すぐわかるPerl』『すぐわかる オブジェクト指向 Perl』『文字コード「超」研究』の著者・深沢千尋さんがご自身のBlog「イジハピ!」に、このスクリプトの“すぐわかる”解説を書いてくれました。うれしい!  http://blog.query1000.com/archives/39051213.html


#!/usr/bin/perl

use utf8;
binmode STDOUT, ':utf8'; 
binmode STDERR, ':utf8'; 
binmode STDIN, ':utf8';

while(<>) {
  # 単位語の前に数字がない場合「一」を補う
    s/(?<![一二三四五六七八九千百十])(?=[兆億万])/一/g;
    s/(?<![一二三四五六七八九])(?=[千百十])/一/g;
  # 欠けている桁をゼロとして復活させる
    s/(?<=兆)(?![一二三四五六七八九][十百千万]?億)/〇億/g;
    s/(?<=億)(?![一二三四五六七八九][十百千]?万)/〇万/g;
    s/(?<=[兆億万])(?![一二三四五六七八九]千)/〇千/g;
    s/(?<=千)(?![一二三四五六七八九]百)/〇百/g;
    s/(?<=百)(?![一二三四五六七八九]十)/〇十/g;
    s/(?<=十)(?![〇一二三四五六七八九])/〇/g;
  # 単位語のうち千百十を消す
    s/[千百十]//g;
  # 億万でゼロを整理
    s/〇〇〇〇[億万]//g;
    s/(?<=[兆億万])〇+//g;
  # 洋数字に変換
    y/〇一二三四五六七八九/0123456789/;
  # 3桁毎にコンマを挿入
    s/(?<=\d)(?=(\d\d\d)+(?!\d))/,/g;

    print $_;
}


*7月7日訂正:次の赤字部分を付け加えました。これがないと「二億二百万」などで4桁余分の0が入ってしまいます。

  # 欠けている桁をゼロとして復活させる
    s/(?<=兆)(?![一二三四五六七八九][十百千万]?億)/〇億/g;
    s/(?<=億)(?![一二三四五六七八九][十百千]?万)/〇万/g;

*7月8日補正:単位語のうち兆億万は残して、ゼロの羅列を減らしました。

*7月9日訂正:億万でゼロを整理のところの2行目で洋数字の0は間違いで漢数字の〇にしないといけませんでした。
  # 億万でゼロを整理
    s/〇〇〇〇[億万]//g;
#   s/(?<=[兆億万])0+//g; #誤
    s/(?<=[兆億万])+//g; #正

2014年6月19日

洋数字を単位語入りの漢数字に変換するぞ

縦組みで数字はやはり漢数字で書きたい。でも原稿はたいてい洋数字で書いてくる。

いちいち書き換えるのは面倒だし、間違えやすい。そこは計算機に任せよう。

perlの先後読み正規表現を使って、単位語を入れる位置を指定すれば、意外に簡単かも。ちゃんと動くかな?


#!/usr/bin/perl

# utf-8テキストを扱うまじない
use utf8;
binmode STDOUT, ':utf8'; 
binmode STDERR, ':utf8'; 
binmode STDIN, ':utf8';

while (<>) {
  # 数字は半角にそろえておく
    y/1234567890/1234567890/;
  # 単独の0は「ゼロ」に書き換える
    s/(?<!\d)0(?!\d)/ゼロ/g; 
  # 桁区切りのコンマを取っておく
    s/(?<=\d),(?=(\d\d\d)+(?!\d))//g;
  # 4桁ごとに区切って万億兆を挿入
    s/(?<=\d)(?=\d\d\d\d(?!\d))/万/g;
    s/(?<=\d)(?=\d\d\d\d(?=万))/億/g;
    s/(?<=\d)(?=\d\d\d\d(?=億))/兆/g;
  # 下から1桁ずつ十百千を挿入
    s/(?<=\d)(?=\d(?!\d))/十/g;
    s/(?<=\d)(?=\d(?!\d))/百/g;
    s/(?<=\d)(?=\d(?!\d))/千/g;
  # 0になってる桁を削除
    s/0[十百千]//g;
    s/億0万/億/g;
    s/兆0億/兆/g;
    s/0//g;
  # 十百には1をつけない
    s/1([十百])/\1/g;
  # 各桁を漢数字に書き換え
    y/123456789/一二三四五六七八九/;

    print $_;
}


6月25日 修正:「0万」「0億」が消えてしまってはよくない場合があるので、「億0万」「兆0億」の場合だけ消えるようにした。
7月10日 改訂:もとの洋数字がコンマ区切りでも変換でるように、コンマ消去の処理を最初に付け加えた。ただしく3桁ごとに区切ってないとうまく変換できないけど、後にコンマが残るので、もとの桁区切りがおかしかったことがわかっていいかな。
10月13日 修正:「海抜0m地帯」なども0が消えてはいけないし、こういったものは縦書きだと「ゼロ」と書くことが多いので、そんな場合に対応できるようにした。



未来の自分のためにちょっとメモ:

(?<=\d)(?=\d\d\d\d(?!\d))は、

後読み
後ろをちょっと振り返えれば (?<= )
数字\dがひとつは見えて (?<=\d)

先読み否定先読み
先を望めば (?= )
数字がよっつ見えて \d\d\d\d
さらにその先は数字じゃない (?!\d) (←もちろん、文字がなくてもかまわない)
(?=\d\d\d\d(?!\d))

そういう場所。
文字じゃなくて場所だってところが味噌。
組版的には字間かな。