スクリプト言語

自然言語処理と直接には関係しないスクリプト言語処理実験やExcel関数やVBAマクロなどの話題。

VBA,VB,HTS,HTA,JavaScript,PHP, Unix Like Tools (Sort, Uniq, Join, Sed, Grep, AWK, Perl,and so on)

中国語と国語学のためのBookmarklet、簡体字・繁体字変換Toolなど。

目次

[Go to top page]


GIFファイルのメタデータ書き換え

ImageMagickでSVGファイルをGIFに変換したら、メタデータ領域にImageMagickの情報が書き込まれていることに気づいた。

このメタデータをビジュアルで確認できるソフトはJpegAnalyzer Plus(かみさか氏作)しかないようだ。

※バイナリエディタで見れば気づくかもしれないが。

GIFのヘッダ情報に関する解説で充実している所はここここ
ありがたく参考にさせて頂いて、今回の作業で必要な部分の要点をまとめると、以下のようになるらしい。

JpegAnalyzer PlusでのApplication Extensionブロックの表示

Application Extensionブロック…アプリケーション(ソフトウェア)の独自情報を書き込む欄。

この中に小分類としてApplication Identifierが8文字分、次いでAuthentication Codeが3文字分、固定長で確保されている。

歴史的な経緯によって、アニメーションGIFにはApplication Extension block には“Netscape”と“2.0”という文字列が含まれる。

Application Extensionは、0x21 0xFF 0x0B で開始され、終端記号は0x00である。

00000000: 47 49 46 38 39 61 60 00 60 00 F2 00 00 0D 0D 0D 
00000010: 2F 2F 2F 68 68 68 A0 A0 A0 B0 B0 B0 90 90 90 EC 
00000020: EC EC 00 00 00 21 F9 04 01 00 00 07 00 21 FF 0B 
00000030: 49 6D 61 67 65 4D 61 67 69 63 6B 0E 67 61 6D 6D 
00000040: 61 3D 30 2E 34 35 34 35 34 35 00 2C 00 00 00 00 
00000050: 60 00 60 00 00 03 D4 78 BA DC FE 30 CA 49 AB BD 
00000060: 38 EB CD BB FF 60 28 8E 64 69 9E 68 AA AE 6C EB 
00000070: BE 70 2C CF 74 6D DF 78 AE EF 7C EF FF C0 A0 70 
00000080: 48 2C 1A 8F C8 A4 72 C9 6C 3A 9F D0 A8 74 4A AD 
00000090: 5A AF D8 AC 76 CB ED 7A BF E0 B0 98 63 28 8F 15 
000000A0: 86 02 C1 30 36 08 00 00 C1 80 0D 26 C0 EF 82 35 
000000B0: 7D 6B 08 DC FF 79 7B 0B 04 05 02 05 03 03 04 8A 
000000C0: 8B 8C 8D 8E 8F 90 91 92 93 8E 6F 7F 97 02 82 07 
000000D0: 06 97 9D 77 7E 9E A0 9E A3 A4 9D A2 A5 A8 A1 04 
000000E0: 0D 69 00 01 01 86 89 88 B2 B3 B5 B6 B7 B4 B9 04 
000000F0: B8 88 BB BC B6 BE B3 BE C1 88 87 C5 BD 6B 0E 65 
00000100: CB 9A 67 CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA 
00000110: DB DC DD DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA 
00000120: EB EC ED EE EF F0 F1 F2 F3 50 09 00 3B 

ImageMagickが生成したGIFファイルには以下のように書き込まれていた。

Application Identifier ImageMag
Authentication Code ick

これを削除し、その代わりにComment Extensionブロックを設定したい。

Comment Extensionブロック…GIFファイル中にコメントを記入するための拡張ブロック。コメントは画像表示に影響を与えない。

0x21 0xFEで始まり、その次の1バイトで文字列長を1~255までの値で指定する(0と指定してしまうと、終端記号の意味になってしまう)。

今回の作業では、「Copyright (C) 1996- AI-NET Corporation. All rights reserved.」という文字列を入れたい。字数を数えると60文字分ある。

従って60を16進数に直した 0x3Cと入れれば良いのだろう。

そして、終端記号は0x00である。

00000000: 47 49 46 38 39 61 60 00 60 00 F2 00 00 0D 0D 0D 
00000010: 2F 2F 2F 68 68 68 A0 A0 A0 B0 B0 B0 90 90 90 EC 
00000020: EC EC 00 00 00 21 F9 04 01 00 00 07 00 21 FE 3C 
00000030: 43 6F 70 79 72 69 67 68 74 20 28 43 29 20 31 39 
00000040: 39 36 2D 20 41 49 2D 4E 45 54 20 43 6F 72 70 6F 
00000050: 72 61 74 69 6F 6E 2E 20 41 6C 6C 20 72 69 67 68 
00000060: 74 73 20 72 65 73 65 72 76 65 64 2E 00 2C 00 00 
00000070: 00 00 60 00 60 00 00 03 D4 78 BA DC FE 30 CA 49 
00000080: AB BD 38 EB CD BB FF 60 28 8E 64 69 9E 68 AA AE 
00000090: 6C EB BE 70 2C CF 74 6D DF 78 AE EF 7C EF FF C0 
000000A0: A0 70 48 2C 1A 8F C8 A4 72 C9 6C 3A 9F D0 A8 74 
000000B0: 4A AD 5A AF D8 AC 76 CB ED 7A BF E0 B0 98 63 28 
000000C0: 8F 15 86 02 C1 30 36 08 00 00 C1 80 0D 26 C0 EF 
000000D0: 82 35 7D 6B 08 DC FF 79 7B 0B 04 05 02 05 03 03 
000000E0: 04 8A 8B 8C 8D 8E 8F 90 91 92 93 8E 6F 7F 97 02 
000000F0: 82 07 06 97 9D 77 7E 9E A0 9E A3 A4 9D A2 A5 A8 
00000100: A1 04 0D 69 00 01 01 86 89 88 B2 B3 B5 B6 B7 B4 
00000110: B9 04 B8 88 BB BC B6 BE B3 BE C1 88 87 C5 BD 6B 
00000120: 0E 65 CB 9A 67 CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 
00000130: D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 
00000140: E9 EA EB EC ED EE EF F0 F1 F2 F3 50 09 00 3B 

ということで、バイナリ置換すればよろしいのだが、tr では正規表現[^\x00]+が指定できず、なんだか上手く行かない。

Kipp版 Jperl(jperl5.005_03-990822 Built 21:32:17 Nov 6 1999)ではbinmodeをワンライナーで指定する方法がよくわからなかった。

5.8以降のWindows版Perlは、ActivePerlであれStrawberryPerlであれ、ちょっと使う気になれない
5.6.xの頃までは頑張ったけど、文字コードのフラグが色々面倒で、もう勉強するのが嫌になってしまった。

Windowsの「UNIX ベース アプリケーション用サブシステム」に入っているPerlは"This is perl, v5.8.8 built for authenticamd-interix"とある。

これで

perl -p -i.back -e 's/\x21\xFF\x0B[^\x00]+\x00/\x21\xFE\x3C\x43\x6F\x70\x79\x72\x69\x67\x68\x74\x20\x28\x43\x29\x20\x31\x39\x39\x36\x2D\x20\x41\x49\x2D\x4E\x45\x54\x20\x43\x6F\x72\x70\x6F\x72\x61\x74\x69\x6F\x6E\x2E\x20\x41\x6C\x6C\x20\x72\x69\x67\x68\x74\x73\x20\x72\x65\x73\x65\x72\x76\x65\x64\x2E\x00/g' *.gif

こんな感じにしたら、動いた。

JpegAnalyzer PlusでのComment Extensionブロックの表示

これから18万個のファイルを書き換え操作せにゃならん。がんばれHDD。

ImageMagickのmogrifyコマンドによるSVG→GIF一括変換

ImageMagickをダウンロードしようとすると、各種あってわけがわからないよ。

  1. ImageMagick-X.X.X-XX-Q16-x64-dll.exe←64ビット用各種DLL付属でRGBの各値を16bit(RGBAを8byte)で処理する山盛りセット。
  2. ImageMagick-X.X.X-XX-Q16-x64-static.exe←同上のDLLなしセット。
  3. ImageMagick-X.X.X-XX-Q8-x64-dll.exe←64ビット用各種DLL付属でRGBの各値を8bit(RGBAを4byte)で処理する使用メモリ半減セット。
  4. ImageMagick-X.X.X-XX-Q8-x64-static.exe←同上のDLLなしセット。
  5. ImageMagick-X.X.X-XX-Q16-x86-dll.exe←32ビット用各種DLL付属でRGBの各値を16bit(RGBAを8byte)で処理する山盛りセット。
  6. ImageMagick-X.X.X-XX-Q16-x86-static.exe←同上のDLLなしセット。
  7. ImageMagick-X.X.X-XX-Q16-x86-windows.zip←Win32ポータブル用。解凍するだけで動くレジストリを汚さないヤツ。

こういうことらしい。それで、QとはQuantumDepthのことで、PNG,GIF,JPEGでTrueCollarと呼ばれるのは大体8bitなんだそうです。

ということで、3番目の「Q8-x64-dll」が扱いやすいらしい。

以下、ImageMagick-6.9.0-Q16-x64-dll(DLL同梱版)であれこれオプションを試して、程良い感じを得られたコマンド。

mogrify -geometry 96x96! -density 96x96 -alpha opaque -transparent white -antialias -colors 16 -format gif C:\svg\*.svg

各オプションの意味の自分用メモ。

: pngをgifに一括変換。入出力の指定順がconvertコマンドと逆のように見えるので注意。
: 縦横96ドットにリサイズ -geometry 96x96!
: 1ドットあたりを(72ピクセルではなく)96ピクセルに変更 -density 96x96
: アルファチャネルを有効にし、それを完全に不透明にする -alpha opaque
: 白背景を透過-transparent white
: アンチエイリアスをかける(非常に微細な差しか出ないが1倍で若干太めに出る)-antialias
: 色数は16色に減色 -colors 16

以下は、あんまり良い結果が得られなかったコマンド。

: 当初の指定。多数のファイル中、背景が透明化されないファイルがチラホラとある。
mogrify -geometry 96x96! -density 96x96 -transparent white -colors 16 -format gif C:\svg\*.svg

 

: これでもダメ。多数のファイル中、背景が透明化されないファイルがチラホラとある。
mogrify -geometry 96x96! -density 96x96 -transparent white -antialias -colors 16 -format gif C:\svg\*.svg

関連リンク

cronを使ってディレクトリのバックアップと全部削除

以下、CPIのシェアードプラン(Z1)での設定です。

さくらインターネットやエックスサーバーやヘテムルでは違うかもしれません。

CPIのシェアードプランZ1からACE01にサーバを引っ越しました。

DNSを書き換えてもらい、ドメイン名の紐付けが変わったのを確認。

ディレクトリのバックアップ

「さて、旧サーバ(Z1)に残っていたデータを一応、丸ごとバックアップしておこう…。」

ACE01の場合は、ここに書いてある(連載第1回目の記事だけでよろしい)。

Z1サーバでは「AddHandler x-httpd-php536 .php」は「AddHandler x-httpd-php528 .php」です。

特定ディレクトリのバックアップは、/html/svg/と/html/gif/をそれぞれのファイルにバックアップする場合は以下のような感じ。

一応、バックアップできる例(やや問題あり。後述。)

/usr/bin/tar cvfz /usr/home/z999999m99/html/svg.tar.gz /usr/home/z999999m99/html/svg
/usr/bin/tar cvfz /usr/home/z999999m99/html/gif.tar.gz /usr/home/z999999m99/html/gif

「z999999m99」はZ1でのマルチドメインの場合。Z1での主ドメインの場合は「z999999」となる。

これをBOMなしのUTF-8、改行はCR+LFで保存。ファイル名は「backup.sh」とでもしておく。

使用しているエディタによっては、気づかぬうちに拡張子が「.sh.txt」となってしまう場合があるので注意。

こいつを、/html/直下にFTPで転送します。ASCIIモードで転送します。

パーミッションは775か705あたりがよろしいようです。604で送ったら動きませんでした。

次いで、Webコントロールパネルに入って、[制作ツール]→[スクリプト定期実行ツール]で「/html/backup.sh」を指定する。

以下の「新規登録」の所で、「実行するスクリプトを選択してください」の▼から「/html/delall.sh」を指定し、今から3分後くらいを「毎時」「○○分」というように指定して「追加」します。

「3分後くらい」と書きました。動作を1分後に指定しかなったのは、ntp.nict.jpの時刻サーバと比較すると、あなたのパソコンと、CPIのサーバとで、それぞれ、ちょっとだけ時刻がずれているかもしれないからです。

cronでディレクトリを圧縮ファイルにする

さて、15分くらいたってから、FTPクライアントでもう一度、サーバに接続してみましょう。

確認を即座に行わないのは、圧縮などの場合、ある程度の処理時間がかかるからです。

おお!できたできた! ダウンロードはバイナリモードで行います。

シェルをアップロードした時にASCIIモードにしたままで、切り替え忘れてダウンロードすると、壊れたファイルがHDDに保存されるで注意。

tar.gzファイルが生成された。

11:22分に実行開始。
その6分後、11:28分にsvgの圧縮ファイルが生成された。この圧縮ファイルには18万3千個のファイルが入っている。
更に3分後、11:31分にgifの圧縮ファイルが生成された。この圧縮ファイルには9万6千個フのァイルが入っている。

でもこれだと絶対パスで保存されるんだなぁ…。

「gif.tar.gz」が生成されるんだけど、それをFTPクライアントでWindowsにダウンロードして解凍すると「gif.tar」が出てくる。

それを解凍すると、「usr/home/z999999m99/html/gif/」が作られる。

相対パスで圧縮したかったんだが、どうしたものか…。

CDしてから生成すれば良いのかもしれない。試していないけど、たぶん、こんな感じ?

cd /usr/home/z999999m99/html/
/usr/bin/tar cvfz /usr/home/z999999m99/html/svg.tar.gz /svg
/usr/bin/tar cvfz /usr/home/z999999m99/html/gif.tar.gz /gif

その他に、-Cオプションというのがあるそうな。

/usr/bin/tar cvfz /usr/home/z999999m99/html/svg.tar.gz -C /usr/home/z999999m99/html svg
/usr/bin/tar cvfz /usr/home/z999999m99/html/gif.tar.gz -C /usr/home/z999999m99/html gif

引数が5個になるのね。これで/svg/ディレクトリと/gif/ディレクトリだけを圧縮できるそうな。

最後の書き方で試してみたら、上手く行った。やったね!

ディレクトリの削除

「さて、旧サーバに残っていたデータを削除しよう…。」

…ここでハマりました。

FTPクライアントで再帰的な削除をがんばると、とても時間がかかって大変です。

CPIにはSecure File ManagerというWebブラウザで操作するナイスな仕組みが用意されています。

[Webコントロールパネル]→[FTP/ファイル管理]→[セキュアファイルマネージャ]でアクセスできます。

CPIのセキュアファイルマネージャ

ところが、「お客様のドメイン名」を入力し、「FTPアカウント」と「パスワード」を旧サーバのものを入れた場合、どうなるか?

なんと、セキュアファイルマネージャには入れません。

