author | Eckhart Koeppen <eckhart.koppen@nokia.com> |
Wed, 21 Apr 2010 11:15:19 +0300 | |
branch | RCL_3 |
changeset 11 | 25a739ee40f4 |
parent 1 | ae9c8dab0e3e |
permissions | -rw-r--r-- |
1
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1 |
Shift-JISテキストを正しく扱う |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
2 |
最近の更新履歴 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
3 |
2005-03-26: 「最初に」中、XML日本語プロファイル第2版に基づき、若干追記。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
4 |
2005-03-09: 「最初に」中、文章を若干修正。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
5 |
2003-06-24: Shift-JISの漢字を含むファイル名/パス名 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
6 |
2003-05-31: 「最初に」中、「シフトJIS」などの表記について。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
7 |
2003-05-24: CP932重複定義文字の変換 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
8 |
2002-08-30: Perl 5.8.0 について。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
9 |
2002-01-17: 長い文字列に対する正規表現検索 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
10 |
2001-12-15: ShiftJIS::Collate が overrideCJK パラメータを廃止したことに伴う 日本語文字列を並び替えるの書き換え。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
11 |
最初に |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
12 |
ありがちなエラー |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
13 |
エラーや間違いを防ぐ対策 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
14 |
文字列リテラルの作り方 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
15 |
正規表現とマッチ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
16 |
グローバルマッチ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
17 |
アルファベットの大文字と小文字 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
18 |
長い文字列に対する正規表現検索 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
19 |
外字の変換 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
20 |
CP932重複定義文字の変換 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
21 |
文字数を数える |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
22 |
文字単位に分割する |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
23 |
いろいろな分割 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
24 |
特定の長さで切りそろえる |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
25 |
日本語文字列を並び替える |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
26 |
Shift-JISの漢字を含むファイル名/パス名 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
27 |
最初に |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
28 |
日本語の文字コードにはいくつかのものが使われています。ある程度一般的なものなら、どれを使ってもよいでしょう(どの文字コードで符号化されているかの情報が失われさえしなければ)。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
29 |
例えば、日本語版Windowsでは、メモ帳でもDOS窓でもShift-JISが使われています。こういう場合、処理の途中でわざわざEUC-JPやUTF-8に変換するとしたら面倒です。デバッグのとき、「この段階ではこの変数には何が入っているのか」出力して点検するのはよく行われますが、このときEUC-JPとして収められていたら、作業は手間どるでしょう。入力も出力もShift-JISで行うつもりなら、処理の全体でShift-JISのまま扱えたらきっと便利でしょう。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
30 |
注: "シフトJIS", "Shift_JIS", "Shift-JIS" などの表記の違いについてはよくわかっていません。今のところ分かっていることは: |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
31 |
JIS X 0208:1997の附属書1(シフト符号化表現)には、「参考」として「この符号化表現は通常“シフトJISコード”と呼ばれている」の記述があります。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
32 |
IANA の CHARACTER SETS には、Shift_JIS と Windows-31J とが別に登録されています。また、Shift_JISについて、「CCS(符号化文字集合)はJIS X0201:1997とJIS X0208:1997であり、完全な定義はJIS X 0208:1997の附属書1に示されている。」と記しています。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
33 |
W3C の XML Japanese Profile には、Shift-JISにUnicodeへの変換表が複数ある旨の記載があります。XML Japanese Profile (Second Edition)では、Unicode Consortiumで公開されているMicrosoft CP932の変換表によるcharsetの名称 "x-sjis-cp932" を "Windows-31J" に変更しています。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
34 |
Microsoft社の Global Dev では、Codepage 932 を "Japanese Shift-JIS" と注記しています。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
35 |
しかし、Shift-JISにはある種の癖があって、ちょっとしたことがバグやエラーや文字化けの原因となります。なんとかならないものでしょうか。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
36 |
Perlは制御文字やナル文字を含むバイナリデータですら正しく処理できるように設計されているので、スクリプトやテキストをShift-JISで書いたくらいで問題になることはありません。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
37 |
しかし、perlがスクリプトを解釈するときは(通常)バイト単位で調べるので、Shift-JISのようなマルチバイト文字を含む符号はそのままでは直接理解できません。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
38 |
たとえば、Shift-JISで 'あ' という文字は、16進数で82 A0という2バイトで表されます。これを "\x82\xA0" と書いてもperlにとっては同じです。これが日本の(country)日本語の(language)文字であるとか、Shift-JISで書かれている(charset)とかいう情報はどこにも含まれていません。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
39 |
そのため、Shift-JISで書きたいときには、perlの誤解を受けないように書いてやらなければなりません。その配慮は、プログラマがしてやらなければなりません。この文書の記述は、そのような手間をかけても、Shift-JISを用いることに意義があると考えている人には参考になるかもしれません。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
40 |
そんな手間を掛けたくない人は、 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
41 |
Perl 5.8.x以降を使う。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
42 |
利点:perl5-porters@perl.org でサポートされている。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
43 |
欠点:独特の考え方があり、従来の日本語処理とは相容れないところがある(もっとも、そのうち慣れて気にならなくなるかもしれない)。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
44 |
jperlを使う。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
45 |
利点:Shift-JIS を文字として直接扱うことができる。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
46 |
欠点:現在、維持する人がいない。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
47 |
文字コードをUTF-8かEUC-JPに変換してから処理する。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
48 |
利点:Perl 5.8.x以降でなくても動作する変換用のモジュール(.pm)やライブラリ(.pl)がいろいろ入手可能。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
49 |
欠点:Shift-JISほど悪くないにしても、マルチバイト文字をシングルバイト文字と区別せず、ともに一文字として処理するのは面倒である。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
50 |
という対処をとったほうがよいでしょう。これらのプログラムは有名なので、探せばすぐ見つかるでしょうから、入手先はここには示しません。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
51 |
なお、この文書に書かれている事が、最も勧められない方法なので、ここから先は、そのつもりでお読み下さい。この方法について何か疑問が生じたとしても、それについて他のところで質問すると、何でそんなやり方をしているのかと、きっと非難されるでしょう。かといって、私にも訊かないで下さい。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
52 |
Shift-JISを使ったときにありがちな(?)エラー |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
53 |
Shift-JISには、第2バイトが [@-~](ASCII 10進数で64-126)の範囲に入るものがあります。これらのASCII文字は、perlにとって特別な意味をもつことがあるため、しばしばエラーの原因となります。Shift-JISでは、2バイト文字の第2バイトは、[\x40-\x7E\x80-\xFC])の範囲にあるため、実に188分の63、約3分の1の文字が何らかの問題を起こし得るといえます。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
54 |
次に、Shift-JISを使ったときに起こりがちなエラーとその原因を示します。エラーメッセージはperlの違い(バージョンやどのプラットフォーム用のものであるか等)により多少の違いがあるかもしれません。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
55 |
エラーにならなくても、文字化けしたり、期待したような動作をしなかったりで、うまくいかないことがあります。この場合、エラーが出ない分、原因を自分で探さなければならなくなるためバグ取りはしばしば困難です。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
56 |
ここではエラーに対する対策は提示しません。対策はあとでまとめて書きます。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
57 |
なお、ここには文字コードをEUC-JPにしても起こるような問題やエラーは示しません。基本的に、EUC-JPなら起きないが、Shift-JISのときには起こるような事柄に限ります。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
58 |
エラーにはならないけど文字化けする(1) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
59 |
例えば、"表示" とか "暴力" とかいうリテラルが文字化けを起こします。これらは "侮ヲ" とか "沫ヘ" になります。これは、"表" や "暴"の文字の第2バイトが \ であるため、ダブルクオート文字の中では次の文字のエスケープをすることになるので、表示 = 0x955C8EA6 であっても、クオートの結果は "表示" = 0x958EA6 となるからです。'表示' とすれば文字化けは起こりませんが、シングルクオートでも防げない文字化けやエラーがあります(次例)。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
60 |
エラーにはならないけど文字化けする(2) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
61 |
例えば、"ミソ\500" というリテラルでは、\ が脱落してしまいます。これは、'ミソ\500' や q(ミソ\500) などとしても防ぐことができません。それは \\ という連続があると \ 1個になってしまうという規則があるからです。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
62 |
クオートやクオート風演算子の中では、文字列にクオートと同じ文字を含められるように、\ によるエスケープを付ければクオートの終端文字ではなく、文字列の一部とみなします。そのため、\\ が \ の文字を表すエスケープになります。これはクオートの始端・終端文字を何にしても同じことです。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
63 |
エラーにはならないけど文字化けする(3) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
64 |
例えば、"丸十net" というリテラルが文字化けを起こします。これは "丸・ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
65 |
et" のように途中で改行されてしまいます。これは、"十" の第2バイトが \ であるため、ダブルクオート文字の中では次の 'n' と合わせて\nのすなわち改行文字を表すメタ文字として解釈されるからです。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
66 |
エラーにはならないけど文字化けする(4) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
67 |
例えば、"引数 ARGV" というリテラルが文字化けを起こします。これは、" "(全角スペース)の第2バイトが @ であるため、ダブルクオート文字の中では次の ARGV と合わせて "@ARGV" という配列として変数展開を行うからです。@ARGVのように必ず定義されるような配列なら、展開されますが、別の場合ではエラーになるかもしれません(それは次項を参照)。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
68 |
In string, @dog now must be written as \@dog (Perl 5.6.0まで) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
69 |
「文字列の中では、@dogは今は\@dogと書かなければならない」 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
70 |
前例でみたように、全角スペース " "の第2バイトは @ であるため、後ろの文字と合わせて配列であるかのように解釈しようとします。"犬 dog" のような場合、@dog という配列が定義されていればそれを用いて変数展開しますが、定義されていない場合、エラーメッセージを出します。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
71 |
``now must be written as''「今はこう書かなければならない」とは、Perl4までは配列の変数展開は行わなかったため、"hoge@foo.bar" のような書き方をすることができたのだが、今 Perlでは @foo が展開されてしまうので、注意を喚起するためエラーを出すようにしているようです(もしPerlが昔から配列の展開をサポートしていたら、エラーを出すことなく、黙って展開するだけだったかもしれません。次項も参照)。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
72 |
"犬 \dog" とすればいいという意見もありますが、\d がメタ文字として特別意味がないためにうまくいくのであって(Perl 5.6以降では、警告 Unrecognized escape \d passed through 「認識できないエスケープ \d が渡された」を引き起こします)、例えば "花 \flower" のときは、\f が改ページ文字として解釈され、文字化けします。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
73 |
Possible unintended interpolation of @dog in string (Perl 5.6.1以降) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
74 |
文字列の中で、@dogが予期せずに展開される |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
75 |
前項と同じく、"犬 dog" ですが、Perl 5.6.1(ActivePerl 626)以降では、定義されていない配列でも黙って展開します。配列 @dog が展開されるので、"犬\x81" と同じになります。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
76 |
これはエラーではなく、警告になります。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
77 |
Can't find string terminator '"' anywhere before EOF |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
78 |
「終端文字 '"'がファイルの終り EOF までに見つからなかった」 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
79 |
例えば、"対応表" のようなリテラルでは、'表' の第2バイトが \ であるため、うしろの " をエスケープしてしまいます。このためperlは、その " はクオート文字列の終端文字とはみなさずに、文字列がさらに続くと考えてしまいます。これ以降、スクリプトの中に " の文字が全く含まれなければ、このようにエラー報告をします。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
80 |
qq{ "日本語" }のような場合にも注意しなければなりません。"本" の第二バイトは { なので、このままでは { }のネストがずれてしまい、同様のエラーが発生します。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
81 |
Bareword found where operator expected |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
82 |
「裸の語が演算子があってほしい位置に見つかった」 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
83 |
例えば、print "<img alt=\"対応表\" height=115 width=150>"; のような場合、\" による引用符のエスケープは、表 の第2バイトの\のため、\\ " という組み合わせになり、エスケープが打ち消されています。そのため、このリテラルは、perlから見ると、"<img alt=\"対応表\" で終わっています。そのため、リテラルの後に、height という「裸の語」(クオートで囲まれていない文字列)があるようにみて、ここには裸の語ではなく、演算子があるべきではないか?とperlは考えます。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
84 |
Unrecognized character \x82 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
85 |
「認識されない文字 \x82」 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
86 |
これは、非ASCII文字やその他の文字を「裸の語」にしたときに出るメッセージです。"対応表" のようなリテラルがあって、そのあとに "なんでもいいけど" のようなリテラルがあったとき、前例と同じ理由から起こるものです。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
87 |
また、q{マッチ} のような場合にも、'マ' の第二バイトが } なので、{ } のカッコはそこで終わってしまい、同様なエラーになります。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
88 |
マッチしないはずなのにマッチする(1) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
89 |
"ヤカン" =~ /ポット/ はマッチします。それは、'ポ' の第二バイトが | なので、/ポット/ は /\x83|ット/ とみなされ、\x83 だけマッチすればよいからです。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
90 |
マッチしないはずなのにマッチする(2) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
91 |
"兄弟" =~ /Z/ はマッチします。それは、'兄' の第二バイトが 'Z' だからです。第二バイトがアルファベットになる文字には注意が必要です。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
92 |
マッチするはずなのにマッチしない(1) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
93 |
"運転免許" =~ /運転/ はマッチしません。それは、'運' の第二バイトが '^'なので、/運転/ は /\x89^転/ とみなされ、文字列の始め ^ の前に \x89 はないからです。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
94 |
Search pattern not terminated |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
95 |
「サーチパターンが終了しない」 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
96 |
これは、/表/ のように、第二バイトが \ である文字でサーチパターンを終わらせようとしたときに起こります。マッチ演算子の終端文字 / をエスケープしてしまうので、サーチパターンがさらに先に続くように解釈されます。その先にもう一度/はありますか? |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
97 |
あったところで、別のエラーが発生するでしょう。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
98 |
Substitution replacement not terminated |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
99 |
「置換操作の置換文字列が終了しない」 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
100 |
置換演算子は s/PATTERN/REPLACEMENT/の形式をとらねばなりません。しかし s/表/裏/; のように、第二バイトが \ である文字でPATTERN部分を終わらせようとしたときにこのエラーが起こります。マッチ演算子の終端文字 / をエスケープしてしまうので、PATTERNがさらに先に続くように解釈されます。そのためperlは、PATTERNは 表/裏 の部分であると考え、3番目の/の先にREPLACEMENT部分があるに違いないと思うのですが、その先にもう一度/はありますか? |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
101 |
あったところで、別のエラーが発生するでしょう。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
102 |
unmatched [ ] in regexp |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
103 |
「正規表現にマッチしない [ ] がある」 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
104 |
例えば、/プール/ ではエラーが起こります。それは 'ー' の第二バイトが [ なので、/プール/ は /プ\x81[\x83\x8B/ とみなされ、perlは文字クラスがあるのではないかと思います。しかし文字クラスの終了を示す ] が見つからないのでエラーになります。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
105 |
エラーにはならないけど文字化けする(5) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
106 |
例えば、lc('アイウエオ')は、'ヂツテトナ'を返します。Shift-JISの2バイト文字の中には、第2バイトがASCIIで英字に当たるものがあります。詳しくはアルファベットの大文字と小文字をご覧下さい。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
107 |
エラーや間違いを防ぐ対策 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
108 |
以上のようなエラーを防ぐにはさまざまな方法が考えられます。例えば、"表\示" と書けばいいなどという提案があります。もちろんそれでもかまいません。しかしそのためにはどの文字の後に \ を入れればいいかを知る必要があります。それは文字コード表を見れば一発で明らかです。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
109 |
…などという面倒なことが苦にならない人、文字コード表なんか(少なくとも問題になるような文字くらいは)暗記してしまえばいいというような人にとっては、確かにそれで解決になると思います。しかし、そのような人には、こんなページを見にくる必要もヒマもないでしょう。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
110 |
そこで、このようなページをわざわざ見にくるような人は、文字コード表をいちいち調べたくないひとだと仮定します。別にそうだからといって非難されることはありません。しかし、手間を惜しむあまり間違ったプログラムを平気で作っていては、顔にクリームパイをぶつけられても仕方ありません。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
111 |
文字列リテラルの作り方 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
112 |
よく知っておかねばならないことは、\ というエスケープ用の文字は、変数展開やメタ文字の解釈よりずっと前の段階でさまざまな影響を及ぼすということです。そのため、どうしたらデータを確実に変数の中に収められるかを考える必要があります。変数の内部に収めてしまえば、Perlがデータを適切に管理してくれます。よく知られている $str = "表示" の文字化けも、変数$strに代入する以前、ダブルクォートで囲んだ時点ですでに文字化けしていると考えるべきです。すでに文字化けしたデータを代入して、好い結果が得られるはずがありません。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
113 |
ヒアドキュメントは安全性の高い解決法です。ただし、終端文字列をシングルクォートで囲んでやらなくてはなりません。ダブルクォートで囲んだり、クォートを付けなかったりでは、予期せぬ変数展開やメタ文字の解釈を防ぐことができません。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
114 |
シングルクォートで終端文字列を囲んだヒアドキュメントでは、変数展開やメタ文字の解釈は何も起こりません。ただ、終端文字列(この場合は "\nEOF\n")を探すことだけを行います。ヒアドキュメントを使うと文字列に改行文字がつきますが、chompで除くといいでしょう。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
115 |
次の例は $str = 'ここにテキストを書く' と同じように働きますが、文字列の内容によって問題が起こりません。書いたとおりにリテラルを代入できると期待できます。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
116 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
117 |
chomp($str = << 'EOF'); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
118 |
ここにテキストを書く |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
119 |
EOF |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
120 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
121 |
$src = << 'EOF'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
122 |
$path = "C:\\path\\file"; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
123 |
open FH, $path; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
124 |
EOF |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
125 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
126 |
多くの文字列を一度に作りたければ、splitで分割すると容易に作れます。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
127 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
128 |
($name, $career, $age, $memo) = split "\n", << 'EOF'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
129 |
田中一郎 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
130 |
プログラマ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
131 |
三十五 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
132 |
大福が好物である。 酒はあまり呑まない。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
133 |
EOF |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
134 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
135 |
もう少し簡潔に書きたければ、空白文字、\(2バイト文字に含まれているのは構わない)、およびカッコを含まないという条件で、qw() を使うことができます。例えば、@str = qw(表示 対応表 );のように空白を入れてカッコのエスケープを防ぎます。@str = qw(表示 対応表);のように空白を入れないとエラーの元です。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
136 |
1つの文字列を作る時でも、左辺を丸カッコで囲んでリストコンテキストを示すか、右辺をスライスにするかしなければなりません。これは、(現状では)qw// は split(' ', q//) の略記として実装しているからです。なお、Perl 5.6ではリストと等価になっているようです。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
137 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
138 |
($str) = qw(百三十 ); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
139 |
$str = (qw/百三十 /)[0]; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
140 |
$str = qw/百三十 /; # Perl 5.6 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
141 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
142 |
正規表現とマッチ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
143 |
正規表現のメタ文字は多いので、正規表現の中にShift-JISの文字列を埋めこむのは得策ではありません。例えば、/\Q対応表/ ではエラーになります。これは、/ / の範囲の決定が真っ先に行われ、その時点でエラーが発生するので、\Q の効果を及ぼすことができないからです。また、/\Q対応表\E/ は巧く行きません。これは、対応表\E という文字列を含むものにしかマッチしません。これは、\\ という連続があるため、\E が認識されないからでしょう(たぶん)。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
144 |
そのため、変数に入れて、マッチ演算子や置換演算子の中で展開させるとよろしいです。このとき日本語文字列は予めquotemeta 関数で処理しておきます。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
145 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
146 |
$pat = quotemeta +(qw/ 表 /)[0]; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
147 |
$str =~ /$pat\d+/; # 表1, 表2, ..などにマッチ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
148 |
# しかし $str = '剣\\1' でもマッチする(この問題は後述) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
149 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
150 |
上のような書き方は確かに醜いですね。クオートの中で \Q \E を使う時は、正しい文字列が入っている変数と一緒になら問題が起こりません。こうすることで、\Q \E の範囲が明確になるからです。正しい文字列の作り方は、前述のリテラルの作りかたを参考にして下さい。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
151 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
152 |
$pat = "(?:\Q$str1\E|\Q$str2\E)*"; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
153 |
$str =~ /$pat/; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
154 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
155 |
# 実は上の文は次の文と等価。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
156 |
# $pat = "(?:" . quotemeta($str1) . "|" . quotemeta($str2) . ")*"; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
157 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
158 |
リテラルをクォートの中に直接埋めこむとうまく行かないことがあります。それは、perlが \E というメタ文字を発見しようというのを、Shift-JIS文字が妨げるためです。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
159 |
"\Q表\E"では、表Eにマッチする正規表現になります。表の第二バイトの \ と次の \が合わさるので、perlには\Q \x95 \\ Eの組み合わせであるように思われます。 \Qの作用の結果は\\x95\\x5cEになります。そのため、表Eにマッチします。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
160 |
"\Q表"はどうでしょう。この場合は、" " の範囲を決めるときに、表の第二バイトが後のクォートをエスケープしてしまうので、文字列の範囲が期待したようには定まらず、エラーになります。このエラーは\Qの効果を考慮する前に発生するので、防ぎようがありません。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
161 |
"\Q表\\E"はどうでしょう。確かにShift-JISでは問題ありません。しかし同じスクリプトをEUC-JPやUTF-8に変換したときには問題があります。表\Eと余分な2文字がある文字列でないとマッチしません。どちらにしろ、\をどこに添えるかを考える必要があるので、ここの趣旨に合いません。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
162 |
正規表現は例えば、次のようにします。もちろんこれはShift-JISのみに有効です。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
163 |
$digit = '(?:[0-9]|\x82[\x4F-\x58])'; # 数字(半角と全角) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
164 |
$upper = '(?:[A-Z]|\x82[\x60-\x79])'; # アルファベット大文字(半角と全角) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
165 |
$lower = '(?:[a-z]|\x82[\x81-\x9A])'; # アルファベット小文字(半角と全角) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
166 |
$space = '(?:[\ \n\r\t\f]|\x81\x40)'; # 空白文字(半角と全角) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
167 |
$ascii = '[\x00-\x7F]'; # ASCII文字 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
168 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
169 |
# 全角平仮名(濁点・半濁点・踊り字を含む) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
170 |
$hiraZ = '(?:\x82[\x9F-\xF1]|\x81[\x4A\x4B\x54\x55])'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
171 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
172 |
# 全角片仮名(長音符・濁点・半濁点・踊り字を含む) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
173 |
$kataZ = '(?:\x83[\x40-\x7E\x80-\x96]|\x81[\x5B\x4A\x4B\x52\x53])'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
174 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
175 |
# 半角片仮名(半角長音符・句読点を含む) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
176 |
$kataH = '[\xA1-\xDF]'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
177 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
178 |
$onebyte = '[\x00-\x7F\xA1-\xDF]'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
179 |
$twobyte = '(?:[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
180 |
$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
181 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
182 |
# JIS文字 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
183 |
$all_JIS = '(?:[\x00-\x7f\xa1-\xdf]|'. |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
184 |
. '\x81[\x40-\x7e\x80-\xac\xb8-\xbf\xc8-\xce\xda-\xe8\xf0-\xf7\xfc]|' |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
185 |
. '\x82[\x4f-\x58\x60-\x79\x81-\x9a\x9f-\xf1]|' |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
186 |
. '\x83[\x40-\x7e\x80-\x96\x9f-\xb6\xbf-\xd6]|' |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
187 |
. '\x84[\x40-\x60\x70-\x7e\x80-\x91\x9f-\xbe]|' |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
188 |
. '\x88[\x9f-\xfc]|\x98[\x40-\x72\x9f-\xfc]|\xea[\x40-\x7e\x80-\xa4]|' |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
189 |
. '[\x89-\x97\x99-\x9f\xe0-\xe9][\x40-\x7e\x80-\xfc])'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
190 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
191 |
# ベンダ定義文字 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
192 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
193 |
# NEC特殊文字 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
194 |
$NEC_special = '(?:\x87[\x40-\x5d\x5f-\x75\x7e\x80-\x9c])'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
195 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
196 |
# NEC選定IBM拡張文字 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
197 |
$NEC_IBM_ext = '(?:\xed[\x40-\x7e\x80-\xfc]|\xee[\x40-\x7e\x80-\xec\xef-\xfc])'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
198 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
199 |
# IBM拡張文字 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
200 |
$IBM_ext = '(?:[\xfa-\xfb][\x40-\x7e\x80-\xfc]|\xfc[\x40-\x4b])'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
201 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
202 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
203 |
Shift-JISでマッチを行う時には、2つの問題があります。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
204 |
第二バイトがASCIIの領域に入る文字があるので、ASCIIを含むパターンにマッチする可能性がある。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
205 |
ある文字の第二バイトと次の文字の第一バイトが1文字であるかのようにマッチしてしまう。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
206 |
後者はEUC-JPでも起こりうる問題です(UTF-8なら起こらないが、今はそれが問題なのではない)。しかし前者はEUC-JPでは起こらないが、Shift-JISでは起こりうる問題です。これらを防ぐ方法は、結局同じことですが、正規表現の中に、常に先頭を含ませることです。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
207 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
208 |
# 先頭からマッチ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
209 |
$str =~ /^$char*?(?:$pat)/; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
210 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
211 |
末尾からのマッチではうまく行かないことがあります。"右" =~ /E$/を考えれば十分でしょう。また、"\x8E" x 30 . "E"は$str = "試試試試試試試試試試試試試試試E"であるが、"\x8E" x 31 . "E"は$str = "試試試試試試試試試試試試試試試殺"でありますから、Shift-JIS文字列を後ろから切り分ける適切な方法はないと考えられます。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
212 |
少なくとも、2バイト文字を構成しないバイト [\x00-\x3F\x7F] が見つかる所まで、極端な場合は文字列の最初までスキャンしないとわからず、しかも後読み lookbehind の正規表現 (?<=PATTERN)は今の所、不定長にできません((?<=(?:\A|[\x00-\x3F\x7F])$char*) とはできない)ので、先頭から文字単位でばらしてから処理するのが、結局は簡便なのかもしれません。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
213 |
グローバルマッチ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
214 |
グローバルマッチ /g の場合は、\Gを使いましょう。\Gは前回マッチした部分の末尾を指します。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
215 |
次の例では、置換されないのが望ましいのですが、\Gがないので、先頭から開始して文字列全体まで延びてマッチしなかったあと、改めて先頭から1バイト進んだ位置からスキャンを再開するので、ずれた位置なのにマッチしたと考えてしまいます。\Gを使わないと、間違った位置にマッチするかもしれないうえに、余計な再検査をするので、時間もかかります。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
216 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
217 |
$str = '試試試試E試試試試E'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
218 |
$pat = '殺'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
219 |
$str =~ s/\G($char*?)($pat)/${1}E/og; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
220 |
# '試試試試E試試試試E' のまま(正しい)。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
221 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
222 |
\Gを付けない場合 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
223 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
224 |
$str = '試試試試E試試試試E'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
225 |
$pat = '殺'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
226 |
$str =~ s/($char*?)($pat)/${1}E/og; # '殺' があれば 'E' に置換 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
227 |
print $str; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
228 |
# '試試試殺試試試殺' になってしまう(おかしい)。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
229 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
230 |
試試試試E試試試試E |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
231 |
1回目 →→→→/→→→→/ (マッチしない) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
232 |
2回目 |→→→⇒||||||||| (マッチしたので置換) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
233 |
3回目 |||||||||→→→→/ (マッチしない) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
234 |
4回目 ||||||||||→→→⇒ (マッチしたので置換) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
235 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
236 |
凡例: → $charが2バイト文字にマッチ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
237 |
/ $charが1バイト文字にマッチ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
238 |
⇒ $patがマッチ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
239 |
| スキャンの範囲外 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
240 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
241 |
ただし、パターンがゼロ文字幅にマッチする場合には、注意が必要です。次の例は、「ア」の前に 'Z' を入れるものです。第1例は文字のずれ('ア' : 0x8341に対して'泣A' : 0x8B8341がずれてマッチする)を防いでいません。第2例は、上の方法で「ずれ」を防ごうとしたのですが、Z への置換が連続して起こっています。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
242 |
これは第3例のようにする必要があります。これは、第2例では「なぜ?」に書いたように、置換されるからと考えられます。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
243 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
244 |
$str = "アイウエアアイウア泣A"; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
245 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
246 |
print +($temp = $str) =~ s/(?=ア)/Z/g, $temp; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
247 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
248 |
print +($temp = $str) =~ s/\G($char*?)(?=ア)/${1}Z/g, $temp; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
249 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
250 |
print +($temp = $str) =~ s/\G(\A|$char+?)(?=ア)/${1}Z/g, $temp; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
251 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
252 |
結果 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
253 |
5 ZアイウエZアZアイウZア技ア |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
254 |
7 ZアイウエZZアZZアイウZZア泣A |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
255 |
4 ZアイウエZアZアイウZア泣A |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
256 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
257 |
なぜ? |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
258 |
ア イ ウ エ ア ア イ ウ ア 泣 A |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
259 |
1 \G Z |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
260 |
2 \G$char$char$char$char Z |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
261 |
3 \G Z |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
262 |
4 \G$char Z |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
263 |
5 以下、省略 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
264 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
265 |
つまり、グローバルマッチでは、マッチがゼロ文字幅でないパターンの前には\G($char*?)を、ゼロ文字幅であるパターンの前には\G(\A|$char+?)を入れる必要があります。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
266 |
ただし、これでも正しく(?)マッチさせられない場合があります。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
267 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
268 |
$str = "0123000123"; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
269 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
270 |
print +($temp = $str) =~ s/0*/Z/g, $temp; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
271 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
272 |
print +($temp = $str) =~ s/\G($char*?)0*/${1}Z/g, $temp; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
273 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
274 |
print +($temp = $str) =~ s/\G(\A|$char+?)0*/${1}Z/g, $temp; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
275 |
__END__ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
276 |
9 ZZ1Z2Z3ZZ1Z2Z3Z |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
277 |
14 ZZ1ZZ2ZZ3ZZ1ZZ2ZZ3ZZ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
278 |
7 Z1Z2Z3Z1Z2Z3Z |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
279 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
280 |
これは、パターンがゼロ文字幅にマッチするものであると、/gがその場で無限に足踏みして終了しなくなるのを防ぐため、perlは、マッチを強制的に進めているのですが(cf. perlre, Repeated patterns matching zero-length substring)、この進め方の真似(しかもバイト単位ではなく、文字単位で進むもの)が、\G($char*?)や\G(\A|$char+?)では、うまくできないからです。もっともこういうマッチをすることは、ほとんどないと考えられますので、気にする必要はないのかも知れません(<負け惜しみ)。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
281 |
アルファベットの大文字と小文字 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
282 |
Shift-JISの2バイト文字の中には、第2バイトがASCIIで英字に当たるものがあります。そのため、関数 uc, lc や、メタ文字 \U, \Lが2バイト文字の一部を変換してしまったり(しかし関数 ucfirst, lcfirst や メタ文字 \u, \l は問題とならない)、m//i や s///iなどの /i修飾子によって違う文字なのにマッチしてしまったりすることがあります。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
283 |
Shift-JIS文字列に含まれるASCIIの英字を大文字または小文字に揃えたいなら、例えば、次のようなサブルーチンを作れば実現できます。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
284 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
285 |
$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
286 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
287 |
lc("PERLプログラミング"); # 'perlプロバラミンバ' |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
288 |
tolower("PERLプログラミング"); # 'perlプログラミング' |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
289 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
290 |
sub tolower { |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
291 |
my $str = $_[0]; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
292 |
$str =~ s/\G($char*?)([A-Z]+)/$1\L$2/g; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
293 |
$str; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
294 |
} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
295 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
296 |
sub toupper { |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
297 |
my $str = $_[0]; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
298 |
$str =~ s/\G($char*?)([a-z]+)/$1\U$2/g; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
299 |
$str; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
300 |
} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
301 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
302 |
ケース無視のマッチ /i の場合は、例えば 'エ'の第二バイトは 'G' であり、'ト'の第二バイトは 'g' であることから、'エ' =~ /ト/iはマッチします。ですから、Shift-JISで正確なマッチをしたければ、/i修飾子は使うことができません。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
303 |
かわりに、文字列に含まれるアルファベット(二バイト文字の第2バイトにあるものを除く)を小文字(または大文字、どちらか)に統一してマッチさせます。tolowerの定義は上をご覧下さい。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
304 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
305 |
$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
306 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
307 |
$lcstr = tolower($str); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
308 |
$lckey = tolower(quotemeta $key); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
309 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
310 |
if ($lcstr =~ /^$char*?$lckey/) { |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
311 |
print "matched"; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
312 |
} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
313 |
else { |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
314 |
print "not matched"; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
315 |
} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
316 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
317 |
または埋め込み修飾子 (?ismx-ismx) を用いても好い結果を得られます。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
318 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
319 |
"第1回Perl講縮のご案内" =~ /^$char*?PERL講習/i # マッチする(困る) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
320 |
"第2回Perl講縮のご案内" =~ /^$char*?((?i)PERL)講習/ # マッチしない(良し) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
321 |
"第3回Perl講習のご案内" =~ /^$char*?((?i)PERL)講習/ # マッチする(良し) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
322 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
323 |
全角2バイトアルファベットのケース無視は、選択により実現できます(が、やっぱり変)。'A'の第2バイトが '`' なのも、ちょっと注意です(m`` などのとき致命的エラーになる。ただしバッククォートを使う意味は特にない)。原則的にはリテラルをマッチ演算子や置換演算子に直接埋め込むのは避けたい所です。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
324 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
325 |
/(?:P|p)(?:E|e)(?:R|r)(?:L|l)/; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
326 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
327 |
その代わりにこんなサブルーチンを作ってみてもよいかもしれません。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
328 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
329 |
$CharRE = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
330 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
331 |
$pat = make_regexp_ignorecase("PERL講習"); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
332 |
print "第5回Perl講習会" =~ /^$char*?$pat/ ? "OK": "NOT"; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
333 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
334 |
sub make_regexp_ignorecase { |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
335 |
my $str = $_[0]; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
336 |
$str =~ s/\G([A-Za-z]+|$CharRE)/ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
337 |
my $c = ord $1; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
338 |
if($c == 0x82) { |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
339 |
my $v = vec($1,1,8); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
340 |
0x81 <= $v && $v <= 0x9A ? sprintf('\\x82[\\x%2x\\x%2x]', $v, $v-33) : |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
341 |
0x60 <= $v && $v <= 0x79 ? sprintf('\\x82[\\x%2x\\x%2x]', $v, $v+33) : |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
342 |
quotemeta($1); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
343 |
} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
344 |
elsif(0x41 <= $c && $c <= 0x5A || 0x61 <= $c && $c <= 0x7A) {"(?:(?i)$1)"} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
345 |
else {quotemeta($1)} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
346 |
/geo; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
347 |
$str; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
348 |
} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
349 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
350 |
長い文字列に対する正規表現検索 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
351 |
正規表現は、Perl にとって欠かせない存在といえます。しかし正規表現の制限として、*, +, {min,max} などの量指定子がマッチを繰り返せる回数の上限という問題があります。(詳細は perlre 参照のこと)。そのため、$char*? という正規表現には、危険性があります。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
352 |
例えば、次のようなマッチングを考えて見ましょう。$strは、「あ」が10万字連続したあとに、「アイABC」が連結された文字列です。このような文字列(ただし、「『あ』が10万字連続」ということは分からず、任意の Shift-JIS テキストであろうということにします)から、半角アルファベットが連続した部分を見つけたいとしましょう。すると、今までの考え方からすると、次のようにすればよいと思われます。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
353 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
354 |
my $char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
355 |
my $str = ('あ' x 100000) . 'アイABC'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
356 |
$str =~ /^$char*?([A-Z]+)/o; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
357 |
print $1; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
358 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
359 |
しかし、これは、環境によっては、大きなエラーを引き起こします。例えば、Windows 98上で Active Perl 522 を用いた場合、Error: Runtime exception という Perl のエラーになりました。また、Windows 98上でVC++ 6.0でコンパイルされた Perl 5.6.1 だと、「このプログラムは不正な処理を行ったので強制終了されます。〜」などといったエラーになりました。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
360 |
このような問題をできるだけ防ぐためには、次のようにします。つまり、文字列の先頭から調べていく場合、二バイト文字の文字境界を間違えるのは、二バイト文字の第一バイトの直後を文字境界と誤認識した時だけです。Shift-JISでは、二バイト文字の第一バイトは、[\x81-\x9F\xE0-\xFC] だけです。あるいは、EUC-JP に変換可能な領域だけを考慮すれば、[\x81-\x9F\xE0-\xEF] だけということができます。それ以外のバイトの直後は、例えば、0x41 の直後は、'A' の直後か、'ア' の直後かは分かりませんが、確かに文字境界になります。従って、[\x81-\x9F\xE0-\xFC]+ (または [\x81-\x9F\xE0-\xEF]+ )のバイト(二バイト文字)が連続するところだけに注意すればよいことになります。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
361 |
このため、以下のように、^$char*? の代わりに $Apad を使い、\G$char*? の代わりに $Gpad を用いれば、一バイト文字か、二バイト文字のうち第二バイトが [\x40-\x7E\x80\xA0-\xDF] で終わるものが、少なくとも適当な間隔で(上限に達しないうちに)出現すれば、エラーにならずに処理することができます。(確率的な問題ですので、完全ではありません。) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
362 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
363 |
# 一回だけマッチ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
364 |
my $Apad = '(?:(?:\A|[\x00-\x80\xA0-\xDF])(?:[\x81-\x9F\xE0-\xFC]{2})*?)'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
365 |
my $str1 = ('あ' x 100000) . 'アイABC'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
366 |
$str1 =~ /$Apad([A-Z]+)/o; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
367 |
print "$1\n"; # "ABC" と表示される。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
368 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
369 |
# グローバルマッチ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
370 |
my $Gpad = '(?:(?:\G|[\x00-\x80\xA0-\xDF])(?:[\x81-\x9F\xE0-\xFC]{2})*?)'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
371 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
372 |
my $str2 = 'あ' x 100000 . 'アイABC'. 'お' x 100000 . 'XYZ'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
373 |
my @array = $str2 =~ /$Gpad([A-Z]+)/go; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
374 |
print "@array\n"; # "ABC XYZ" と表示される。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
375 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
376 |
外字の変換 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
377 |
ベンダ定義文字やユーザ定義文字を含む文字列を他の環境でも利用できるようにするには、適切な変換が必要です(無論、まったく同じ字体の利用はほとんど望めず、おそらくは類似した文字や文字列に変換することになるでしょう)。これはPerlでは置換演算子 s/// を使えば比較的容易に実現できます。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
378 |
あらかじめ、どの外字をどう変換するかを定義する変換テーブルを用意しなくてはなりません。これはPerlではハッシュにしておくとその後の処理が楽になります。ここでは、'w932_gai.txt'で定義する、Windows codepage-932コードに基づいた機種依存文字の(部分的)変換テーブルを使うことにします。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
379 |
次のコードでは、1文字づつマッチさせ、その文字が変換ハッシュのキーにあれば対応する値の文字列に置換し、そうでなければそのまま残します。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
380 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
381 |
require 'w932_gai.txt'; # %tableの定義(不完全!) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
382 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
383 |
$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
384 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
385 |
$str =~ s/($char)/exists $table{$1} ? $table{$1} : $1/geo; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
386 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
387 |
同様な処理は、つぎのような書き方でもできますが、外字にマッチする正規表現 $gaijiを用意する必要があります。ずれたマッチをしないために、こちらの正規表現には \G が必要です。例えば、$str = '∞@';の後ろ2バイトは "\x87\x40" ですが、こうすればマッチがずれる心配がありません。また、非欲張りマッチ ($char*?)を使えば $char が外字にマッチしないよう変更する必要はありません。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
388 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
389 |
require 'w932_gai.txt'; # %tableの定義(不完全!) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
390 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
391 |
$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
392 |
$gaiji = '(?:[\x87][\x40-\x9c])'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
393 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
394 |
$str =~ s/\G($char*?)($gaiji)/$1$table{$2}/g; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
395 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
396 |
CP932重複定義文字の変換 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
397 |
Microsoft Windows 日本語版で一般的に使用されているコードページ 932 (CP932) では、幾つかの文字が重複して定義された状態になっています。ここで、文字が重複定義されているとは、Unicodeの同じ符号位置に対応付けられていることとします。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
398 |
例えば、CP932 -> Unicode -> CP932 の順で変換されると、重複定義文字は、どれか一つに揃えられます。この優先順位は JIS X 0208, NEC特殊文字 (13区)、IBM拡張文字 (115〜119区)、NEC選定IBM拡張文字 (89〜92区) の順です。一例として、'∵' の場合、NEC特殊文字の "\x87\x9A" や IBM拡張文字の "\xFA\x5B" は、JIS X 0208 の "\x81\xE6" になります。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
399 |
しかし、CP-932 のテキスト中、重複定義文字がどれかに揃っていないことがあります。例えば "\x87\x9A" や "\xFA\x5B" が含まれていると、テキストを目で見ると違いがないのに、"\x81\xE6" で検索しても見つけられないことになります。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
400 |
重複定義文字を揃えるモジュールとして、ShiftJIS/CP932/Correct.pm があります。入手と使い方はPerlのページに戻れば見つかります。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
401 |
また、ShiftJIS/String.pm の strtr() または trclosure() を使う方法もあります。入手と使い方はPerlのページに戻れば見つかります。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
402 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
403 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
404 |
# (1) $necJIS -> $jisNEC (9対) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
405 |
$necJIS = "\x87\x90\x87\x91\x87\x92\x87\x95\x87\x96\x87\x97\x87\x9A\x87\x9B\x87\x9C"; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
406 |
# NEC特殊文字のうち、JIS文字に変換されるべき非漢字 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
407 |
$jisNEC = "\x81\xE0\x81\xDF\x81\xE7\x81\xE3\x81\xDB\x81\xDA\x81\xE6\x81\xBF\x81\xBE"; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
408 |
# JIS文字のうち、NEC特殊文字に重複定義されている非漢字 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
409 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
410 |
# (2) $necibmJIS -> $jisNECIBM (1対) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
411 |
$necibmJIS = "\xEE\xF9"; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
412 |
# NEC選定IBM拡張文字のうち、JIS文字に変換されるべき非漢字 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
413 |
$jisNECIBM = "\x81\xCA"; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
414 |
# JIS文字のうち、NEC選定IBM拡張文字に重複定義されている非漢字 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
415 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
416 |
# (3) $ibmJIS -> $jisIBM (2対) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
417 |
$ibmJIS = "\xFA\x54\xFA\x5B"; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
418 |
# IBM拡張文字のうち、JIS文字に変換されるべき非漢字 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
419 |
$jisIBM = "\x81\xCA\x81\xE6"; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
420 |
# JIS文字のうち、IBM拡張文字に重複定義されている非漢字 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
421 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
422 |
# (4) $ibmNEC -> $necIBM (13対) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
423 |
$ibmNEC = "\xFA\x4A-\xFA\x53\xFA\x58\xFA\x59\xFA\x5A"; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
424 |
# IBM拡張文字のうち、NEC特殊文字に変換されるべき非漢字 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
425 |
$necIBM = "\x87\x54-\x87\x5D\x87\x8A\x87\x82\x87\x84"; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
426 |
# NEC特殊文字のうち、IBM拡張文字に重複定義されている非漢字 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
427 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
428 |
# (5) $necibmIBM -> $ibmNECIBM (13対) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
429 |
$necibmIBM = "\xEE\xEF-\xEE\xF8\xEE\xFA\xEE\xFB\xEE\xFC"; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
430 |
# NEC選定IBM拡張文字のうち、IBM拡張文字に変換されるべき非漢字 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
431 |
$ibmNECIBM = "\xFA\x40-\xFA\x49\xFA\x55\xFA\x56\xFA\x57"; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
432 |
# IBM拡張文字のうち、NEC選定IBM拡張文字に重複定義されている非漢字 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
433 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
434 |
# (6) $necibmCJK -> $ibmCJK (360対) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
435 |
$necibmCJK = "\xED\x40-\xEE\xEC"; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
436 |
# NEC選定IBM拡張文字中の漢字 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
437 |
$ibmCJK = "\xFA\x5C-\xFC\x4B"; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
438 |
# IBM拡張文字中の漢字 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
439 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
440 |
use ShiftJIS::String qw(trclosure); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
441 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
442 |
# 変換用クロージャの生成 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
443 |
$correctCP932 = trclosure( |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
444 |
$necJIS.$necibmJIS.$ibmJIS.$ibmNEC.$necibmIBM.$necibmCJK, # from |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
445 |
$jisNEC.$jisNECIBM.$jisIBM.$necIBM.$ibmNECIBM.$ibmCJK # to |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
446 |
); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
447 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
448 |
$result = $correctCP932->($source); # $source を変換して $result を得る |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
449 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
450 |
文字数を数える |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
451 |
Shift-JIS文字列の文字数を数えるには、マッチ演算子を利用するならスカラーコンテキストで数えた方が若干速かったです。それより、置換演算子を利用したほうが速く書けるとわかりました。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
452 |
もっともXSで書いたほうがずっと速かったです。まあ、XSUBは無理に利用しなくてもよいでしょう。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
453 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
454 |
use Benchmark; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
455 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
456 |
$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
457 |
$s = "漢字あ\0AアCテスト -"; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
458 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
459 |
timethese (100000, { |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
460 |
le => q{ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
461 |
($str = $s) =~ s/$char/0/go; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
462 |
$le = length $str; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
463 |
}, |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
464 |
sg => q{ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
465 |
$sg = ($str = $s) =~ s/$char//go; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
466 |
}, |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
467 |
ab => q{ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
468 |
$ab = 0; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
469 |
$ab++ while $s =~ /[^\x81-\x9F\xE0-\xFC]|../g; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
470 |
}, |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
471 |
ar => q{ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
472 |
$ar = @{[ $s =~ /$char/go ]}; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
473 |
}, |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
474 |
gr => q{ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
475 |
$gr = grep defined, $s =~ /$char/go; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
476 |
}, |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
477 |
wh => q{ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
478 |
$wh = 0; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
479 |
$wh++ while $s =~ /$char/go; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
480 |
}, |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
481 |
sj => q{ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
482 |
$sj = sjslen($s); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
483 |
}, |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
484 |
xs => q{ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
485 |
$xs = sjlength($s); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
486 |
}, |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
487 |
}); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
488 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
489 |
sub sjslen { |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
490 |
my($str,$len,$i,$c,$blen); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
491 |
$str = shift; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
492 |
$blen = length $str; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
493 |
while ($i < $blen) { |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
494 |
$c = vec($str, $i, 8); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
495 |
if (0x81 <= $c && $c <= 0x9F || 0xE0 <= $c && $c <= 0xFC){ $i++ } |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
496 |
$i++,$len++; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
497 |
} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
498 |
$len; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
499 |
} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
500 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
501 |
結果 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
502 |
Benchmark: timing 100000 iterations of ab, ar, gr, le, sg, sj, wh, xs... |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
503 |
ab: 4 wallclock secs ( 3.46 usr + 0.00 sys = 3.46 CPU) @ 28901.73/s |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
504 |
ar: 6 wallclock secs ( 5.98 usr + 0.00 sys = 5.98 CPU) @ 16722.41/s |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
505 |
gr: 6 wallclock secs ( 5.50 usr + 0.00 sys = 5.50 CPU) @ 18181.82/s |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
506 |
le: 3 wallclock secs ( 2.09 usr + 0.00 sys = 2.09 CPU) @ 47846.89/s |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
507 |
sg: 2 wallclock secs ( 1.92 usr + 0.00 sys = 1.92 CPU) @ 52083.33/s |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
508 |
sj: 9 wallclock secs ( 8.57 usr + 0.00 sys = 8.57 CPU) @ 11668.61/s |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
509 |
wh: 5 wallclock secs ( 4.78 usr + 0.00 sys = 4.78 CPU) @ 20920.50/s |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
510 |
xs: 1 wallclock secs ( 0.38 usr + 0.00 sys = 0.38 CPU) @ 263157.89/s |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
511 |
(warning: too few iterations for a reliable count) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
512 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
513 |
XSUB |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
514 |
int |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
515 |
sjlength(arg) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
516 |
SV* arg |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
517 |
PROTOTYPE: $ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
518 |
PREINIT: |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
519 |
unsigned char *str, *p, *e; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
520 |
STRLEN byte, len = 0; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
521 |
CODE: |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
522 |
p = str = (unsigned char *)SvPV(arg, byte); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
523 |
e = str + byte; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
524 |
while (p < e) { |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
525 |
if (0x81 <= *p && *p <= 0x9F || 0xE0 <= *p && *p <= 0xFC) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
526 |
++p; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
527 |
++p, ++len; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
528 |
} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
529 |
RETVAL = len; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
530 |
OUTPUT: |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
531 |
RETVAL |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
532 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
533 |
文字単位に分ける |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
534 |
Shift-JIS文字列を文字単位に分割しましょう。この場合は、XSを利用してもあまり速くなりませんでした。返り値のリストを用意するのに時間が取られるのか、やはりPerlの正規表現の処理はかなり速いものだということでしょう。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
535 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
536 |
use Benchmark; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
537 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
538 |
$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
539 |
$s = "日本語ニホンゴ\0ABC" x 100; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
540 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
541 |
timethese (1000, { |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
542 |
re => q{ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
543 |
@re = $s =~ /$char/go; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
544 |
}, |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
545 |
xs => q{ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
546 |
@xs = sjsplit($s); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
547 |
}, |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
548 |
}); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
549 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
550 |
結果 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
551 |
Benchmark: timing 1000 iterations of re, xs... |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
552 |
re: 7 wallclock secs ( 6.65 usr + 0.00 sys = 6.65 CPU) @ 150.38/s |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
553 |
xs: 6 wallclock secs ( 5.33 usr + 0.00 sys = 5.33 CPU) @ 187.62/s |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
554 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
555 |
XSUB |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
556 |
void |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
557 |
sjsplit(arg) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
558 |
SV* arg |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
559 |
PROTOTYPE: $ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
560 |
PREINIT: |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
561 |
unsigned char *str, *p, *e; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
562 |
STRLEN ch, byte, len = 0; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
563 |
PPCODE: |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
564 |
str = (unsigned char *)SvPV(arg,byte); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
565 |
e = str + byte; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
566 |
for (p = str; p < e; p++) { |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
567 |
if (0x81 <= *p && *p <= 0x9F || 0xE0 <= *p && *p <= 0xFC) ++p; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
568 |
++len; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
569 |
} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
570 |
EXTEND(SP,len); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
571 |
for (p = str; p < e; p += ch) { |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
572 |
ch = (0x81 <= *p && *p <= 0x9F || 0xE0 < *p && *p <= 0xFC) ? 2 : 1; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
573 |
PUSHs(sv_2mortal(newSVpv(p,ch))); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
574 |
} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
575 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
576 |
色々な分割 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
577 |
文字で分割でみたように、文字列を分割するには、m//gが便利です。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
578 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
579 |
$onebyte = '[\x00-\x7F\xA1-\xDF]'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
580 |
$twobyte = '(?:[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
581 |
$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
582 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
583 |
#1バイト文字の塊と2バイト文字の塊に分ける。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
584 |
while ($str =~ /\G($onebyte*)($twobyte*)/g) { |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
585 |
push @one, $1 if $1 ne ''; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
586 |
push @two, $2 if $2 ne ''; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
587 |
} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
588 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
589 |
#句点が最後の文字となるように分割する。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
590 |
# '。' ではいいが、文字によっては注意が必要。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
591 |
@sentences = $str =~ /\G$char*?(?:。|.|$)/g; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
592 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
593 |
特定の長さで切りそろえる |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
594 |
長い文字列を特定の長さ(バイト長)で切りそろえるなら、次のようにしてできます。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
595 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
596 |
$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
597 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
598 |
$str = 'わざわざEUC-JPに変換しないで、Shift-JISのまま処理'. |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
599 |
'できたらいいんだけど、なかなか面倒だねえ。'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
600 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
601 |
print join "\n", bytebreak($str,15); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
602 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
603 |
sub bytebreak{ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
604 |
my($byte,$bmax,$ch,@lines); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
605 |
my $str = shift; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
606 |
$byte = $bmax = shift; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
607 |
foreach $ch ($str =~ /$char/go) { |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
608 |
$byte += length $ch; # 次の文字を継ぎ足した長さ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
609 |
if ($byte <= $bmax) { |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
610 |
$lines[-1] .= $ch; # 長すぎなければ継ぎ足す |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
611 |
} else { |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
612 |
$byte = length $ch; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
613 |
push @lines, $ch; # さもなければ次の行へ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
614 |
} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
615 |
} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
616 |
return @lines; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
617 |
# 長さが足らない場合に、右をスペースで埋めたければ。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
618 |
# return map {$_ .= ' ' x ($bmax - length)} @lines; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
619 |
} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
620 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
621 |
禁則処理は、例えば次のようにして行います。単純な考え方では、禁則処理は、(i) 行頭禁則文字の直前で改行しない;(ii) 行末禁則文字の直後で改行しない;ということになります。また、"(a)"のように、行末禁則文字と行頭禁則文字の間に1文字しかない連続した部分は、その部分の全体が無改行になる点にも配慮します。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
622 |
この例では文字列の長さをバイト長 length で規定していますが、文字幅とバイト数は必ずしも比例しませんので、場合によっては(ギリシア文字は半角幅にしたいとか、またはプロポーショナルの場合とか、UTF-8の場合とか)文字幅を返す width のような関数を定義する必要があるでしょう。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
623 |
また、この例のやり方では、禁則による無改行部分だけで一行より長くなる場合は、はみだしを防げません。それが困るなら、禁則の例外として行を分ける(例えば$nextの長さが$bmaxを超えないようにする)処置が必要でしょう。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
624 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
625 |
$CharRE = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
626 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
627 |
# 行頭禁則文字(一部分) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
628 |
$NotAtBegin = q/)]}’”」』)]}!,.:;?、。々゛゜!,.:;?/; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
629 |
# 行末禁則文字(一部分) |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
630 |
$NotAtEnd = q/([{‘“「『([{/; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
631 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
632 |
# ハッシュを作る |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
633 |
@NotAtBegin{$NotAtBegin =~ m/$CharRE/g} = (); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
634 |
@NotAtEnd{ $NotAtEnd =~ m/$CharRE/g} = (); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
635 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
636 |
$Str = 'わざわざEUC-JPに変換しないで、Shift-JISのまま処理'. |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
637 |
'できたらいいんだけど、なかなか面倒だねえ。'; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
638 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
639 |
print join "\n", linebreak($Str,16); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
640 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
641 |
sub linebreak{ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
642 |
my($byte,$i,@chars,$next,@lines); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
643 |
my($str, $bmax, $pad) = @_; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
644 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
645 |
# $byteは次の文字を継ぎ足したときの長さ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
646 |
$byte = $bmax; # すぐ改行できるための初期値。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
647 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
648 |
# 文字単位にばらす |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
649 |
@chars = $str =~ /$CharRE/go; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
650 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
651 |
for ($i=0; $i<@chars; $i++) { |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
652 |
$next .= $chars[$i]; # 次の文字 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
653 |
$byte += length $chars[$i]; # 次の文字を継ぎ足した長さ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
654 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
655 |
# 次の文字が行末禁則のとき |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
656 |
next if $i+1 < @chars && exists $NotAtEnd{ $chars[$i] }; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
657 |
# 次の文字の次が行頭禁則のとき |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
658 |
next if $i+1 < @chars && exists $NotAtBegin{ $chars[$i+1] }; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
659 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
660 |
# 行の振り分け |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
661 |
# 長すぎなければ継ぎ足す |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
662 |
if ($byte <= $bmax) { |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
663 |
$lines[-1] .= $next; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
664 |
} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
665 |
# さもなければ次の行へ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
666 |
else { |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
667 |
push @lines, $next; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
668 |
$byte = length $next;# 新しい行の長さ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
669 |
} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
670 |
$next = ''; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
671 |
} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
672 |
return defined $pad && 1 == length $pad # 詰め物 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
673 |
? map {$_ .= $pad x ($bmax - length)} @lines |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
674 |
: @lines; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
675 |
} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
676 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
677 |
ぶら下がり禁則の場合($bmin から $bmaxの範囲を許す)。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
678 |
$bmin = $bmax - 2; # 例えば。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
679 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
680 |
# 行の振り分け |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
681 |
# 長すぎなければ継ぎ足す |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
682 |
if ($byte <= $bmax && @lines && length $lines[-1] < $bmin){ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
683 |
$lines[-1] .= $next; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
684 |
} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
685 |
# さもなければ次の行へ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
686 |
else { |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
687 |
push @lines, $next; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
688 |
$byte = length $next;# 新しい行の長さ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
689 |
} |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
690 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
691 |
日本語文字列を並び替える |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
692 |
仮名文字列を五十音順にソートするモジュールとして、ShiftJIS/Collate.pm があります。入手と使い方はPerlのページに戻れば見つかります。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
693 |
「読み・表記照合」は次のようにして行います。sortYomiメソッドの受け取るリストの各要素は、[ 表記列, 読み列 ]という配列リファレンスでなければなりません。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
694 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
695 |
use ShiftJIS::Collate; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
696 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
697 |
my @data = ( |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
698 |
[qw/ 小山 こやま /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
699 |
[qw/ 長田 ながた /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
700 |
[qw/ 田中 たなか /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
701 |
[qw/ 鈴木 すずき /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
702 |
[qw/ 小嶋 こじま /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
703 |
[qw/ 児島 こじま /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
704 |
[qw/ 小山 おやま /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
705 |
[qw/ 小島 こじま /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
706 |
[qw/ 小島 こじま /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
707 |
[qw/ 山田 やまだ /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
708 |
[qw/ 永田 ながた /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
709 |
); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
710 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
711 |
@sort = ShiftJIS::Collate->new()->sortYomi(@data); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
712 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
713 |
「簡易代表読み照合」は次のようにして行います。sortDaihyoメソッドの受け取るリストの各要素は、[ 表記列, 読み列 ]という配列リファレンスでなければなりません。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
714 |
サンプルコード |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
715 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
716 |
#!perl |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
717 |
use ShiftJIS::Collate; |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
718 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
719 |
my @data = ( |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
720 |
[qw/ λ計算 らむだけいさん /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
721 |
[qw/ JIS番号 じすばんごう /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
722 |
[qw/ 安達 あだち /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
723 |
[qw/ 安藤 あんどう /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
724 |
[qw/ 河西 かさい /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
725 |
[qw/ 河内 かわち /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
726 |
[qw/ 角田 かくた /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
727 |
[qw/ 角田 かどた /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
728 |
[qw/ 如月 きさらぎ /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
729 |
[qw/ 河内 こうち /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
730 |
[qw/ 幸山 こうやま /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
731 |
[qw/ 幸山 さきやま /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
732 |
[qw/ 佐藤 さとう /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
733 |
[qw/ 佐和田 さわだ /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
734 |
[qw/ 沢島 さわしま /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
735 |
[qw/ 沢田 さわだ /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
736 |
[qw/ 澤田 さわだ /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
737 |
[qw/ 角田 つのだ /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
738 |
[qw/ 槌井 つちい /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
739 |
[qw/ 土井 つちい /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
740 |
[qw/ 土居 つちい /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
741 |
[qw/ 戸井 とい /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
742 |
[qw/ 戸田 とだ /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
743 |
[qw/ 土井 どい /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
744 |
[qw/ 土居 どい /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
745 |
[qw/ 土岐 とき /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
746 |
[qw/ 安田 やすだ /], |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
747 |
); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
748 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
749 |
@sort = ShiftJIS::Collate->new()->sortDaihyo(@data); |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
750 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
751 |
|
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
752 |
Shift-JISの漢字を含むファイル名/パス名 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
753 |
本項目は、他の項目に増して、検討不充分のまま記述していますので、もし何か参考にしようと思った場合、十分に注意の上、納得できるまでご自分の作業環境でテストしてください。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
754 |
Windows (95/98/NT/2000など) で、ファイル名やパス名が漢字(ここでは二バイト文字の意味で使っていますので、平仮名や記号なども含みます。)を含む場合、Perlで扱う際に問題が生じる可能性があります。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
755 |
末尾バイトが "\x5C" の漢字をもつファイル名/パス名 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
756 |
ディレクトリ操作関数(mkdir, rmdir, opendir, -d など)、ファイル操作関数(open, unlink, -f など)で、アクセスできないことがあります。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
757 |
ファイルの場合は、末尾に半角スペースを添えるとアクセスできる場合があります(例えば、-f '表 ' または -f "\x95\x5C\x20" など)。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
758 |
ディレクトリの場合は、末尾に / か \ を添えるとアクセスできる場合があります(例えば、-d '表/' または -d "\x95\x5C/" など)。末尾に添える文字を半角スペースとしても、うまくアクセスできる場合があります。添える文字の候補として、三種類の文字(スラッシュ、円記号、空白)を挙げましたが、どの文字がよいかは、関数によって異なる場合があるようです。使用する前に十分にテストしてください。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
759 |
なお、ディレクトリ名の末尾に / か \ を添える場合、もともと末尾に / か \ が付いている場合には、二重に付けるとうまく行かないおそれがありますので、文字列連結の前に検査したほうがよいでしょう。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
760 |
どうしても挙動が不明で信頼できない場合は、`` または qx// や system()関数などを通じてWindowsのコマンドを呼ぶのが良いと思います。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
761 |
おまけ |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
762 |
Shift-JIS で書かれた POD を Perl 5.8.1, 5.8.2 の Pod::Html で HTML に変換した場合、アンカーの名前は、 英数字と仮名文字 [0xA6..0xDF] を除き、 他の各バイトは下線('_')に変換されるようです。 具体的には、use locale; 下で、lc と s/\W/_/g を実行した結果 (cf. Pod::Html::anchorify) になります。 |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
763 |
[2003-11-18] |
ae9c8dab0e3e
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
764 |
Perlのページ |