そして、「お客様のドメイン名」を入力し、「FTPアカウント」と「パスワード」を新サーバのものを入れた場合、どうなるか?

当然、新サーバのACE01の方に入ります。

そして、ACE01だとSSHを使えますが、Z1ではSSHはありません。

う~ん…困った。

仕方ないので、これもcronでシェル操作をすることにしました。

おっかない操作なので、念のため、挙動範囲を絞り込むことにしました。

/html/以下にあるcgi-bin以外のディレクトリを手動で_で始まるものに変更します。

例えば

/html/gif/
/html/svg/

/html/_gif/
/html/_svg/

などとするわけです。

次いで、以下の内容をUTF-8、改行はCR+LFで保存。

rm -rf /usr/home/z999999/html/_* > /dev/null 2>&1

なお、「z999999」の部分は、あなたのユーザIDです。マルチドメインの場合は「z999999m99」のようにちょっと長いかも。

あ、この命令は一行だけですが、改行を入れること。

ファイル名は例えば「delall.sh」とでもしておきましょう。

使用しているエディタによっては、気づかぬうちに拡張子が「.sh.txt」となってしまう場合があるので注意。

こいつを、/html/直下にFTPで転送します。ASCIIモードで転送します。

パーミッションは775か705あたりがよろしいようです。604で送ったら動きませんでした。

設置が終わったら、[Webコントロールパネル]→[制作ツール]→[スクリプト定期実行ツール]に入ります。

以下の「新規登録」の所で、「実行するスクリプトを選択してください」の▼から「/html/delall.sh」を指定し、今から3分後くらいを「毎時」「○○分」というように指定して「追加」します。

「3分後くらい」と書きました。動作を1分後に指定せず、確認も即座に行わないのは、ntp.nict.jpの時刻サーバと比較すると、あなたのパソコンと、CPIのサーバとで、それぞれ、ちょっとだけ時刻がずれているかもしれないからです。

cronでディレクトリ削除

さて、削除ですからすぐに結果は出ているでしょう。

4分くらいたってから、FTPクライアントでもう一度、サーバに接続してみましょう。

たぶん、ディレクトリ名が「_」で始まるディレクトリと、その配下のファイル群は全て消えているはずです。

消えていないように見えた場合は、FTPクライアントの画面をリフレッシュしてみてはどうでしょう?

それでもダメな場合は、たぶん、パーミッション設定をちゃんとしていないか、スクリプトの行末に改行が入っていません。

サーバ退去時に必要なその他の掃除

契約解除後になると、アクセスできなくなる。

サーバ上に残しておくと、「思わぬ時に、思わぬ形で、全世界に丸見え」になるかもしれない。しかも、削除権限なし。

だから、クリーニングは大切。

やらねばならない作業の例。

User-agent: *
Disallow: /
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<!-- † -->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="ja-JP">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta name="robots" content="noindex,nofollow,noarchive">
<meta http-equiv="refresh" content="0;URL=http://www.example.jp">
</head>
<body>
</body>
</html>
Options +FollowSymLinks -Indexes
RewriteEngine On

RewriteCond %{HTTP_HOST} ^(127\.0\.0\.1)(:80)? [OR]
RewriteCond %{HTTP_HOST} ^(2130706433)(:80)? [OR]
RewriteCond %{HTTP_HOST} ^(bvdeus999\.secure\.ne\.jp)(:80)? [NC]
RewriteRule ^(.*) http://www.example.jp/$1 [R=301,L]

<FilesMatch "^\.ht">
Satisfy all
Order Allow,Deny
Deny from all
</FilesMatch>

CPIへのお申し込みは、以下からどうぞ。

シェアードプラン(共有サーバACE シリーズ):ディスク容量無制限。月間転送容量も(あまりにも過剰でない限りは)上限なし。マルチドメイン数無制限で各ドメイン毎に1個ずつIPアドレスを付与。.htaccess可。DB 使い放題。ftpアカウント数無制限。メールアカウント数無制限。SSHあり。月額費用 3,800円(税別)~

CloudCore VPSCVシリーズ):超高速・高性能でウェブサービス。開発に最適な VPS。全 4プラン。月額費用 1,200円(税別)~

マネージドプラン専用サーバCHM-S シリーズ):サーバー環境をパッケージ化したマネージド専用サーバー。リソース専有で安定稼働。

ルート権限付ハイブリッドプラン物理専用サーバCHP/仮想専用サーバCHV シリーズ):サーバ環境を自由に構築。CPI への運用代行も選べる root 権限付専用サーバ。

目次へ戻る

Excelで対象セル範囲とは別のセルに重複データのチェック結果を表示する方法

Excelでの重複データのチェックは、条件付き書式を使う方法を紹介しているサイトが多いようです。

でも、それだと、単に重複セルに色が付くだけなんですよね。

「対象範囲とは別のセル」に、「何という値が重複している」と、具体的に示してくれる方法が、なかなか見つかりません。

仕方ないので自分で工夫してみました。
※なお、IFERROR関数とMODE.SNGL関数はExcel2007以降で対応。
Excel2003までの場合はISERROR関数とMODEで類似のことができるはずです。

サンプルファイルのダウンロード→RepetitionCheck.xlsx

B13セルには以下の式が入力してあります。

=IF(COUNTIF(B2:B11,"")=0,IFERROR(MODE.SNGL(B2:B11)&"が重複しています!","OK:重複は1つもありません。"),"未入力のセルがあります。全部埋めてください。")

IF関数の条件分岐の最初にある COUNTIF(B2:B11,"")=0 の部分で、未入力セルの数をカウントし、そのセル数が0であるかどうかを確認します。

未入力セルが0に等しくないときには「未入力のセルがあります。全部埋めてください。」とメッセージを出します。

すべてのセルを埋めて、IF関数の前半部分の条件式をtrueが返るようにすると、IF関数の前半の処理を行います。

そこで未入力部分に8を入れてみました。つまり、上から10,10,,8,7,5,5,4,3,2,1となるようにしてみたわけです。

つまり、10が2個、5も2個となって、2箇所、重複データが入っていることになります。

そういう場合、最頻値を出す関数、MODE.SNGL(B2:B11)&"が重複しています!"が(数値の大きい方から)効いて「10が重複しています!」というメッセージが出ます。

10のうち、一方を9に書き換えると、MODE.SNGL(B2:B11)&"が重複しています!"が(数値の小さい方に移り、残りの最頻値である5を指して「5が重複しています!」というメッセージが出ます。

56に変更すると、最頻値は1つも存在しなくなるのでMODE.SNGL関数は#n/aを返します。

IFERROR関数は、その#n/aを受け取って、「OK:重複は1つもありません。」と表示します。

目次へ戻る

VBScript(VBS)での改行の扱いの留意点

正規表現のマッチングでハマる所

VBScriptではMultilineがTrueでもGlobalがTrueでも、"."の中には"vbCr"は含まれるけど"vbLf"は含まれないんだって!

そうすると、VBSで"vbCrvbLf"が各行の行末にある複行レコードを読み込んだ場合、「Strings1+CR+LF+Strings2+CR+LF+Strings3+CR+LF+EOF」に対して「(^.*$)(^.*$)(^.$*)」とした配列の中身は$1は「Strings1+CR」、$2は「Strings2+CR」、$3は「Strings3+CR」となる。要するにLFでSplitしたような感じになるらしい。

問題点A

配列の末尾にCRがついていることに気づかないで文字列を接合すると、内部で加工している最中でも色々とエラーが出そうで面倒。
最終出力時に「Strings1+CR」に対してWriteLineメソッドを行った場合、「Strings1+CR+CR+LF」とかになってしまう可能性があるかもしれない。

問題点Aの対処法

Multilineで読み込んだら、速攻で内部の改行を全て「vbLfのみ」で統一する。

' 前処理:読み込みしたデータの改行をLF(0A)に統一
inText = replace(inText,VbCrLf,VbLf)
inText = replace(inText,VbCr,VbLf)

問題点B

"."の指定で"vbLf"はsedやPerlのs修飾子に相当する文字列に入らない。
だから、「Strings1+CR+LF+Strings2+CR+LF+Strings3+CR+LF+EOF」に対して「Strings1.*?Strings3」としても、マッチしない。
理由は、LFでSplitされてしまうから(※但し、"vbCr""."の中に含まれる)。
"."にLFも含めてマッチさせたい場合、どうすんのよ?

問題点Bの対処法

[vbLf.]のように文字クラスで指定して「Strings1[vbLf.]*?Strings3」と処理する。
このキャラクタクラス指定だと"."側がCRにヒットして、"vbLf"側がLFにヒットするので、内部的にはCR+LFの2文字として認識されるということになる。字数を勘定する時には注意。

出力先ファイルへの書き込みでハマる所

出力先ファイルに書き込みで

objFile.WriteLine (outText)

のようにWriteLineメソッドを指定をすると、「文字列」の最後にCR+LFを追加して出力する。
(追記されるのはLFではなく、CR+LFなんだそうな。)
そして、MultilineTrueだと、ここで勘違いが原因で、ハマる。

「なんでファイルの最後に余計な改行が1個入っちゃうんだろ?」という風に思うわけですね。

その勘違いとは、「各行」の意味についてである。

MultilineTrueだと、メモリ上に展開されている「改行を含んだ文字列」の「全体の方」が1つの大きな1レコードとして扱われる(配列は1個)のである。

仮に、「全体の方」の内部に改行などが存在したとしても、それはフィールドセパレータとしても(使おうと思えば)使える「単なる文字」の意味しか持っていない。

以上のような状況なので、WriteLineメソッドでは出力したファイルの末尾に、余分に1つだけ改行が入るのだ。
MultilineTrueの場合、「改行を含んだ文字列」の「全体」の、更に内部に存在する各行がWriteLineされるのではない。

MultilineTrueで、既に、意識的にデータの各末尾に改行を付与してあるのだったら、Writeメソッドを使って以下のようにすれば良い。

objFile.Write (outText)

ちなみに指定した回数分、空行を出力する WriteBlankLines というメソッドもあるらしい。

目次へ戻る

コマンドラインで順列組み合わせ重複ありを出力する

準備

補足:文字コードについて

コマンドラインからCHCP 65001でUTF-8に、CHCP 850でUTF-16LEに変更できる。
CMD.EXE /UでもUTF-16LEになる。Shift_JISに戻すにはCHCP 932。
CHCPは、たぶんチェンジ・コードページのことだと思う。

なお、コードページを換えた場合は、バッチを保存する時の文字コードもそれに合わせる必要がある。これはonigsedについても同じ。
あと、CMD.EXEでは、CHCP 65001しても、フォントの設定が上手く行かない場合が多い。
ECHOが出て、標準入力からエラーコードを返してやるようなインタフェースのバッチだと困る。
ただ、フォントが化けていてもリダイレクトやパイプのような入出力そのものはきちんとUTF-8で送られているようだ。
何をどうやっても難しいのであきらめ所を見極めるのが大切。
あんまり気にしない方が良い。

いっそのこと、シェルを替えてしまうのも手かもしれない。
Cygwin入れてコンパイルとか面倒くさいのでWinZsh(zsh.exeが3.0.8deb14、MSVC6-1で2010年2月コンパイル。バイナリはこれ一つだけで後は山のようなドキュメント。コードページがANSIである。lsと入れただけで障害モジュールの名前: ntdll.dllとエラーが出る。管理者権限で起動してもだめ。残念。)とかwin-bash(bash.exeとsh.exeがMSVC++4.0で2007年9月コンパイル。それ以外のUnixLikeToolsが2003年7月のコンパイルのCygwin版。たぶんUnicodeは通らない。残念。)とか前寺さん作のComWin32(シェア・ウェア)とか。
今探してみたら、SteelCommandというのがカッコイイ。タブとして複数枚のシェルウィンドウを開ける上に、GUIなディレクトリエクスプローラが付いている。FDやMIELのDOS窓版みたいなデザイン。Python窓や.NET窓も付いている。サイトに動画デモあり。一見の価値あり。
但しUTF-8などは未対応。nkfを通せとの由。残念だが、漢文やる人には向いていないようだ。
結局、WindowsPowerShellということになるんだろうか。権限必要だからみんなが使う雰囲気にならないんだよね。WSHは結構流行ったのに。


3Combination.cmd(仮称)のコード

2文字でのやり方をナカガワアキラ氏@Hitoashi-Osakiniに教えて貰い、3文字の場合に改造したコードは以下のような感じ(要onigsed)。
FOR文の入れ子で、変なオプションも山盛り。すこぶる難解である。半年後に30分以内で解読できる自信がない。
出力結果数と突き合わせる検算は、高精度計算サイトが便利。

※3文字で2分40秒くらいで出力された。案外、速い。バッチ、恐るべし。

@ECHO OFF
CLS
DEL output3.txt > NUL 2>&1
@ECHO =================================
@ECHO 3文字の順列組み合わせ(重複あり)
@ECHO =================================
@ECHO 開始時刻 %DATE:/=-% %TIME: =0%
@ECHO 開始時刻 %DATE:/=-% %TIME: =0%>> output-time.txt
FOR /F delims^=^ eol^= %%A IN (input.txt) DO (
FOR /F delims^=^ eol^= %%B IN (input.txt) DO (
FOR /F delims^=^ eol^= %%C IN (input.txt) DO (
@ECHO "%%A%%B%%C">> output-tmp.txt
)
)
)
@ECHO 終了時刻 %DATE:/=-% %TIME: =0%>> output-time.txt
@ECHO =================================>> output-time.txt
@ECHO 終了時刻 %DATE:/=-% %TIME: =0%
@ECHO =================================
@ECHO 以下に結果の一覧を表示します。
PAUSE
onigsed.exe --ctype=SJIS -e "s/^\"\(...\)\"$/\1/g" output-tmp.txt > output3.txt
DEL output-tmp.txt > NUL 2>&1
TYPE output3.txt
@ECHO =================================
@ECHO 今回の結果は「output3.txt」に保存されています。
@ECHO 開始・終了の時刻は「output-time.txt」に保存されています。
@ECHO =================================
@ECHO この画面を閉じます。
PAUSE
EXIT

応用の考察

目次へ戻る

色々なソースコードのハイライター

ソースコードの見栄え調整用のツールをいくつか試し、HTMLの末尾、閉じのbodyタグ直前にJavaScriptを置くのは嫌なんだぁ~!で格闘した顛末を記しておきます。

はやり始めたばかりの頃にすぐに飛びつかないのがポイントですね。

旦那や女房や畳やドラえもんやCPUなどのハードウェア・テクノロジーは、新しい方がいいが、味噌やラーメン屋やOSやWeb実装のようなソフトウェア・テクノロジーは、ある程度、寝かして置いたものの方がいいのである。

例えば、VRMLってフォーマットを、今、どのくらいの人が覚えているだろうか。
VRML対応ブラウザplug-inで、Windows8.1にセキュリティ上の不安要素を排除した上で対応したものは存在するだろうか。
そういうことです。

SyntaxHighlighter Ver.3.0.83

一番有名なのは、「SyntaxHighlighter」で、2014年2月現在の最新バージョンは、2010年7月リリースのVer.3.0.83。

対応言語は"ActionScript3", "Bash/shell", "ColdFusion", "C#", "C++", "CSS", "Delphi", "Diff", "Erlang", "Groovy", "JavaScript", "Java", "JavaFX", "Perl", "PHP", "Plain", "PowerShell", "Python", "Ruby", "Scala", "SQL", "Visual", "XML".

このバージョンは、Flashの使用がなくなってJavaScriptとCSSのみで動作する点、更にコードがテーブル表示ではなくなり、その結果、行番号までコピー^されてしまうのを避けられるようになった。

オートーローダー機能で、一つの.jsファイルを指定するだけで、複数の.jsファイルに自動分岐呼び出しをする機能が実装されている。そのため、ここで読み込みのオーバーヘッドがかかる。

古いバージョンとVer.3.0.83とでは必要ファイル設置方法コツ・勘所が異なるので、バージョン番号を意識した上で十分な調査が必要。

高機能で、一番良いツールだと思うのだか、読み込みタイミングやオートーローダーなど、色々な要素が絡んでHTMLのパースが末端まで行かないとき、上手く動かない。二晩粘ったけど、どうしても上手く動かせないので、使用を断念。

highlight.js Ver.8.0

次に、Ivan Sagalaevさんの"Highlight.js"。2014年2月現在の最新バージョンは、2014年1月リリースのVer.8.0。

対応言語が充実している。用意されている対応言語設定の.jsファイルは以下の77個。公称で「71 languages」だそうな。

"1c", "actionscript", "apache", "applescript", "asciidoc", "autohotkey", "avrasm", "axapta", "bash", "brainfuck", "clojure", "cmake", "coffeescript", "cpp", "cs", "css", "d", "delphi", "diff", "django", "dos", "elixir", "erlang", "erlang-repl", "fix", "fsharp", "glsl", "go", "haml", "handlebars", "haskell", "http", "ini", "java", "javascript", "json", "lasso", "lisp", "livecodeserver", "lua", "makefile", "markdown", "mathematica", "matlab", "mel", "mizar", "nginx", "nix", "nsis", "objectivec", "ocaml", "oxygene", "parser3", "perl", "php", "profile", "protobuf", "python", "r", "rib", "rsl", "ruby", "ruleslanguage", "rust", "scala", "scilab", "scss", "smalltalk", "sql", "tex", "vala", "vbnet", "vbscript", "vhdl", "vim", "x86asm", "xml".

これは一応、動かせたが、"Highlight.js" Ver.8.0はWindow Onloadで駆動する設計(簡単設置のための親切設計)がコードに組み込まれているため、パースのタイミングがずれた場合、正常に読み込み完了させるのが難しい(解決方法はこちら)。
あと、レガシーブラウザの挙動制御も考えると面倒。

そして、非常に残念なことに、行番号が付かない。これが気に入らなくて、使用を断念。

GeSHi - Generic Syntax Highlighter

GeSHi - Generic Syntax Highlighterの2014年2月現在の最新版は2012年8月リリースのVer.1.0.8.11。

PHP5やASPとの親和性が高いのがウリのようです。

サポートする言語は細かい分類で112言語。

"ABAP", "Actionscript", "ADA", "Apache Log", "AppleScript", "APT sources.list", "ASM (m68k)", "ASM (pic16)", "ASM (x86)", "ASM (z80)", "ASP", "AutoIT", "Backus-Naur form", "Bash", "Basic4GL", "BlitzBasic", "Brainfuck", "C", "C for Macs", "C#", "C++", "C++ (with QT)", "CAD DCL", "CadLisp", "CFDG", "CIL / MSIL", "COBOL", "ColdFusion", "CSS", "D", "Delphi", "Diff File Format", "DIV", "DOS", "DOT language", "Eiffel", "Fortran", "FourJ's Genero", "FreeBasic", "GetText", "glSlang", "GML", "gnuplot", "Groovy", "Haskell", "HQ9+", "HTML", "INI (Config Files)", "Inno", "INTERCAL", "IO", "Java", "Java 5", "Javascript", "KiXtart", "KLone C & C++", "LaTeX", "Lisp", "LOLcode", "LotusScript", "LScript", "Lua", "Make", "mIRC", "MXML", "MySQL", "NSIS", "Objective C", "OCaml", "OpenOffice BASIC", "Oracle 8 & 11 SQL", "Pascal", "Perl", "PHP", "Pixel Bender", "PL/SQL", "POV-Ray", "PowerShell", "Progress (OpenEdge ABL)", "Prolog", "ProvideX", "Python", "Q(uick)BASIC", "robots.txt", "Ruby", "Ruby on Rails", "SAS", "Scala", "Scheme", "Scilab", "SDLBasic", "Smalltalk", "Smarty", "SQL", "T-SQL", "TCL", "thinBasic", "TypoScript", "Uno IDL", "VB.NET", "Verilog", "VHDL", "VIM Script", "Visual BASIC", "Visual Fox Pro", "Visual Prolog", "Whitespace", "Winbatch", "Windows Registry Files", "X++", "XML", "Xorg.conf".

試していないので、実際の設定や挙動は、よくわかりません。

google-code-prettify 2013年3月版

結局、これを使うことにした。

但し、結構、あちこちに手を入れる必要がある。
使い方は、ここと、ここと、ここを参照。
特に、デフォルトでは5行おきにしか行番号がでないので、毎行に行番号を付けたい場合は改造が必要な点に注意。
更にCSSの改造はここを参照し(←丸ごと拝借しました。ありがとうございます。)、行がはみ出る場合はここの「おまけ」を参照。
行番号を自動で出すための改造についてはここ

使ってみて、気に入らない点は、ulとliで行番号を付けている関係上、コードをコピペすると、冒頭に行番号が付いてしまう点ですね。
SyntaxHighlighter Ver.3.0.83では、ソースコード部分だけをコピーできます。これは仕方ないとあきらめることにします。

以下、ちょっと分かりづらい点について補足。

対応している言語は、大きく分けて二種類ある。

「prettify.js」にdefault includeされていて、自動認識するものは以下の通り。

"bsh", "c", "cc", "cpp", "cs", "csh", "cyc", "cv", "htm", "html", "java", "js", "m", "mxml", "perl", "pl", "pm", "py", "rb", "sh", "xhtml", "xml", "xsl".

これらはclass内にlang-htmlなどのように言語を一々記載しないでも、

<pre class="prettyprint">

と書くだけで自動的に認識するそうな。

もちろん、

<pre class="prettyprint lang-html">

のように明示的に宣言しても良く、更に

<pre class="prettyprint"><code class="lang-html">...</code></pre>

でも良いそうです。

行番号を出したい場合はclasslinenumsを追加して

<pre class="prettyprint linenums"><code class="lang-html">...</code></pre>

のように書きます。

「lang-css.js」のような、外部ファイルとして提供されており、<pre class="prettyprint lang-css">のように、class内にlang-*を記載指定して使用するタイプのものは以下の通り。外部.jsファイルは28個である。

"apollo", "basic", "clj", "css", "dart", "erlang", "go", "hs", "lisp", "llvm", "lua", "matlab", "ml", "mumps", "n", "pascalproto", "r", "rd", "scala", "sql", "tcl", "tex", "vb", "vhdl", "wiki", "xq", "yaml".

対応言語数を「幾つ」と数えるのは難しいが、"perl", "pl", "pm"はPerlという言語名でひとくくりにできるかもしれないが、"html"と"xml"は別言語か、同じ言語か。xhtmlだけxml扱いだと数えるのか。そもそも数えても、実用上の意味は何にもない。

ただ、MS-DOSがない。DOSは内部のBashで代用か、外部.jsのBASICで代用か。
また、phpがないのである。これについては、定義ファイルを配布している方がいらっしゃるのでそれを拝借してくるのが良いのかもしれない。

でも、対応言語のキーワード設定ファイルは.jsなのであるから、変なインジェクションを仕込まれていた場合、困ったことになるかもしれない。
定義ファイルを呼び出すための.jsを1個だけ提供しておいて、その.jsファイルから言語に応じた.cssファイルを呼び出す設計の方がスマートだったのではないか。

目次へ戻る

HTMLファイルにPHPを埋め込む

以下、HTMLファイルに外部phpファイルの出力結果を取り込む方法です。

要するに、innerHTMLとかJavaScriptみたいに入れ込みたいわけです。

あれこれ探すと、以下のような真っ当な回答ばかり…。でも、それじゃ嫌なんだ!

最も多い回答の例

でも、それじゃ嫌なのだ! サイト全体じゃなくて、スポットで使いたい!アドホックで使えればそれでいいの!

…ということで、色々調べてわかったこと。

  1. 仕掛けは「HTML→JavaScript(実はphp)」としておく。
  2. phpが吐き出す文字列をJavaScriptとして正しい構文で出力させる。
  3. HTML側では、それを「JavaScriptから返ってきた結果」として、何事もなかったかのように扱う。

こういう風にやればいいみたい。

以下、サンプルとサンプルのコード。

※CallPHP.htmlにCallPHP.phpを埋め込んだサンプルを動かしてみる

html側のコード
この例では文字コードをUTF-8に設定してある。バイナリでUPする。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Language" content="ja">
<meta name="robots" content="index,follow">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<title>PHPを挿入</title>
</head>
<body>
<p>この下に挨拶</p>
<script type="text/javascript" src="CallPHP.php"></script>
<p>この上で挨拶</p>
</body>
</html>

php側
この例では文字コードはUTF-8で保存し、バイナリでUPしてからパーミッションを604に設定した。動かなければ644か705か755でどうぞ。

<?php
header("Content-type: text/javascript");

$str = <<< EOD
<p>哥们儿!</p>
<p>吃飯了吗?</p>
EOD;

$str = preg_replace("/\r\n|\n\r|\r|\n/",'',$str);

echo <<< EOD
<!--
document.write("$str");
//-->
EOD;
?>

JavaScriptのdocument.write()内で改行するには、行末の改行を1個の¥でエスケープすれば良いんだけど、今回の場合は、改行を削除した方が早いので、そのような処理を入れています。

ちょっと横道に逸れますが、サンプルの出力用データは、簡体字中国語の例文にしてあります。
これは、phpファイルの方も文字コードをUTF-8で保存して、その確認のために、EUC-JPやShift_JISでは出せない文字を入れました。

なお、phpがUTF-8で動くかどうかは、サーバの仕様によります。
php.iniファイルの設定をいじるか、.htaccessに以下のような設定を入れればUTF-8対応で動くと思います。
※例はPHP5の場合の.htaccessの書き方。

# On/Offで指定するものはphp_flag、文字列で指定する場合はphp_valueを使う。
# デフォルト言語を日本語に設定
php_value mbstring.language = Japanese
# 内部エンコーディングを UTF-8 に設定
php_value mbstring.internal_encoding = UTF-8
# デフォルトのHTTP入力文字エンコーディングを設定(順番)
php_value mbstring.http_input = UTF-8,ASCII,EUC-JP
# デフォルトのHTTP出力文字エンコーディングを設定
php_value mbstring.http_output = UTF-8
# HTTP入力エンコーディング変換を有効にする
php_flag mbstring.encoding_translation = On
# デフォルトの文字エンコーディング検出順序を設定(順番)
php_value mbstring.detect_order = UTF-8,ASCII,EUC-JP
# 代替文字のデフォルト値を設定
php_value mbstring.substitute_character = none;

さて、phpのコードの方に話を戻しますが、先頭でPHP側で最初にヘッダー送信をさせているヘッダー送信部分は、Perlでは動くはずなんだけどPHPで以下のようにした場合、動かなかった。

echo "Content-type: text/html ¥n";

PHPでのヘッダー送信は、以下で行けとの指示が多い(External JavaScript and PHPなど)

header("Content-type: application/x-javascript");

試してみたら「application」でなくて「text」で、かつ「x-javascript」でなくて「javascript」とした以下の《普通の指定》でも、ちゃんと行けるみたい。

header("Content-type: text/javascript");

但し、確認は、Windows用のFirefox27.0.1と、IE10だけである。

SafariやOperaやChromeや、スマートフォンで、どうなるかはわからない。あと、古いブラウザでは動かないかもしれない。

一番の注意点の注意点」とダメ押しして説明されているのは、たぶん、その当時は、IE6対応とかも大切だったためだろう。

気になったので一応、phpのMIMEタイプについて調べたけど、よくわからなかった。

JavaScriptについては例によって神崎氏のサイトにまとめられていた。

面白いことに、IEの場合、HTMLのソースコードを見ると、埋め込まれているphpのファイル名(上の例ではcallPhp.php)と位置がわかる。

そこで、そのphpファイルをアドレスで直接指定すると、同名のjsファイルとして保存される(上の例ではcallPhp.js)。

JSファイルの中身は、phpのソースコード丸見えではなく、JavaScriptとして最終的に出力された以下の文字列であった。

<!--
document.write("<p>哥们儿!</p><p>吃飯了吗?</p>");
//-->

目次へ戻る

PHPで改行を置換する場合のエスケープ処理

Perlで改行を取り去りたい場合。

$str =~ s/¥r//g;
$str =~ s/¥n//g;

まぁ、普通はこんな風に書きますが、PHPでは関数を通さないとダメらしいです。

PHPで、シングル・クオーテーションを使って、以下のように書いた場合。

$str = preg_replace('/\r|\n/','',$str);

では全然動いてくれないのであった。

PHPで、シングル・クオーテーションを使う際は、以下のように書く。

$str = preg_replace('/\\\r|\\\n/','',$str);

見ての通り、シングル・クオーテーションの場合、エスケープ文字「¥」のエスケープを行い、更にその¥もエスケープしてメタキャラクタだと示さないと動いてくれないのであった。そういうわけで、¥は3個必要。

で、ダブル・クオーテーションだと挙動が異なる。

$str = preg_replace("/\r|\n/",'',$str);

これで動く。

あと、PHPの場合、修飾子gがなくても全部取り去る。というか、gは存在しないらしい…。必死で探したのに。

細かいところで、なんだかよく判らん仕様である。

目次へ戻る

PHPとPerlのヒアドキュメントの違い

Perlだと

$str = << EOD;
<p>こんにちは</p>
<p>こんばんは</p>
EOD
print $str;

という風に書くんだと思うけど、PHPでは動かなかった。

PHPでは

$str = <<< EOD
<p>こんにちは</p>
<p>こんばんは</p>
EOD;
echo $str;

と書く。

どこが違うのか? 2点違いがある。

1つ目。リダイレクト記号<が2個と3個で違う。Perl だと <<となる部分がPHPでは <<< と書く。

2つ目。EODの開始宣言直後に;を付けるか、終了宣言直後に付けるかも違う。

Perlだと EOD;~EOD なのが、PHPでは EOD~EOD; と書く。

なんでこんなつまらない所でエラー出るんだよぅ…。

なお、EOD は End Of Document の略で、EOM は End Of Message の略で、EOF は End Of File の略であるが、実は、これらは組み込み済みの物ではないから、指定する文字列は何でも良いらしい。

目次へ戻る

秀丸エディタの「変換モジュールライブラリ」の設置場所についてについて

秀丸エディタの設定が複雑すぎて、もうわけわからん。

どんどん高機能化しているのだが、なにしろ歴史と伝統のあるエディタなので、複雑怪奇である。

発端は、32ビット(x86)版とx64版の両方を入れたことである。

なんでそんな変なコトをしたのかというと、リムーバブルHDDに持ち出し用の秀丸を設定するためなのであった。

リムーバブルHDDに「持ち出し用の秀丸をバージョンアップする」には、一度、メインパソコンに32ビット(x86)版を入れなければならない。だって、出先で使うパソコンに、必ず64版のWindowsが入っているとは限らないからね。

※「秀丸持ち出しキット」そのものは、ここからダウンロード可能。

そうすると、標準のインストールでは、

  1. 32ビット(x86)版「秀丸」のプログラム本体は以下の場所にインストールされる。
    C:\Program Files (x86)\Hidemaru\
  2. 64ビット(x64)版「秀丸」のプログラム本体は以下の場所にインストールされる。
    C:\Program Files\Hidemaru\
  3. マクロ類は以下の場所にインストールされる。
    C:\Users\ユーザ名\AppData\Roaming\Hidemaruo\Hidemaru\Macro\
  4. 設定ファイル類は以下の場所にインストールされる。
    C:\Users\ユーザ名\AppData\Roaming\Hidemaruo\Hidemaru\Setting\

こんな風になるわけである。

さて、「マクロ」や「設定ファイル」の場所の指定は[その他]→[動作環境]→[環境]の「パス」で行う。

「マクロ」ファイルの位置指定は[マクロ]→[マクロ登録]から行う。ここで選択できるのは「マクロ」の拡張子である「*.mac」のみである。

そして、「変換モジュールライブラリ」の拡張子は「*.hmf」とか「*.hmf64」なのである。

そうなのである。[マクロ]→[マクロ登録]のメニューからは「変換モジュールライブラリ」を指定できないのだ!

では、どこから「変換モジュールライブラリ」を指定すれば良いのか?

ちなみに、導入した変換モジュールは以下の通り。

BASE64デコード V1.20ULTI v1.25 大文字小文字変換カスタムソート変換モジュール + 部首順ソート用データUniq

32ビット(x86)版だけをインストールする場合や、64ビット(x64)版だけをインストールする場合ならば、C:\Users\ユーザ名\AppData\Roaming\Hidemaruo\Hidemaru\…のような「ヘンテコな場所」にファイルを置く義理などない。

そんなもの、本来は、マクロも設定ファイルも、全部まとめて秀丸本体の*.exeファイルがある場所に放り込んでおけば良いのだ。

しかし、32ビット(x86)版と、64ビット(x64)版を共存させる場合は、共通で使いそうなモジュールを置く場所は、同じ所にしておいた方が管理が楽である。

ということで、追加する変換モジュール(*.hmf)は、C:\Users\ユーザ名\AppData\Roaming\Hidemaruo\Hidemaru\Macro\に置くのが最善であるということになる(もちろん、C:\HidemaruSet\などのディレクトリを掘ってそこにぶち込んでも構わないのだが)。

で、「変換モジュールライブラリ」の位置指定はどこでやるのか?

  1. [その他]→[動作環境]で、「上級者向け設定」のチェックをON。
  2. 「編集」→「変換」で、使いたい変換モジュールをそれぞれ「追加」で指定。
  3. 64ビット(x64)版の秀丸の方では、メニューの一番下に出る「64bit版」で「32bit変換モジュール(*.hmf)を動作可能にする」をONにする。
  4. 但し、64ビット(x64)版変換モジュールが提供されている場合は、明示的に「*.hmf64」を選択しておく。

以上である。

ここまでの説明、サイトー企画のWebPage内では、「素人にもすぐわかるような説明」は、見当たらないのである。

商売やる気あるのか?と思うでしょ? 違うんですね。人間というのは、自分にとって当たり前になりすぎてしまったことは、説明しないという習性があるのだ。

これが「文化的なギャップ」とか「異文化・多文化のギャップ」とか「ジェネレーション・ギャップ」の原因になるわけですね。

こんな感じ。

で、その「ギャップを埋める仕事」が、今後のビジネスでは有望。 

とくに、「知財分野」と、「ノウハウと、人脈も含めた体験的知識の集大成が丸ごと必要な分野」が儲かる。

なぜか? 「参入障壁が高い」から。

日本企業の海外進出アドバイザーとか、観光マネジメントとか、コンピュータ関連の情報化技術とか、人間の集団を相手とする人材マネジメントとか。

今回の場合は、h-tomさんのこのページ(目次はここ)が「コンピュータ関連の情報化技術」に相当する。

浅野内匠頭は大馬鹿者です。先に院使饗応役に任ぜられていて、「お作法」を分かっている吉良上野介に対して、相応の授業料を払って指南を仰がなかったくせに、「教えてくれない」と逆ギレして刃傷沙汰に及んだのです。死罪は当然。切腹にして貰えたなんて、なんと温情がある処置なのでしょう。それなのに、家来が討ち入りをするなんて、どうかしています。若い社員が仕事で失敗し、懲戒解雇となるべき所を社長の温情で自己都合退職にして貰ったのに、その元社員の父が、当該の上司を逆恨みして待ち伏せし、刺し殺したようなものです。(◕‿‿◕)わけがわからないよ。

歌道や茶道や華道などで、「お作法」を伝授して頂くためには、相応の授業料を払うのが当たり前でしょう?

歌道の世界では、更に参入障壁を高くするために、「切り紙伝授」というルールも作られました。

知財分野」と、「ノウハウと、人脈も含めた体験的知識の集大成が丸ごと必要な分野」が儲かる、というのは、そういうことです。

医師や弁護士なんかは、まさにそれでしょう。

国家資格なので最初の時点での参入障壁がメチャメチャ高い。
次に、多くの症例とか、多くの手術とか、多くの事件とかを扱って、それぞれの修羅場を「切った張ったの世界」で、くぐり抜けてきた医師や弁護士の方が、より高い報酬を手にするわけです。
当たり前のことですね。

目次へ戻る

Unicodeで漢文の返点を使いたいんだけどMS明朝が残念な件

U+3190~U+319Fに漢文の返点符号が入っているんだけどね。これが実際には使い物にならない。

このうち、U+3190とU+3191は、MS明朝にもMingLiuにも入っていない。

Arial Unicode MSとメイリオには入っているけど、ゴシック系のフォントで返り点を打つのは目立ちすぎてしまってどうしようもない。

U+3190 ㆐←MS明朝にもMingLiuにも入っていない。文字と文字を繋いで熟語扱いする竪線。
U+3191 ㆑←MS明朝にもMingLiuにも入っていない。自動でリガチャになってくれない。
U+3192 ㆒
U+3193 ㆓
U+3194 ㆔
U+3195 ㆕
U+3196 ㆖
U+3197 ㆗
U+3198 ㆘
U+3199 ㆙
U+319A ㆚
U+319B ㆛
U+319C ㆜
U+319D ㆝
U+319E ㆞
U+319F ㆟

現代の標準的な点の付け方(中学~大学の学部レベル)では、レ点がくっつくのは「一レ」、「上レ」、「甲レ」、「天レ」だけだと思う。
ただ、大学院レベルになると、江戸時代の生の文献を読む場合も出てくるだろう。
以前、「乙レ」点を振ってあるのを見て仰天したことがあるから、歴史的には例えば「二レ」点なんてのもアリなんだろう。

そうすると、「一レ」、「上レ」、「甲レ」、「天レ」このコードポイントが並んだときだけリガチャ扱いにするとか、あるいは、U+3192~U+319FにU+3191が後置した場合だけリガチャ扱いにするとかの処理をOS側に組み込んでくれると良いんだけど。

あるいは、返り点の「一レ」点を結合文字扱いできないか…と考えたんだけど両方とも、基底文字としての機能もあるからやはりリガチャ処理が良いように思う。

で、Unicodeの制御符号を探してみると、以下のようなものがあることがわかった。ゼロ幅文字ってBOMだけじゃないのね。

U+200B ZERO WIDTH SPACE(ゼロ幅スペース)
U+200C ZeroWidthNonJoiner(ゼロ幅非結合子)HTMLでの代替文字列は「&zwnj;」
U+200D ZeroWidthJoiner(ゼロ幅結合子)→HTMLでの代替文字列は「&zwj;」

この前後、U+2000~U+200Fの領域には、なんだかよくわからんスペースが定義されている。

色々探してみると、アンテナハウスの小林徳滋氏「Unicode とXSL によるアラビア語の組版」発表資料に、以下のような制御符号位置についての言及があった(順序などは入れ替え、説明の文句も一覧表から変更した)。

暗黙で弱い方向のマーク

範囲は局所的である。方向特性をもつ文字と同等に扱われるが、文字とは違い表示されない(幅がゼロの文字)。

LRM U+200E Left-to-Right Mark Left-to-Right ゼロ幅マーク
RLM U+200F Right-to-Left Mark Right-to-Left ゼロ幅マーク

明示的で強い方向性の文字の埋め込み

LRE U+202A Left-to-Right Embedding 続く文字を左から右へ埋め込まれたものとして扱う
RLE U+202B Right-to-Left Embedding 続く文字を右から左へ埋め込まれたものとして扱う

明示的で強い方向性の文字の終了

PDF U+202C Pop Directinal Format 双方向性の状態を、直前のLRE、RLE、RLO、LRO の状態に戻す

明示的で強い方向性の文字の上書き

LRO U+202D Left-to-Right Override 続く文字を強い左から右方向文字として扱う
RLO U+202E Right-to-Left Override 続く文字を強い右から左方向文字として扱う

あと、その前後を調べてみると、U+202FにはNARROW NO-BREAK SPACEというのが定義されているみたい。

英文版WikipediaでのZero-width_joinerの説明に従うと、結合したい文字に後置する書式のようだから、「一レ」点の場合は以下のようにするみたい。

U+3192(一)+U+3191(レ)+U+200D(ゼロ幅結合子)

あるいは、

U+3192(一)+U+202B(Right-to-Left Embedding)+U+3191(レ)+U+202C(Pop Directinal Format)

こんな感じなのかな…。

もちろん、OSやアプリケーションの組み版エンジン、レンダリングエンジンが対応しているかどうかとか、フォントのグリフにそういった細工がしてあるとかの諸々の要素で表示結果は異なるんだろうけど。

そういえば、U+200BはMSが配布しているExcelの一覧表の中で使われているのを見たことがありますね…。
エディタで編集できなくて焦った。そのときは、仕方なしにANSIテキストに強制保存して「?」に化けさせて処理したけど、Unicode文字が使われていたら、もう少し工夫が必要な所だった。

文字がほしいと駄々をこねたて増やして貰ったのは良いけど、「研究者は、それらの符号化情報を適切に使いこなせていないよね。」ということが露呈してしまったわけである。これって、実装のために血反吐を吐く努力をしてくれた人々には、大変失礼な話である。

でも、Unicode Line Breaking Properties (Unicode Standard Annex#14)という文書にあるUnicodeに定義された組み版関係の制御文字についての説明を読んでも、あまりに処理が煩雑で、よくわからん。

あと、Unicode 用語 英日対訳表Unicode 用語 日英対訳表を見つけた。技術用語の含意がわからなくなる場合があるのでこのような資料は貴重。

アラビア語みたいな複雑な結合文字処理系ではなく、部分的にリガチャにしてほしいだけなんだけどなぁ。

かといって、レ点に前進を伴う文字としての属性を与えるのはダメだよね。レだけでも基底文字として使われるからなぁ。

リガチャはotfフォントのGSUBといいうテーブルで定義するらしい。

http://www.microsoft.com/typography/otspec/GSUB.htm

そしてFontForgeで、その辺の設定をいじれるようだ。

http://kudakurage.hatenadiary.com/entry/20120720/1342749116

この作業過程を見ると、どうやら、「代替で割り当てられるグリフをどこに設置するか?」という難問があることがわかった。

いろんなユーザがいるんだから、できるだけ勝手にPUAを潰すのは避けたい。

キロとか株式会社とか平成ならば、割当先のコードポイントとグリフが既にあるし、欧文のfiとかffとかgyとかの場合はたぶん、予約領域みたいのがあるのだろう。

ただ、その他の任意指定のグリフはどうしているんだろうなぁ。

UCSそのグリフをIVSに放り込むという安直な逃げ道を考えたけど、一とレのどっちにぶら下げるのよ?というツッコミが入るだろう。

そんな使い方はどう考えてもIVSの趣旨にかなわないので却下だろうなぁ。

目次へ戻る

Excelで元号から西暦への相互換算表示をする―附録:民國紀元(民國曆)の計算と表示

「西暦から元号にしたい」ではなく、「元号から西暦にしたい」という需要が結構多いらしいので、やってみた。

Excelファイル(ExcelGENGOH.xlsx)。

中に入っている台湾版Excelの画像の出典はここ

なお、清以前の中国の元号について、Excelでやるのは無理です。

プログラムで超厳密に処理したい場合は、Whenを使う。(但し、使いこなすことそのものが難しい。)

分散処理のためか、suchowanさんのページは現在、複数のアドレスがあるので列挙。

http://www.asahi-net.or.jp/~dd6t-sg/

http://homepage1.nifty.com/suchowan/

http://hosi.org/a/

検索窓口に元号から選択する入り口がないようなので、サンプル。

http://hosi.org/cgi-bin/day.cgi?承和

http://hosi.org/cgi-bin/day.cgi?道光

王朝名・時代名だと以下のような感じ。

http://hosi.org/cgi-bin/eras/form.cgi?唐

http://hosi.org/cgi-bin/eras/form.cgi?宋

私の場合、よほど厳密に知りたい場合以外は、平楽寺書店の『東方年表』とか、辻善之助『大日本年表』を使います。

※なお、『大日本年表』の全文PDFは、こちらdnhnenpyou.pdfをダウンロードできます。

目次へ戻る

PHP:Oliver[1993]の計算による文字列の類似性計算

動かしてみる。→similar.php

単に、PHPでのフォームの受け渡し方法の確認をしたかっただけ。

ソースは以下の通り。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Language" content="ja">
<meta name="robots" content="index,follow">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<title>PHP:Oliver[1993]の計算による文字列の類似性計算</title>
</head>
<body>
<p>PHP:Oliver[1993]の計算による文字列の類似性計算</p>
<form action="similar.php" method="post">
<p>
<textarea name="text_A" rows="20" cols="60"></textarea>
<textarea name="text_B" rows="20" cols="60"></textarea>
</p>
<input type="submit">
<p>
文書の類似度:
<?php
$TEXT_A = $_POST['text_A']; // データの代入はpostされたnameを入れる
$TEXT_B = $_POST['text_B'];
$S = similar_text($TEXT_A, $TEXT_B, &$P);
$U8 = $S / 3;
echo ("バイト単位比較での一致数:{$S}、類似度:{$P}%");
echo ("<br>※ソースコードがUTF-8なので(非サロゲートな)全角1文字は3バイト。上記の一致数を3で割った数:{$U8}");
?>
</p>
<p><?php echo ("<b>1つめの文書:</b>{$TEXT_A}"); ?></p>
<p><?php echo ("<b>2つめの文書:</b>{$TEXT_B}"); ?></p>
<input type="submit" value="消去">
</form>
</body>
</html>

目次へ戻る

ExcelでUnicode順に並べ替えたい

Excel2007や2010では平仮名と片仮名は同一視してSortされます。

「ア」と「あ」をSortしても、








のようになる。

「あ」だけのカタマリと「ア」だけのカタマリに区分できません。これでは困りますね。

Excel関数にはCODEという関数がありますので、それで文字コードを作業用の列に導き出し、その作業用の列を使って並べ替えを行えば、期待通りの並び順にできます。

でも、CODE関数で番号が導出できるのはUnicodeの文字全部ではななく、Shift_JIS収録範囲の文字に限られるようです。
仕方ないので、ユーザ定義関数を作ることにしましょう。

以下、そのやり方。

Excel VBAに以下の三行を定義してVBA エディタを閉じる。

Function Chr2UniHexNum(先頭文字)
Chr2UniHexNum = Hex(AscW(先頭文字))
End Function

その後、fxボタン(関数貼り付けボタン)の▼で、「論理関数」の2つほど下にある「ユーザー定義」を選択する。

そうすると、VBAで定義した「Chr2UniHexNum」という名前の関数が出るはずなので、それを普通の関数のように使う。

これで、「選択したセル内の《先頭の》文字」の文字コードをUnicodeの16進数で表示できます。

※セル内の2文字目とかを調べたい場合はLEFT関数やMID関数やRIGHT関数と併用して下さい。

但し、Unicodeのプレーン領域のみに対応です。
Ext.B領域の文字で試してみたら、サロゲートペアの前の部分だけしか取得できず、正しい数値にはなりませんでした。
少し残念。

目次へ戻る

ファイル名を親フォルダと同名に変更して、一階層上のフォルダに移動する

某大学のレポート提出システムがイマイチ使いづらい。

提出されたファイルをまとめてzipファイルで回収可能なのだが、treeを取ると、以下のようなディレクトリ構造なのである。

このディレクトリ名は学籍番号(個人情報なので、ここではダミーデータを載せている)。

フォルダー パスの一覧: ボリューム WD7500BPVT-XP
ボリューム シリアル番号は 00000200 1234:56EF です
        D:.
        ├─12183519
        ├─12226738
        ├─12245086
        ├─12245783
        ├─12266259
        ├─12270048
        ├─12287539
        ├─12294513
        ├─12303043
        ├─12382746
        ├─12421174
        ├─12427722
        ├─12432987
        ├─12433961
        ├─12457529
        ├─12476718
        ├─12516991
        ├─12524902
        ├─12536694
        ├─12538647
        ├─12568124
        ├─12613644
        ├─12678581
        ├─12730675
        ├─12734788
        ├─12763157
        ├─12814290
        ├─12892900
        ├─12917826
        ├─12953862
        ├─12958087
        ├─12967608
        ├─12973844
        ├─12993390
        └─12993522

しかも、これら各フォルダの中には、「1.xls」だけとか「1.xlsx」だけとか、「異なるフォルダ名の中に入っているファイルと同名の、1から始まる数字のファイル」が入っている。

なんだよこれ…。

ほんとにびっくりするほど論外!

学籍番号-数字.拡張子」とか、ファイル名だけで識別可能なように設計すべきだろうが…。

きっと、これと同じように社員番号がフォルダ名になっているようなシステムもあるに違いない。

ちうことで、困っている自分と皆さんのためにバッチファイルを作った。これ→sdir_ren_move.zip

内容は以下の通り。

: ==========================================================
: sdir_ren_move.cmd 2012/01/23 http://www.tanimoto.to
: ==========================================================
: カレント直下のサブディレクトリ中にあるExcelファイルについて…
: 手続き1 サブディレクトリ名をファイル名としてリネーム
: 手続き2 それらのファイルを、カレント直下に移動
: 手続き3 サブディレクトリを全部削除
: ----------------------------------------------------------
: 注:
: 上書き防止対策は行っていないので、気をつけて使用のこと。
: 孫、曽孫ディレクトリも含むようにしたつもりだけど、よく確認していない。
: ==========================================================
: 以下、手続き1(Wordファイルなどの場合は拡張子部分を適宜に書き換えのこと)
: Excel97-2003
for /D %%f in ( * ) do ren %%f\*.xls %%f.xls
: Excel2007-
for /D %%f in ( * ) do ren %%f\*.xlsx %%f.xlsx
: Excel2007- Macros
for /D %%f in ( * ) do ren %%f\*.xlsm %%f.xlsm
: ----------------------------------------------------------
: 手続き2
for /D %%D in (.\*) do move "%%D\*" .\
: ----------------------------------------------------------
: 手続き3
for /D %%D in (.\*) do rd /S /Q "%%D\"
:END
: ==========================================================

目次へ戻る

Unicodeの文字一覧を出力するWordマクロ Ver. 1.2 2015/01/29

改訂履歴 Ver. 1.0 2011/11/05 → Ver. 1.2 2015/01/29

chr関数の扱える文字の範囲について、テキトーな把握をしていたらば、大失態をしでかしてしまった。

その検証の過程で、chrとchrWの比較もする必要があったので作ったものから、chr関数については省き、chrW関数に関する部分だけを若干、ユーザフレンドリな感じに書き換えたもの。

マクロ付きWordファイルそのものをzipにしたのがchrWListVBA.zipです。
以下は、Ver1.0時点でのBASファイル。最新版では少しコードを変更しています。詳細は上記zipファイル内の実装をご覧ください。


Attribute VB_Name = "Module1"
Sub CharWUnicodeList()
Attribute CharWUnicodeList.VB_Description = "Unicodeの文字一覧を出力するWordマクロ Ver. 1.0"
Attribute CharWUnicodeList.VB_ProcData.VB_Invoke_Func = "Project.Module1.CharWUnicodeList"
' ==================================================
' Unicodeの文字一覧を出力するWordマクロ Ver. 1.0 2011/11/05
' by tanimoto http://www.tanimoto.to
' ==================================================
' 本文には、そのグリフが含まれているフォントを指定しておくのが無難。
'さしあたり、収録数が多い「Arial Unicode MS」に設定しておけば、大体の文字は表示できる。
Dim Num As Variant
Dim StartNum As Variant
Dim EndNum As Variant

StartNum = InputBox(Prompt:="開始位置は?:Unicode16進数で入力。例は点字範囲の先頭(空白)記号", _
 Title:="開始位置の指定", Default:="2800")
StartNum = Val("&H" & StartNum) ' 以下も同じだが、CLng("&H" & StartNum)でも動く。

EndNum = InputBox(Prompt:="終了位置は?:Unicode16進数で入力。例は点字範囲の末尾", _
 Title:="終了位置の指定", Default:="28FF")
EndNum = Val("&H" & EndNum)

If StartNum >= EndNum Then
MsgBox Prompt:="開始位置よりも終了位置が小さい数値で指定されています。"
Exit Sub
Else
For Num = StartNum To EndNum
Selection.TypeText Text:="10進数:" & Num & "|16進数:" & Hex(Num) & "→【" & ChrW(Num) & "】" & vbCrLf
Next Num
End If

End Sub

目次へ戻る

幸之助君の今日の一言

JavaScriptでのDOMの初歩を勉強していた頃の試作品。kounosuke.html

基本の基本であるgetElementByIdの練習。

タイムスタンプは2008/03/04 15:51:40となっていた。

今更だけどUPしてみる。

技術はどんどん新しくなる。3年前はインラインフレームは、まだ許容される雰囲気だったらしい。
でも、その1年後には「全く非推奨だよね~」という雰囲気になったんだっけ…。

何でかなぁ。

XHTML 1.0 StrictだけでなくXHTML 1.1で非推奨になったのがジワジワ効いてきたのが、その頃だったのかな…。
HTML4.01ではiframeの中のalignは非推奨だけど、iframeそのものは非推奨じゃないんはずだよね…。

目次へ戻る

■Word VBAマクロにおける画面遷移とWordオブジェクトモデルについてのメモ

副題:原稿が遅いのはサボっているからじゃないんですよぉ。ホントに資料がないんですよ! > 編集さん。

初版記述:2011/02/13

http://msdn.microsoft.com/ja-jp/library/aa192495(v=office.11).aspx

.NET 開発者の観点から捉えた Word オブジェクト モデル
Mary Chipman
MCW Technologies, LLC

April 2003
日本語版最終更新日 2003 年 8 月 7 日

適用対象 :
MicrosoftR "Visual Studio Tools for Office"
Microsoft Office Word 2003
Microsoft Visual StudioR .NET 2003

以下、MSによる説明。

Document オブジェクト

Word でのプログラミング作業では、Document オブジェクトやそのコンテンツを必要とすることが多々あります。Word で特定のドキュメント (アクティブ ドキュメント) を操作する場合、Application オブジェクトの ActiveDocument プロパティを使用して参照できます。Word のすべての Document オブジェクトは Application オブジェクトの Documents コレクションのメンバでもあります。このコレクションには現在開いているすべてのドキュメントが属します。Document オブジェクトを使用して操作できるドキュメントは 1 つですが、Documents コレクションを使用した場合は開いているすべてのドキュメントを操作できます。ドキュメント操作は Application レベルと Document レベルのどちらでも実行できるため、Application クラスと Document クラスは多くのメンバを共有しています。

ドキュメントに関して実行できる一般的なタスクの例を挙げると、次のようになります。

Document オブジェクトのコレクション

ドキュメントは文字を並べた単語から構成され、各単語は文を構成します。文は段落を構成し、さらに段落はセクションを構成します。各セクションには、それぞれヘッダーとフッターがあります。Document オブジェクトには、これらの構造に対応するコレクションがあります。

Word のすべての Document オブジェクトは Application オブジェクトの Documents コレクションのメンバでもあります。」サラッと書いたな…。

Excel VBAでもそうなのだが、この「メリケンな仕様」が、数々の混乱の元凶なのである。

エエ加減というか、プラグマティズムに徹したと言うか…。でも、困るのである。

MSも、Office2007の頃からは、オブジェクトモデルをオブジェクトツリーで示すのを意図的にやめている雰囲気があります。
でも、ツリー構造で示した当初の方針が、いまだに、「ある程度」わかっている人たち(つまり、他の人たちに説明する《かもしれない》人たち)の脳内で、尾を引いているような気がします。

●Application オブジェクト

>Application オブジェクトの下位にあるオブジェクトやコレクションを参照する場合は、
>Application オブジェクトを明示的に参照する必要はありません。
>たとえば、組み込みの ThisDocument プロパティを使用すれば、Application
>オブジェクトを使用せずにアクティブ ドキュメントを参照できます。ThisDocument は
>アクティブ ドキュメントを参照するプロパティであるため、これを使用して Document
> オブジェクトのメンバを処理することができます。Document オブジェクトの詳細に
>ついては後述します。


原文
http://msdn.microsoft.com/en-us/library/aa192495(v=office.11).aspx

>When you're referring to objects and collections beneath the Application object,
> you don't need to explicitly refer to the Application object.
> For example, you can refer to the active document without the Application
> object by using the built-in ThisDocument property.
> ThisDocument refers to the active document, and allows you to work with
> members of the Document object.
> The Document object will be covered more fully in later sections of this document.

「組み込み」は「built-in」を訳したものですな…。
MSの機械翻訳による「超訳」ではないことを確認しないとひどい目に遭う。
MSは、VBAのマニュアルの説明も嘘だらけだし。Excelの関数の説明も嘘だらけだし…。
実に困る。


>ヒント アクティブな Document オブジェクトを参照する ThisApplication.
>ActiveDocument プロパティは、最も使用頻度の高いプロパティと考えられますが、
>通常は ThisApplication.ActiveDocument 構文の代わりに ThisDocument を使用
>することをお勧めします。

○Application のプロパティ

>ActiveDocument : アクティブ ドキュメント (フォーカスがあるドキュメント) を表す Document オブジェクトを返します。

>ActiveWindow : フォーカスがあるウィンドウを返します。

●Document オブジェクト

Word で特定のドキュメント (アクティブ ドキュメント) を操作する場合、
>Application オブジェクトの ActiveDocument プロパティを使用して参照できます。
>Word のすべての Document オブジェクトは Application オブジェクトの Documents
> コレクションのメンバでもあります。このコレクションには現在開いているすべての
>ドキュメントが属します。Document オブジェクトを使用して操作できるドキュメント
>は 1 つですが、Documents コレクションを使用した場合は開いているすべてのドキュ
>メントを操作できます。ドキュメント操作は Application レベルと Document レベル
>のどちらでも実行できるため、Application クラスと Document クラスは多くのメン
>バを共有しています。

結局、以下のまとめで良いんでしょうか?

A:Documents(i)で、特定のDocument オブジェクトを取得する方法

よく知られている通りの方法。

B:ThisApplication.ActiveDocument プロパティを使う方法

Application オブジェクトそのものの ActiveDocument プロパティでアクセスする方法である。
当然、Application オブジェクトそのものは省略して書けるので、普通はいきなり

ActiveDocument

と書いて取得する。

Excel VBAの場合、ApplicationオブジェクトのプロパティはThisWorkbookであるが、Wordでは“This”ではない! ActiveDocument である。 うきゃ~!

細かくここの挙動を考えると、Application オブジェクトの中に Documents コレクション があり、そのメンバとしてDocument オブジェクトを生成をすると、(当該のDocument オブジェクトのプロパティではなく、)一段上のオブジェクトであるApplication オブジェクトの方に属するプロパティとしてActiveDocument プロパティが生成され、ActiveDocumentの名前で参照できるようになる。
これ、「え~?!ナニソレ。」感が満載なんだけど、読み取りのみが可能な属性で、しかも状況遷移するものだから、子供のオブジェクトとするのは無理があって、プロパティとしたんだと思う。

C:ThisApplication.ThisDocument

ThisDocument プロパティの場合も、Application オブジェクトを明示的に使用せず、省略して暗黙に(いきなり、独立的に)書けるので、普通はいきなり、

ThisDocument

と書いて取得する。

これはMSによる説明によるとアクティブ ドキュメントを参照する「組み込み」のプロパティであるそうな…。
でも、どこに「ぶら下げる」形で「組み込み」されているのかは、この説明ではよくわからんので、さしあたり、この「組み込み」を「独立」と解釈したけど、これで良いの?

土屋和人氏Blog(http://blog.clayhouse.jp/article/43361783.html)の説明によると、

>Wordの文書を表すDocumentオブジェクトのクラス名の初期値が「ThisDocument」
>であり、それを名前で直接指定して


呼び出したモノがThisDocumentなのだよ、君ィ~。ということだそうな。

MSの「組み込み(built-in)」って言い方、よくわかんないよねぇ?
これを「Documentオブジェクトのクラス名の初期値」と理解すれば良いみたいですな…。

■まとめ(仮)

周知の通り、オブジェクトの上下関係を丁寧に書くとApplication.Documents.Documentとなるわけだ。(まぁ、実際のコードで、こんな書き方したらエラーになるはずだけど…)
んで、BやCの取得方法は、両方とも省略しないで書いた場合は「Applicationオブジェクトの直下」に付けられて3段目のDocumentの中の特定のオブジェクトを指定している、と…。
んで、Aの方法の場合も、省略しないで書いた場合はApplication.Documens(i)と2段目まで表記することによって3段目のDocumentの中の特定のオブジェクトを指定している、と…。
そうすると、オブジェクトツリーの何段目かは、一致していることになる…。
それで、MS的には、CのThisDocumentを使用推奨するよ、と言うことらしい。

むぅ…。
まぁ、そこまでは良いことにしよう。
そうすると、ActiveWindowは、ThisDocumentと、絶対こんがらがって来るよね?

あと、WindowオブジェクトのPreviousとNextプロパティとActiveWondowとの使いこなしである。

こんなメソッドがあるみたいなのね…。

MoveUp ([Unit], [Count], [Extend])
MoveDown ([Unit], [Count], [Extend])

WdUnits の列挙値は以下の通り。

wdLine : 行単位で移動します。この値は既定値です。
wdParagraph : 段落単位で移動します。
wdWindow : ウィンドウ単位で移動します。
wdScreen : 画面単位で移動します。

てぇことは、MoveDown(wdWindow,2)とすると、Previous相当とか、Documents(i)相当とかの挙動を実現できるのだろう。

ああ…もうワケわかんないよ。

目次へ戻る

JISの改廃

官報を見ていて気づいたのだが…

平成23年1月20日付(号外 第12号)
--------------------------------------------------------------
〔官庁報告〕
産 業
日本工業規格(経済産業省) ……… 7
--------------------------------------------------------------
日本工業規格
日本工業標準調査会の調査審議を経て、平成23年1月20日に下記の日本工業規格を制定及び改正したので、工業標準化法(昭和24年法律第185号)第16条の規定に基づき公示する。
平成23年1月20日

経済産業大臣海江田万里



1.制定された日本工業規格

(★以下摘記)


日本工業標準調査会の調査審議を経て、平成23年1月20日に下記の日本工業規格を廃止したので、工業標準化法(昭和24年法律第185号)第16条の規定に基づき公示する。
平成23年1月20日

経済産業大臣海江田万里



廃止された日本工業規格

(★以下摘記)

Cは無視してXとZを中心にめぼしいものを摘記したらこんな風だった。
SGML/XMLの交換は各自で勝手にやってるから実効性が無いので廃止する、ということなんでしょうねぇ。

目次へ戻る

Excelのデータを、分配法則的に整形したい場合はどうすれば良いか?

○具体例

漢字字典のデータを入力してあったとします。

A列に親字。B列以降には訓が入っているとします。

しかしながら、訓は一つだけの場合もあるでしょうし、五つある場合もあるでしょう。

ひょっとして八つ訓があるかもしれません。

B列まで訓があるか、F列まで訓があるか、I列まで訓があるか。それはいろんな場合がある。

行によって列数がまちまちのExcelデータ。ありがちです。

で、それらを

というように出力したい。

つまり…

行によって列数がまちまちのExcelデータ。

こんなのを、以下のようにしたい場合。

たすき掛け出力の結果。

こういう時はどうすれば良いか?

答え。gawkを使う。

以下、作業手順。

○作業1

[スタート]→[プログラム]→[アクセサリ]→[メモ帳]を起動し、以下の3行分をファイル名「bunpai.awk」というファイル名でテキストファイルとして保存する。なお、3行目最後の「}」の後には必ず改行を入れること。

このとき、「文字コード」の所は、「ANSI」で構わない。

BEGIN{ OFS="\t" }
{ for (i = 2; i <= NF ; i++ )
print $1,$i }

○作業2

[スタート]→[プログラム]→[アクセサリ]→[メモ帳]を起動し、EXCELからメモ帳にデータを貼り付けて保存する。

ファイル名は「data.txt」とする。

但し、普通の日本語文だけの場合は「文字コード」の所を「ANSI」にして保存する。これでShiftJISで保存される。

また、漢文やら中国語やらハングルやらが入っているデータの場合は「文字コード」の所を「UTF-8」にして保存する。

メモ帳に貼り付けたとき、文字が□に見えるなどして、こんな風(←シタ、タケノカハの部分)に、正常に表示されない場合があるが、気にしないで保存して良い。

○作業3

以下の2行分をファイル名「kidou.cmd」というファイル名でテキストファイルとして保存する。

このとき、「文字コード」の所は、「ANSI」で構わない。

但し、保存する前に、作業2で保存した元データがShiftJISであった場合は1行目の冒頭にある「REM」を削除する。

作業2で保存した元データがUTF-8であった場合は2行目の冒頭にある「REM」を削除する。

REM gawk.exe -W ctype=SJIS -f bunpai.awk data.txt > output.txt
REM gawk.exe -W ctype=UTF8 -f bunpai.awk data.txt > output.txt


○作業4

Unicode対応のgawkを解凍する。

 

○作業5

作業用フォルダを作成する。(場所はどこでも良い。)

その作業用フォルダに、以下の4つのファイルを入れる。

bunpai.awk
data.txt
kidou.cmd
gawk.exe

○作業6

kidou.cmdをダブルクリックする。

一瞬、真っ黒画面が出て、すぐに終了し、output.txtとして、作業結果が出力されるはずである。

出力されたoutput.txtをメモ帳で開き、全部をコピーしてEXCELに貼り付ける。

これで完成。

実験用サンプルファイル→awk_bunpai_sample.zip

なお、Windows Vistaと、Windows 7の場合は、管理者権限のパスワードを求められる場合があるかもしれない。

目次へ戻る

HTML中でのPHPフォームデータ受け渡しサンプル

案外、全部を挙げてくれているところが無いので載せてみる。

まず、使用例(画像/試してみる)。

こんにちは、なのはさん。あなたの年齢は9歳。あなたは世界で一番、劫火が似合う小学生なの。

上の例は、テキストボックス、テキストエリアの両方を使ってみた。

submitボタンは必須。

あと、リフレッシュも付けてみたが、JavaScriptと比べると、ここはちと難しい印象かも(POSTの場合だけ?)。

以下、POSTの例のソース。GETも同様。

htmlファイル名を、form actionの中で指定している"post_test.php"と同名で保存するのがミソ。

これによって、コマンド送信元のファイル自身が結果を受信する。

この、ファイル名については非常に重要なはずだが、明示的に説明してくれている情報源はあんまり無いかも…。

あと、以下のコード例ではサーバのphp標準コードがEUC-JPなので、charset=EUC-JPを指定している。

ここいらは、各自の契約しているサーバの設定に合わせて書き換えるべし。

あ、その場合は、当然、保存時の文字コードもcharsetと一致させないとダメよ。

昔のPerlだとARGVとかSTDINとかなんたら書いてタグをEOFでゴリゴリ書いたところだが、それと比べると、なるほど、こりゃ、楽ちんだ。

※その後のPerではcgi.libやcgi.pmを呼び込むという方法ができたようだけど、よく使った記憶があるのはせいぜい5.4の頃まで。しかもローカルで。

なお、ヘッダでプラグマをいじって、ローカルへのキャッシュそのものを禁止する方法ってのは、以下のような記述。
htmlのヘッダ内に追加すれば良い。最近のブラウザでの挙動は確認していないけど。

<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta HTTP-EQUIV="Expires" CONTENT="-1">

受け取りもテキストエリア内で行う場合(UTF-8版)/試してみる

如月ハニーは16歳なんだって。知らなかったよ。

目次へ戻る

Excel2003までの環境でも、所属学科を学籍番号から逆算表示する関数式

B2セルに入れてある多数桁の学籍番号の左から3文字目と4文字目が所属学科とコースを示しているデータに対して、IF関数をひたすらネストさせる場合の解(見やすくするために改行を入れてある)

=IF(VALUE(MID(B2,3,2))=10,"哲学",
IF(VALUE(MID(B2,3,2))=20,"印哲",
IF(VALUE(MID(B2,3,2))=30,"中哲",
IF(VALUE(MID(B2,3,2))=40,"日文",
IF(VALUE(MID(B2,3,2))=50,"英米",
IF(VALUE(MID(B2,3,2))=60,"史学",
IF(VALUE(MID(B2,3,2)=70,"教育[教育]",
IF(VALUE(MID(B2,3,2))=71,"教育[人間発達]",
IF(VALUE(MID(B2,3,2))=72,"教育[初等教育]",
IF(VALUE(MID(B2,3,2))=80,"英コミ",
"学科不明")
)))))))))

これで合っているはずなんだけど、実はExcelの2003まででの関数式では7段階までしかネストできないので、環境によっては正常に動かない。(Excel2007からは対応段数が多くなったのでこのままでOKなはず。)

教育学科のコース別表示は別枠で表示することにして、MID関数で取り出すのを1桁分にした場合でも、8段階になるのでダメ。

(歴史的経緯で)別学科になっている英米文と英コミを合併し、内部でコース分けしてくれると7段以内に収まるけど、「Excel関数の都合があるから学科を合併してくれ」ってのは本末転倒だもんなぁ…。

定石としてはユーザー定義関数で置き換える事になっているらしいけど、それも面倒…。

さて、どうしたもんか。

…結局、&で個々の判定を繋げるという泥臭い方法が最適解であるという結論に至る。

VALUEも使わずに、2桁数値を文字列のまま処理する方向性を取ると、更に式はスッキリする。

この場合の解は以下の通り(見やすくするために改行を入れてある)。

イリーガルデータを明示的に表示する処理が無いのがアレだけど。

=IF(MID(B2,3,2)="10","哲学","")
&IF(MID(B2,3,2)="20","印哲","")
&IF(MID(B2,3,2)="30","中哲","")
&IF(MID(B2,3,2)="40","日文","")
&IF(MID(B2,3,2)="50","英米","")
&IF(MID(B2,3,2)="60","史学","")
&IF(MID(B2,3,2)="70","教育[教育]","")
&IF(MID(B2,3,2)="71","教育[人間発達]","")
&IF(MID(B2,3,2)="72","教育[初等教育]","")
&IF(MID(B2,3,2)="80","英コミ","")

「手段そのものが目的化してしまう」というのは、往々にしてアリガチな誤りである。

だから、「MIDで切り出した文字列をテキストとして貼り付けし直し、一括置換する。」というのも、実はアリ。

欲しいのは、あくまでも「結果」であり、その「過程」は結果を得るための手段に過ぎない。

目次へ戻る

JavascriptのコードをちゃんとインデントさせるためのJavascript

JavascriptのCodeをちゃんとindentさせるためのJavascriptを捜してみた。

すぐに見つかったが、InnerHTMLで出力されるのがイマイチ気に入らない。

ということで、呼び出す側のHTMLだけ、TextBoxに出力するように改造した。これ

tabでなく、Spaceでインデントしたい人は35行目の

code = code.replace(/(\u0020){4}/g, "\t");

をコメントアウトして使って下さい。

Cezary TomczakさんによるOriginalのJsDecoder_1.0.2(GPL準拠で配布)はMozziraの場合はColourが付くようになっていたが、それも廃止。よって、HTMLのHEAD中でJsColorizer.jsを宣言しているが、使っていないのでこの行は削除してもよろし。

目次へ戻る

いろんな言語で「0から100まで出力」

codeなにがしネタ。いろんな言語 で「0から100まで出力」

色んなプログラミング言語の違いの標本として面白い。

誰もが、どんな言語でも書けるワケではないので、ふ~ん。そういう書式なのかぁ…と。

まさかバッチはあるまいと思って書いてみたんだけど、for in do の一行でエレガントに済ませるのが既に投稿されていた。悲しかったので自分の所に貼る。

@ECHO OFF
:LOOP
IF (%SUM%)==(100) GOTO :EOF
SET /A SUM=%SUM%+1
ECHO %SUM%
GOTO LOOP

目次へ戻る

ファイル連番複写機 HTA版 Ver1.0 2008/01/03

新年度用のネタ仕込み。VbScriptで作りました。

ファイル名に4桁固定長の連番数字を付加してひたすらコピーするツール。

ソフト外見

元ファイルが test.html だった場合、test-0001.html , test-0002.html , test-0003.html…という風にコピーされます。

出力結果

ディレクトリ名にスペースが入った場合の処理でちょっと手こずりました。

今のところ、出力先は SequentialNumberCopier.hta が置いてある所に固定で、他のフォルダを指定することはできません。

使い方:

  1. SequentialNumberCopier.exe をダウンロードしてダブルクリックで解凍します。

  2. SequentialNumberCopier.hta が出てくるので、それを、好みの場所に置いてダブルクリックして起動します。

  3. ファイル数を指定し、[参照]ボタンで、複写元ファイルを指定します。

  4. [ファイルコピー実行]ボタンを押します。

なお、こいつが動かない場合は、Windows 2000 および Windows XP 用の Windows Script 5.6(日本語版)か、WSH5.7 Windows XP用とかWindows 2000用とかを入れてみて下さい。
(WSH5.7は、今のところ英語版のみが提供されています。)

このHTAを作る前に使っていたBATファイル。手抜きをして拡張子を決め打ちする仕様になっている。

@echo off
rem 連番コピー
setlocal ENABLEDELAYEDEXPANSION
set /p IN=元ファイル名の拡張子以外の部分を指定してください:
set /p OUT=枝番を半角数字で指定してください(最大9999):
if "%IN%"=="" goto end
if "%OUT%"=="" goto end
rem if "%PAD%"=="" goto end

for /l %%i in (1,1,%OUT%) do (
set x="0000%%i"
copy %IN%.bmp %IN%-!x:~-5,-1!.bmp > nul
)
:end
endlocal

目次へ戻る

Wordの検索や置換での「ワイルドカード」とはナニモノなのか?という話。

以下は、マイクロソフト ワードの搭載する「正規表現っぽいメタ文字」の実験です。

素材は以下の通り。
某悪所、既婚男性板の「メシまずスレ」歴代タイトル(2007/11/23現在)です。

【隠しきれない】嫁のメシがまずい 5皿目【隠しあじ】
【匙加減を】嫁のメシがまずい 6皿目【知らぬ愛】
【外食で】嫁のメシがまずい 7皿目【命をつなげ!】
【愛ゆえの】嫁のメシがまずい 8皿目【暴走】
【好きだから】嫁のメシがまずい 9皿目【言えない】
【誘導】嫁のメシがまずい 10皿目【禁止】
【誘導】嫁のメシがまずい 11皿目【禁止】
【鍋もおでんも】嫁のメシがまずい 12皿目【アレンジ禁止】
【妻の手は】嫁のメシがまずい 13皿目【パルプン手】
【妻の手は】嫁のメシがまずい 14皿目【メガン手】
【目Newは】嫁のメシがまずい 15皿目【救世主?】
【ダイナマイト】嫁のメシがまずい 16皿目【カキフライ】
【夕食に】嫁のメシがまずい 17皿目【招くぞ】
【妻の愛情】嫁のメシがまずい 18皿目【夫の驚愕】
【これは】嫁のメシがまずい 19皿目【何?】
【天使の微笑】嫁のメシがまずい 20皿目【悪魔の味覚】
【緊張の夏】嫁のメシがまずい 21皿目【メシマズの夏】
【食欲の秋】嫁のメシがまずい 22皿目【激ヤセの俺】
【味覚の秋】嫁のメシがまずい 23皿目【死角の味】
【夫で】嫁のメシがまずい 24皿目【実験】
【ゆでん?】嫁のメシがまずい 25皿目【ゆどん?】
【言うも地獄】嫁のメシがまずい 26皿目【言わぬも地獄】
【しゃくって】嫁のメシがまずい 27皿目【ゆった(泣)】
【これ美味しい!】嫁のメシがまずい 28皿目【今度作るね!】
【勇気を出した】嫁のメシがまずい 29皿目【前歯が折れた】
【あれ鈴虫が】嫁のメシがまずい 30皿目【煮えている】
【栄養一番!】嫁のメシがまずい 31皿目【命は二番】
【ガンガる娘は】嫁のメシがまずい 32皿目【迎撃機!】
【弁当に】嫁のメシがまずい 33皿目【牛乳シシャモ】
【真っ黒】嫁のメシがまずい 34皿目【ゴーヤチャンプルー】
【生はだめぇ!!】嫁のメシがまずい 35皿目【牡蠣サラダ】
【旦那のヘタレが】嫁のメシがまずい 36皿目【メシマズ加速】
【大さじは】嫁のメシがまずい 37皿目【お玉じゃねえ】
【嫁の料理は】嫁のメシがまずい 38皿目【当たりつき】
【天国に】嫁のメシがまずい 39皿目【一番近いメシ】
【サバの味噌煮は】嫁のメシがまずい 40皿目【鯵じゃ無理】
【幼子も】嫁のメシがまずい 41皿目【匙を投げる】
【次嫁のメシがまずい くらい】嫁のメシがまずい 42皿目【とっとと立てれ】
【レシピ通りに】嫁のメシがまずい 43皿目【作ったら負けかと思っている】
【わかんない】嫁のメシがまずい 44皿目【思いついただけ】
【喉が痛いなら】嫁のメシがまずい 46皿目【イソジンカレー】
【マズメシは】嫁のメシがまずい 47皿目【家庭崩壊の危機】
【普通を求めて】嫁のメシがまずい 49皿目【何が悪い】
【はるかな夢】嫁のメシがまずい 50皿目【美味い飯】
【夏バテだから】嫁のメシがまずい 51皿目【素麺にリポD】
【びゃあ゛ぁ゛゛ぁ】嫁のメシがまずい 52皿目【まずいぃ゛ぃぃ゛】
【サンマと漁師に】嫁のメシがまずい 53皿目【ゴメンナサイ】
【秋茄子は】嫁のメシがまずい 54皿目【嫁に任すな】
【食べるな】嫁の飯がまずい55皿目【危険】
【綺麗な料理だろ】嫁のメシがまずい 56皿目【食えないんだぜこれ】
【片栗粉は】嫁のメシがまずい 59皿目【骨じゃねぇ・出汁でねぇ】
【マズメシ憎んで】嫁のメシがまずい 60皿目【嫁を憎まず】
【電子レンジは】嫁のメシがまずい 61皿目【パンドラの箱】
【秘蔵の日本酒】嫁のメシがまずい 62皿目【嫁の料理酒】
【発酵?】嫁のメシがまずい 63皿目【腐敗?】
【漬け物で】嫁のメシがまずい 64皿目【入院】

また、上記64皿目には次のスレタイ案が掲載されています。

954 :名無しさん@お腹いっぱい。:2007/11/23(金) 15:16:25
スレタイ案まとめ

【核兵器級】【濃縮味噌汁】
【隣は水炊き】【ウチは闇鍋】
【愛って何だ】【ためらわないことさ】
【赤飯は】【あんこ使わない】
【かもして】【ころすぞ】
【退院】【おめでとう】
【三年間で】【入院五回】
【スパムにも】【塩タップリ】
【嫁が】【危険物】
【お母さん】【元気ですか?】
【とりあえず】【かぼす】
【頭痛いの?】【ただの風邪よ】
【殺される】【殺された】
【唐揚げ戦線】【異常あり】
【義母さん】【助けて】
【少々は】【大スプーンで】
【漬け物嫁は】【うつけ者】
【俺とメシと】【時々入院】
【適量?】【適当?】
【ごめんね】【LUNCH・BOX】
【俺も長生き】【したいんだ】
【離婚届けは】【ごちそうさまのあと】
【生か】【死か】
【もう】【死にそう】
【来年まで】【生き残れ】
【クリスマスケーキは】【おかずじゃない】
【こびりついた】【コゲと俺】
【吉兆より】【恐ろしい】
【惣菜が】【第二夫人】
【死因は】【家庭料理】
【漬物は】【熟成毒】
【Hell死夫】【ル狂うぜ】
【病院食で】【生き残れ】
【しんでしまうとは】【なさけない】
【入院と】【鋼鉄腹と】
【いっそ味蕾を】【無くしたい】
【菌も調味料も】【てんこもり】
【嫁のメシが】【危険】
【素敵料理は】【俺専用…】
【漬け物で】【入院】
【飯】【逃げ出した後】

自分で作ればいいじゃん、とか、一緒に作ればいいじゃん、というツッコミはさておき、問題に入りましょう。

■問題1
以上の文字列から、Wordの置換機能を用いてサブタイトルのみに変換するには、どうしたら良いでしょう?

●攻略法を考える:

対象の文字列をよく観察します。

【A】B【C】

または

【A】【C】

という形式になっていることがわかります。

ここで、Bの有無については、実は、「0文字以上の文字」という風に読み替えして解決する、という方法も、常套手段としてよく使われるわけです。

今回も、これを使って解決しようと思うわけです。

なお、以下では、「ワイルドカードを使用する」をONに指定し、「置換後の文字列」には「\1\2」を指定して作業することを前提とします。

さて、【と】で挟まれているAとCの文字だけを取り出したいわけです。
ところが、

○検索する文字列:
【([!【]@)】[!【】]@【([!【]@)】
では、「スレタイ案」の方は残ってしまいます。

しかし、
【([!【]@)】[!【】]*【([!【]@)】
では、「スレタイ案」も上手く行きますが、改行が無くなってしまいます。

ところで、「ワイルドカードを使用する」をONにしている場合、^pは効きません。
しかしその場合でも、コード番号の直接指定で切り抜けられます。
「^」の後にASCIIコード番号を10進番号で入れます。因みに16進ではうまく行きません。

なお、Unicode値を使用した文字検索もできます。
その場合の指定は「^u」の後にUnicodeのコード番号を10進番号で入れます。
これも16進ではうまく行きません。
更に、[大文字と小文字を区別する] チェック ボックスをオンにする必要があります。

例:
6のUnicode16進番号は36。それを10進になおすと54。よって^u0054でヒット。
「で」のUnicode16進番号は3067。それを10進になおすと12391。よって^u12391でヒット。
「嫁」のUnicode16進番号は5AC1。それを10進になおすと23233。よって^u23233でヒット。
5AC1を16進→10進に換算するのはGoogleの検索窓に0x5ac1 in decimalと入れればできる。
10進→16進は23233 in hexadecimalとやる。2進への変換は23233 in binaryとか。

Word内での改行はCR+LFではなく、LFだけなので、16進数で0D、つまり10進数で
13を使って^13とすれば^pと同義になる。

よって、

【([!【]@)】[!【】^13]@【([!【]@)】

でも行けそうな気がします。しかし、それでも「スレタイ案」の方は残ってしまいます。

直前の文字または式を n 個以上、という指定は {n,} なので、

【([!【]@)】[!【】^13]{0,}【([!【]@)】

としてみると、エラーが出ます。0ではダメなようです。
しかし、

【([!【]@)】[!【】^13]*【([!【]@)】

のような指定は、そもそも * が「直前の文字の…」ではありませんから不可です。
実際に試してみると、どういうわけか、「スレタイ案」の方は残ってしまいます。

Wordには選択子はありませんから、

【([!【]@)】([!【】^13]|*)【([!【]@)】

のように書いて、置換後の文字列の指定を\1\3としてもダメです。では [ ] で「いずれか」を示すやり方は通るかと言うと、

【([!【]@)】[[!【】^13]*]【([!【]@)】

でもダメです。Wordでは [ ] は[a-zND]のような書き方で小文字と大文字のNとDだけに一致させられることは確認しましたが、そこに * を入れるのはダメなようです。

で、「ひょっとして、最短一致?」ということで、以下の指定をしてみました。

【([!【]@)】*【([!【]@)】

驚くべき事に、これで上手くいってしまいます。
おいおい、最左最長一致じゃないんか?

どうも、Wordは最長一致ではなく、最短一致を標準としているようにも見えます。

そうだとすると、 ( ) 内で【以外を指定している [!【]@ すら不要ということになります。

そこで、単純化して

○検索する文字列:
【(*)】*【(*)】

○置換後の文字列:
\1\2

とやってみると、Wordの場合、これでチャンと動くようです。

…って、ここまで書いて、量指定子の挙動について同様の指摘をしているページを発見。

その後も、折を見ていろいろ実験しましたが、結局、以下のように考えるのが良いようです(2011/02/28現在の判断)。

■問題2
では、同様のことを、ふつーの正規表現をふつーにサポートしているEmEditorで行う場合は、どうしたら良いでしょうか?

●解法のヒント:

最左最長一致であることを念頭に置く必要がある。

MS独自のものではない、一般に普及する正規表現では、文字クラス [ ] の中で否定を行う場合、否定演算子 ! ではなくメタ文字 ^ を使うことが多い。
メタ文字 ^ を使った場合、それに続く「各文字1つずつ」の全てを否定できる。
例えば[^abc]で「aでもbでもcでもない」にできる。

●正解例:
○検索する文字列:
【([^【]*)】[^【】]*【([^【]*)】

○置換後の文字列:
\1\2

目次へ戻る

ピンインそのものを入力する方法

ピンインそのものを入力したい場合、中国語IMEを設定しているならば、「マウスカーソルの絵が見えるボタン」から、以下のメニューを辿れば設定できます。

このとき、Pinyin letteerではなくPhoneticを選択すると、注音字母の入力もできます。

ソフト外見

キーボードの絵のボタンを押せば、「ソフトキーボード」の「ピンイン」が表示されます。

ここで、画面上のソフトキーボードのボタンをマウスでクリックしても入力できるし、また、キーボードを打鍵しても入力できます。

ソフト外見

おまけ:ピンイン入力ツール PIN Boy v3.02改 HTA版

PINBoyForHTA.zipをダウンロード後、解凍します。

解凍されたPINBoyForHTA.htaをダブルクリックすると、中国語IMEを設定していなくても、ピンイン入力ができるようになります。

ONにしてから、枠内に入力すると

v1→ǖ v2→ǘ

 

v3→ǚ v4→ǜ v5→ü

のリアルタイム変換がされます。

デスクトップなどに置いておけば便利かもしれません。

HTA(Hyper Text Application)形式のJavaScriptはWindows上のIEで動作します。
Macでは、たぶん動きません。(以下の補記を参照のこと。)

ライセンス関係はHTAファイルのソースをご覧下さい。
オリジナルから、「リアルタイム入力変換」の関数のみを実装しました。

以下、2009/01/02補記

清原文代老師からのご教示によると、当初は、ダブルクリックしただけでは起動できないが、

  1. アイコンをcontrol+クリック。

  2. 「このアプリケーションで開く」から「その他」を選ぶ。

  3. 「選択対象」を「推奨アプリケーション」から「全アプリケーション」に変更する。

  4. SafariかFirefoxを選ぶ。

これでMacOSでも動くらしいです。
なお、二回目からはダブルクリックで開くようだ、とのお教えを受けました。

なんでHTAがMacで動くのかを考えたんですが、HTAの中身は実質、html+javascriptですので、拡張子の関連付けをしてやれば動く、と。そういうことみたいです。
この予想が当たっているとすれば、もっと楽な作業でMacOSで使うには、「PINBoyForHTA.hta」とうファイルの末尾(拡張子)をhtmやhtmlに変更するのが良いんじゃないかと思います。
この予想が当たっているとすれば、たぶん、MacOS9でも動くんじゃないかなぁ…。

まぁ、そんなこんなで、exeだとMACで解凍できないので、ダウンロードファイルをzipに差し替えました(中身は同じです)。

目次へ戻る

青空文庫ルビ付き文書の書式を変更する方法

青空文庫のルビ付きテキストファイルで、「ルビが付く範囲を明示するような表記」に変更したい場合があります。例えば、

青空文庫の表記   置換後の表記
釜形《かまがた》 《釜形/かまがた》
尖《とが》った 《尖/とが》った
被《か》ずいて 《被/か》ずいて
外套《がいとう》を 《外套/がいとう》を
猫背《ねこぜ》に 《猫背/ねこぜ》に
爺《じい》さん 《爺/じい》さん
佇《とど》めて 《佇/とど》めて

というようにしたいわけです。

これをEmEditorの置換機能を使って行うには、以下のような正規表現を用います。

検索する文字列

([^一-龥])([一-龥]+)《([ぁ-ヿA-z]+)》

置換する文字列

\1《\2/\3》

芥川龍之介「煙管」の冒頭部分で試してみましょう。

●置換前
 加州《かしゅう》石川|郡《ごおり》金沢城の城主、前田|斉広《なりひろ》は、参覲中《さんきんちゅう》、江戸城の本丸《ほんまる》へ登城《とじょう》する毎に、必ず愛用の煙管《きせる》を持って行った。当時有名な煙管商、住吉屋七兵衛《すみよしやしちべえ》の手に成った、金無垢地《きんむくじ》に、剣梅鉢《けんうめばち》の紋《もん》ぢらしと云う、数寄《すき》を凝《こ》らした煙管《きせる》である。
 前田家は、幕府の制度によると、五世《ごせ》、加賀守綱紀《かがのかみつなのり》以来、大廊下詰《おおろうかづめ》で、席次は、世々|尾紀水三家《びきすいさんけ》の次を占めている。勿論、裕福な事も、当時の大小名の中で、肩を比べる者は、ほとんど、一人もない。だから、その当主たる斉広が、金無垢《きんむく》の煙管を持つと云う事は、寧《むし》ろ身分相当の装飾品を持つのに過ぎないのである。

●置換結果
 《加州/かしゅう》石川|《郡/ごおり》金沢城の城主、前田|《斉広/なりひろ》は、《参覲中/さんきんちゅう》、江戸城の《本丸/ほんまる》へ《登城/とじょう》する毎に、必ず愛用の《煙管/きせる》を持って行った。当時有名な煙管商、《住吉屋七兵衛/すみよしやしちべえ》の手に成った、《金無垢地/きんむくじ》に、《剣梅鉢/けんうめばち》の《紋/もん》ぢらしと云う、《数寄/すき》を《凝/こ》らした《煙管/きせる》である。
 前田家は、幕府の制度によると、《五世/ごせ》、《加賀守綱紀/かがのかみつなのり》以来、《大廊下詰/おおろうかづめ》で、席次は、世々|《尾紀水三家/びきすいさんけ》の次を占めている。勿論、裕福な事も、当時の大小名の中で、肩を比べる者は、ほとんど、一人もない。だから、その当主たる斉広が、《金無垢/きんむく》の煙管を持つと云う事は、《寧/むし》ろ身分相当の装飾品を持つのに過ぎないのである。

解説

ルビは、何らかの熟語に付くのが普通なわけです。
んで、「何らかの熟語」は、漢字熟語である場合がほとんどです。
従って、その漢字熟語の「直前」は、「漢字以外」のはずです。
しかも青空文庫の場合、本文が「石川郡」で、その「郡」に対してのみ「ごおり」という振り仮名が付いている場合、ちゃんと「|」で区切ってくれているわけです。
そして、「|」は「漢字以外」の文字であるわけですね。

  1. 検索する文字列で指定している [^一-龥] は、「漢字以外」を示しています。

  2. そして [一-龥]+ は「漢字1文字以上」を示しています。

  3. 更に [ぁ-ヿA-z]+ は平仮名・カタカナ・全角アルファベットを示しています。

以上3点が、正規表現を解読するヒントです。

目次へ戻る

白居易は妓女を養っていたけど、同様の贅沢ができるようになったという話

VOCALOID2初音ミク。すげー。

般若心経も行けるのか。ナムナム。

東京メトロの車内放送の声は鼻濁音の発音が気になって仕方ないので、いっそのこと、初音ミクでどうよ?とか、留守電メッセージをミクたんにお願いしてしまうのも手かも…とか。三田寛子さんの声で京阪アクセントを再現すると面白いかもとか、色々思うところあり。

なお、真紅様によるコメントは以下の通り(サーバ劇重)。

ローゼンメイデン アリスプロジェクト ローゼンメイデン アリスプロジェクト

目次へ戻る

EmEditorの置換機能(正規表現ON)で、人民日報コーパスからタグを全部除去する指定

人民日報コーパスは、北京大学計算語言学研究所のWebSiteから入手できます。

1:「\/[a-z]+\]?([ |a-z][ |a-z])?」を、何もナシに置換する。
→この置換は、かなり(1時間くらい)かかる。
2:「\[」を、何もナシに置換する。
3:「  」(半角スペース2個)を、何もナシに置換する。
4:「^\n」を、何もナシに置換する。
5:「([0-9]{8,}-[0-9]{2,}-[0-9]{3,}-[0-9]{3,})」を「\1\t」に置換する。

目次へ戻る

VBA備忘録

"""イロハニ"",""ホヘト"""

で、

"イロハニ","ホヘト"

となる。その他の文字の場合はchr(num)で。

Dim WshShell, oExec
Set WshShell = CreateObject("WScript.Shell")
Set oExec = WshShell.Exec( "del Tmp.txt" )


なんて言う指定は通らない。ファイルが無いと怒られる。

同じディレクトリにあってもTmp.txtのパスをフルパスで書かなきゃナランのか?
とか、"Program Files"以下のディレクトリだからダブルクオーテーションで括ってやらにゃイカンのか?とか 、試行錯誤したけどダメ。

ま・さ・か…。内部コマンドがダメ?
ビンゴ!

ところがCMD.EXEはパスなしで呼び出せる。
というわけで、パスなしでも以下の指定で通るのであった。

Set oExec = WshShell.Exec( "cmd /c del Tmp.txt" )

なんじゃこりゃ?
ホントにこんな仕様なんだろうか?
自分が勉強不足なだけなんだろうか…。

目次へ戻る

Excel関数って、一行野郎と言えなくもない。

表のようなデータを持つExcelのB列に、0001-001、0001-002、…0001-017、0002-001…という風に「歌番号-句番号」を振りたい。さて、B列にはどういう式を入れましょうか?

 
1 1 0001-001 籠もよ
2 1 0001-002 み籠持ち
3 1 0001-003 堀串もよ
4 1 0001-004 み堀串持ち
5 1 0001-005 この丘に
6 1 0001-006 菜摘ます子
7 1 0001-007 家告らせ
8 1 0001-008 名のらさね
9 1 0001-009 そらみつ
10 1 0001-010 大和の国は
11 1 0001-011 おしなべて
12 1 0001-012 吾こそ居れ
13 1 0001-013 しきなべて
14 1 0001-014 吾こそ座せ
15 1 0001-015 吾をこそ
16 1 0001-016 夫とは告らめ
17 1 0001-017 家をも名をも
18 2 0002-001 大和には
19 2 0002-002 群山あれど
20 2 0002-003 とりよろふ
21 2 0002-004 天の香具山
22 2 0002-005 登り立ち
23 2 0002-006 国見をすれば
24 2 0002-007 国原は
25 2 0002-008 煙立ち立つ
26 2 0002-009 海原は
27 2 0002-010 鴎立ち立つ
28 2 0002-011 うまし国ぞ
29 2 0002-012 蜻蛉島
30 2 0002-013 大和の国は

第1案

一応、4-LEN()として桁数を出してREPT("0",…)0を埋めている所がミソといえばミソではある。

また、SUMIF($A$1:A2,A2,A:A)/A2)とした所は、A列先頭行からA列の現在注目セルと同じ行までの中で、現在注目セルと同じ行にあるA列の値と一致するものを見つけてそれらを全部加算し、その加算結果を現在注目セルと同じ行にあるA列の値で割ってね、という指定である。

これによって、「とりよろふ」は、(2+2+2)/2=3となる。つまり、2番歌の3句目だよ~ん、ってことがわかるわけ。我ながら賢いかも。

しかし、冒頭のA2=A1で一つ上のセルを参照しているため、この式ではB1のセルにいきなり入れるとエラーが出る。

で、そのエラー処理のためにISERRなど使った。

その結果、ただでさえ長いのに、同じ事を二重に書く羽目になっているし、B2のセルから入れて、B1にフィル、その後でB3以降にフィルしないといけない。ダメだな、こりゃ。

第2案

B1のセルを始点としたかったので、冒頭部分、A1との比較で行位置を(ROW()-1+1)で出し、Aと繋げて番地扱いにしている。
さっきよりはスッキリした。
こうやってスッキリさせると、自分で何やっているのか見えやすくなる。そしてROW()-1+1って、つまりROW()と一緒じゃん、と気づくのであった。バカである。もうちょっと考えよう。

第3案

さきほど意味を為していなかった冒頭のIF文を取り払った。
あれ?SUMIFの中の最後のオプション、無くても動くんじゃないの?

第4案

ということで、削っても動きました。なんか、用心のためとは言え、余分な()があるようだ。

第5案

とりあえず、こんな感じか?しかしそれにしても、REPTメンドクセ。printfとかsprintfとかないの?

第6案

VBAにFORMAT関数ってのがあるのを発見。こいつを使って「ニセprintf関数」を作ってみた。

この関数そのものは動くけど、引数は2つ必要になってしまう。
まぁ、これはこれで何かの時に使えるだろうけどね。
差し当たり、引数が1つでも動くように改造せねばならん。

これではセルを一つずつ確定、確定しないとダメ。ループで回さないとイカンのか?
よくわからん。処理が速くなるわけでもなさそうだし、面倒なのでこれは却下だなぁ。

第7案

セルの書式設定で0000とか出来るわけだから、似たような関数があるはず。
よくよく探してみると、Excelにもあるじゃん。
でも、TEXTなんて名前つけるセンスはどうよ?これじゃ、見つからないって。フツー。

ま、こんな所でいいでしょ。

しかしこれじゃ、「サラッと一行野郎」って言うより、苦吟する俳人の風情だな。

「花香風に和し月光水に浮ぶ」なんて気分にはなれませんが。

目次へ戻る

MS-IMEによる音声入力

MS-IMEの音声入力機能を使って、NHKの朝7時のニュースを書き出させてみた。

Windows Media Player からの出力は、ヘッドホンコネクタからオス/オスケーブルでマイクコネクタに接続し(つまりアナログ入力になる)、再生モードは「ゆっくり」。ME-IME側は「直接入力」とし、その他の設定はデフォルトとした。認識エンジンはSAPI 5.1を使用した。

※ちなみにネット上で配布されているSAPI5.1のspeechsdk51LangPack.exeには、日本語と中国語の音声認識エンジンのみが入っており、音声合成エンジン(LH Kenji/LH Naoko)は、WinXP Office XPに付属していて、SAPI4.0aMicrosoft Agentの音声定義ファイルの組み合わせはSAPI5.xと互換性がない(はず)。
ところが、Adobeの公開している文書<この説明文書はわかりやすい。)を読むと、Microsoft Agentの音声定義ファイル(AdultMale #1 Japanese(L&H)など)のTTS3000ファイルはSAPI5.Xでも使えるみたい。
たしかに、プロパティ見るとそうなっているんだけど、このファイルをOfficeから入手したか、ネットから入手したか、忘れてしまったので実際のところはよくわからん。

最初の1分間を変換させた結果が、画像の通り。
音声辞書の教育を一切やっていないとはいえ、散々なものでした。残念。

NHKラジオニュースでの惨憺たる結果

犬語を認識するのは当分難しいんじゃなかと…

ラジオを聞きながら、自分で読み上げ、その自分の声で入力すれば、もう少し精度は上がるかもしれません。

ちなみに、SAPIの読み上げの方は、元文書に読点や括弧を補ってやり、読み間違えする熟語などは仮名に開いてやれば、まぁまぁの結果(mp3、約800KB)です。

下の本文は、赤部分が変更を加えたところ。

親譲りの無鉄砲で、こどもの時から損ばかりしている。
小学校に居る時分学校の二階から飛び降りて一週間ほど腰を抜かした事がある。
なぜそんな無闇をしたと聞く人があるかも知れぬ。
別段深い理由でもない。
新築の二階から首を出していたら、同級生の一人が、冗談に、いくら威張っても、そこから飛び降りる事は出来まい。弱虫やーい。と囃したからである。
小使に負ぶさって帰って来た時、おやじが大きな眼をして二階ぐらいから飛び降りて腰を抜かす奴があるかと云ったから、この次は抜かさずに飛んで見せますと答えた。

目次へ戻る

素のWindows+ フリーソフトでどれだけ代替できそうか?

まぁ、OSレベルからUnixなUbuntuとかFedoraを入れて…ってやれば?って話にすぐなるわけですが、「とにかくOSだけはWinなの!」っていう条件を付けた場合どうなるか。ちょっと思考実験。

条件:

以下は、目に付いた物だけ。実際には試していない物の方が多い。

2015-11-22ちょっと加筆

目次へ戻る

中文 簡体字・繁体字変換Tool Ver1.0 2006/03/11

■概要

■動作確認

ソフト外見

「異体字を使用する」と「共通の用語を翻訳する」の指定があるかどうかで、結果は変化します。

以下のテスト用テキストで挙動を試してみると良いでしょう。

空前绝后.皇后.
两面镜子.汤面.
谷雨.硅谷.
乙丑年.丑话说在头里.
干涉.干部.干打雷,不下雨.
计算机.报话机.软件数据库.
周报.报道.
乌云遮不住太阳,云云.

目次へ戻る

中国語翻訳関係のBookmarkletを使ってみよう!

中国語の辞書引きや翻訳をするブックマークレットです。

これは、國學院での授業用に作ったんだけど、國學院の環境では設定できない。
「リンク」ツールバーへのショートカット登録を禁止する設定になっているせいかもしれない。

目次へ戻る

Unicode対応のgawkをgrep代わりに使うワンライナー(一行コマンド)

gawk --ctype=UTF8 "/正規表現/" 対象ファイル名 > 出力ファイル名

Unicode対応のgawkについてはここに書きました。

目次へ戻る

Excelによる平仄と押韻の検定 Ver1.03

拙稿「平仄押韻判定機の作成法―Excelを用いた場合―」(『近思学報・史料と研究』第3輯 近思文庫編 港の人 2006/02)で作ったもの。

 ダウンロード 自己解凍ファイルHYOSOKU103.EXE 598,899(2013/01/08 Ver UP to ver1.03)

目次へ戻る

テキスト処理用JavaScriptツール集

上に掲げたモノたちについての補足説明

新出尚之氏によるUNIX-like toolsアオチャンのサイト、ベクターオリジナルftpで入手可能。最新版は412g)は、とても便利なもので、卒論作成でも修論作成でも、SEDやGREPやAWKと共に、さんざんお世話になりました。
そのUNIX-like toolsですが、川俣晶氏によってNT版UNIX-like toolsとしてWinNT対応版がリリースされていて、一部のツールはUnicodeが通ります。

ところで、来春(2006年4月)に入学する大学1年生(現役合格者=18歳)は、1988年生まれです。
1988年って、昭和63年なんですよ。
昭和64年は平成元年ですので、1988年が、実質上の昭和最後の年ということになります。
さて、1988年はどのような年であったか。

因みにファミコン発売が1983年、Macの発売が1984年…生まれる前なんですな。
そりゃ、「DOSプロンプトって何?」なのも、至極当然なわけです。

また、DOS5.x時代までのコマンドラインツールは、Unicode規格制定以前ですので、普通はUnicodeが通らない。
でも、万葉仮名やら漢文を扱うときには、これでは困るわけですね。

そういうわけで、UNIX-like toolsの中で、今でもよく使われそうなものをJavaScriptやVBScriptと、ブラウザの組み合わせで代替できないかな…と。そんなことを考えたのであります。
(※headやtailなとはGUIが一般的な環境では、あまり使わないんじゃないかな。

目次へ戻る

テキスト検索ツール VBsGrep 2005/12/30版

ソフト外見

目次へ戻る

畳語を見つけるための正規表現EmEditorの場合)

2字以上の任意の長さの文字列の2回以上の繰り返し。

(..+)\1+

1字以上の任意の長さの文字列の2回以上の繰り返しならば以下のようになる。

(.+)\1+

grepを使う場合は、グループ化指定タグ部分の () は、\ でエスケープする必要がある場合もあるかもしれない。

但し、これらの正規表現では「近々」「くれぐれも」「かたがた」は出てこない。

目次へ戻る

改行を挟んだ検索のための正規表現EmEditorの場合)

天[^\n]*\n[^\n]*地

上の正規表現で

…ほげほげ…[改行]

…うにうに…

つまり改行が一つ入る場合を見つけられる。

天[^\n]*\n[^\n]*\n[^\n]*地

上の正規表現で

…ほげほげ…[改行]

…うにうに…[改行]

…んにゃんにゃ…

つまり改行が2つ入る場合を見つけられる。

解説:

結局、 天[^\n]*\n[^\n]*地 という正規表現は

まず「天」が来て、
その後に「改行以外の文字」が「0回以上繰り返され」、
更にその後に「改行」が来て、
その後に「改行以外の文字」が「0回以上繰り返され」、
その後に「地」が来るもの

を見つけてちょ。というワケですな。隔句対などを探すときに便利です。

目次へ戻る

ファジイ検索対応N-gram処理のためのJperlスクリプト

拙稿「曖昧検索性を持たせたN-gramサーチの手法―『新撰萬葉集』と菅原道真の詩の比較を例に―」(『漢字文献情報処理研究』第二号 好文出版 2001/10)の本文中で紹介したスクリプト。

これで何ができるか?

  1. 与えられたテキストファイルから指定文字数までの文字列長を切り出す。
  2. あいまい検索、ファジイ検索ができるDOSのソフトに渡して検索対象ファイルを検索させる。
  3. 1~2を繰り返す。
  4. n-gram検索にあいまい検索性を持たせた結果と同様の結果を得られる。

要するに、


というようなbatファイルを作って実行するのと同じような結果を得られます。

ZFを使わないでSSTRを使う場合は、真ん中辺りにある「zf /i」をSSTRの起動オプションに変更すれば対応可能。

目次へ戻る

暦変換プログラムWhenの解説(両方とも、Windows95以降用 2000/10/06)

『電脳国文学』付録CD-ROM収録のVer0.5β版にはアーカイヴ上のミスがありました。お詫びいたします。
下の最新版をダウンロードしてご利用下さい。
「GUI対応版When インストール方法説明 When簡易マニュアル(私家版β ver0.7)」最新版ダウンロード(約1.2MB)

目次へ戻る

謎(メールで質問されても返事しません)

目次へ戻る

INDEX用のHTMLファイル自動作成スクリプト

目次へ戻る

16進コード番号からUtf8形式のUnicodeを生成するスクリプト(jperl用)

目次へ戻る


[Go to top page]

copyright 1997~ 谷本玲大
http://www.tanimoto.to/