[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends-ml 10811] Re: あさっての土 曜日は読書会の日。そして Item27 と ...



 井上泰です。

> 担当するItemが重複している方の中で、このItem27を担当しても
> 良いよー、という方はいらっしゃいませんでしょうか?


Item30重複しています。
LDAPは全く未経験なのですが挑戦してみます。

Item 30 の試訳を送ります。

------------------------------------------------------------------------------------------------
項目 30 : 正規表現を使用したフォームのデータチェック

最新のMerlinリリース(Java SDK 1.4)は正規表現を導入し、開発者は以前にリ
リースされたストリング処理メソッドよりも容易なやり方で文字テキストを扱う
ことができるようになった。この機能拡張のおかげで、成熟した言語機能がさら
に強化され、エラーチェックとテキスト処理が容易になったが、このことはWeb
アプリケーションコンポーネントにとって非常に重要である。

検索ならびに検索置換は、正規表現の最も普通の利用方法であるが、テキストパ
ターンとデータストリームに真偽テストを実施するのに利用することもできる。
Unixを使い慣れている人は、正規表現の存在と、その能力が強力なのはUnixの
ツールとコマンドであたりまえのように利用されているからだ、ということを認
識すべきである。わたしは、JavaBeanコンポーネントで、正規表現を使用して
フォームテキストを解析し、データチェックや置換を実行するのを好む。図30.1
では、Web Formに、エンドユーザーが誤った入力を送信した場合の、入力フィー
ルドのデータチェックとユーザー画面に表示されたエラーテキストの実例を示
す。続くコードを見れば、Web開発者にとって正規表現がどれだけ重要になりう
るか、Java言語がどれだけ「つねに価値を提供しつづるプログラミング言語」で
あるか、が明らかになるだろう。

図30.1のフォームは、ユーザー入力を取得し、ワークフローにおける次のアプリ
ケーションに渡す前にデータチェックを行う。リスト30.1のデータチェックビー
ンは、ユーザー入力を読み込み、Mamentoパターンを使用して記憶し、正しい入
力が送信されたかどうかをチェックする。誤った入力にはタグをつけ、ユーザー
画面に送り返し、正しい入力はどうあるべきかを指示する。

電話番号は一般に文字ストリングで、読みやすくするため区切り文字で分けられ
る。したがって正規表現は、0から9の範囲の数字とダッシュ文字の組み合わせだ
けを受付けるべきである。36行目の電話番号パターンは、ユーザー入力は10文字
で、入力にダッシュ区切り文字をオプションで利用できることを保証する。ほん
の1行で実行されるのと同じ操作を実行するには、複数の文字列処理が必要にな
るだろう。正規表現のなかの2つのバックスラッシュ"\\d"に注意。これがPerlの
一つのバックスラッシュ表記法とは異なるのは、(最初の\は)正規表現ではなく
(\に続く文字を)エスケープ文字の値とみなすから。括弧"{}"の表記法は、検査
対象のストリングリテラルに見つけられるべき数字の個数を示す。

(訳注: サンプルコードのなかの、()+は誤り、一回以上の繰り返しはすべて許容
することに)

社会保険番号は一般にダッシュ区切り文字で分けられた9桁の数字から成る。そ
こで正規表現が受付ける必要があるのは、電話番号パターンと同様な、数値と文
字数の制約である。

生年月日のフォーマットには、さまざまな種類があるが、ここでアプリケーショ
ンがチェックするユーザー入力は、"YYYY-MM-DD"フォーマットに従う。63行から
77行までのコメントにされたコードは、直前のDOB(Date of birth 生年月日)
チェックで実装されている。繰り返しになるが、このコードセグメントを見れ
ば、少ないコードが多くを実行するのは明らかである。

(訳注: 形式チェックだけが行われる。たとえば、2003-01-50はエラーにならない。
正規表現で日付の妥当性チェックも可能か?
正規表現が駄目ならDateFormatをsetLenient(false)で実行する。
同期化の問題あり。その都度インスタンス生成するか、DDJ7月のThreadLocalソ
リューションを利用する。)

Eメールのアカウントチェックは85行に記述されたパターンで行う。このパター
ンテキストは、アンダーラインとピリオドを含めた英数字がat(場所)記号(@)で
区切られ3バイトの拡張子で終了するかを、テストする。(訳注: unicodeを使用
するJavaでは「3バイト」は「3文字」とすべきだろう。サンプルコードは{2,}で
2文字以上になっている)

わたしが、ほんとうに嫌気がさすのは、何か自分の興味あることにアクセスする
のに、自分自身の情報を過度に多く入力させられることである。これでいらだつ
と幼稚な入力になってしまい、打ち込む時間が長くなればなるほど下品になって
ゆく。こんなことをするのは自分だけじゃないことはわかっている。というの
も、大抵のサイトには、汚い単語をチェックする何らかの機能が備わっており、
不適切な言葉がデータベースに伝播しないことを保証しているから。

94行から96行までのコードは、ユーザー入力をチェックし、不適切な言葉を捕ま
え、より穏やかで中傷的でないテキストへの置き換えを保証する。正規表現の
(darn | shoot ...) は、ユーザーのコメントテキスト入力に実行され、マッチ
するものが見つかれば、MatcherクラスのreplaceAll(text)メソッドで置き換え
られる。

(訳注: darn: damn, shoot: やだーっ, damn: くそ、畜生,  jerk: ばか、と
んま,  stupid: まぬけ、ぼんくら / jerk stupidもある, dummy: でくのぼう)

次のコードでは、括弧の中の副正規表現がテキストを置き換え新しいテキストを
返す方法を説明する。以下の例で、わたしの意図は、小数点以下2桁に続く数字
をすべて切り捨てることである。これは、小数点以下2桁の数字を"\\.\\d\\d"で
マッチングすることで、実現することができる。以下のコードセグメントを実行
すれば、testAnswerは111.63と出力される。

もうひとつ、グループ操作を実行する簡単な例を、下に示すピッグラテン(Pig
Latin)文字列操作を実行するコードの一部に示す。ピッグラテン遊びでは、母音
以外で始まる文字列はすべて、先頭文字を文字列の末尾に移動し、最後に文字
"ay"を付け加えることになっている。EaglesはEで始まるので、文字列操作は行
われない。これ以外の文字列はすべてピッグラテン文字列操作で置き換えられる。

(訳注: Pig Latinでは、先頭文字は1文字だけとは限らない。例えば、speakは
eakspayになる。母音が現れるまでの子音は何文字であっても移動の対象になる。)

Unixシステムで正規表現を利用する開発者にとって大きな問題は、ツールで、と
りわけ ed, ex, vi, sed, awk, grep, egrepで、動作に一貫性がないことであ
る。表記法が異なるため予期しない結果が生じ、苦痛は避けられず、ツールの正
規表現ライブラリのパターン構文をよく理解しなければならなくなる。ユーザが
問題を抱えるのは、パターンを記述する時やパターンが出現する文脈を認識する
時である。同じ問題はサードパーティの正規表現を使用するJavaアプリケーショ
ンにも存在する。望むらくは、最新Java SDKの正規表現の実装がこれに取り組
み、アプリケーションや異なるプラットフォーム間で、パターンの一貫性を提供
してくれることである。

Merlinリリースに含まれる正規表現ライブラリは、すでに強力になっているビジ
ネス向けプログラム言語にとって久しく待ち望まれた追加機能だった。パターン
マッチと置換は、将来、Javaの開発作業に多大な柔軟性をもたらし、Web開発を
容易にするはずである。正規表現を利用すれば、パターンにメタキャラクタを実
装することで、テキストの範囲マッチングが改善され、テキスト処理という経験
は楽しみに変わる。

公表されたJava 2 Standard Edition APIによると、Java正規表現APIは、以下の
Perl 5でサポートされる操作をサポートしない。

・条件付き構文 (?{X})
・埋め込みコード構文 (?{コード})
・埋め込みコメント構文。文字列のコメントをパースするには、?#コメント を
使用。
・プリプロセス演算。"\l、\L、\u、\U" 構文要素の実装を含む。ストリングす
べてに、小文字変換、大文字変換操作を実行するには、"\L"、"\U"を使用する。
ストリングの次の文字に小文字変換、大文字変換操作を実行するには、"\l"、"\
u"構文要素を使用する必要がある。

さらに、Javaの正規表現クラスがサポートするがPerl 5でサポートされない構文
要素は次のとおり。

強欲な数量子。条件を満たした場合に他の操作に後戻り (バックトラック) しな
いこと。できるだけ長い文字列マッチ操作を生じる。

文字クラス操作の優先度。リテラルエスケープ、グループ化、範囲、結合、交差。

上のチェックコードでユーザー入力のパースは問題ないが、Webページ内のテキ
ストをパースしたいと思うかもしれない。以下のコードは、自動Webナビゲー
ションで網にかかったすべてのHTMLページからメタデータを取り除くために使用
する。166行目でPatternクラスが使用され、ページでパースするストリングパ
ターンを設定する。パターンの部分には、2つのタグ要素、meta nameとcontent
がある。MatcherクラスをpageOutputストリングのWebページの内容に与え、
Stringクラスの新しいsplitメソッドを使用して、すべての項目を分離する。

新たな正規表現が、次のレベルの自動Webナビゲーションを行うため、HTMLペー
ジの追加リンクを分離するのに使用される。<a href></a>パターンが、テキスト
からパースするターゲット正規表現である。グループ化(a|A)は、大文字と小文
字表現のどちらにもマッチするよう使用する。

(訳注: Web spideringとは、Webサイトを自動的にたどるロボット機能のことら
しい。
metaタグのnaem=robot,descriptionなどが関連。
http://www.w3.org/Search/9605-Indexing-Workshop/ReportOutcomes/Spidering.txt)

図30.2に示すWebページは、上のコードの自動Webナビゲーションの結果を示して
おり、コードはregexpTest.jspアプリケーションに存在する。以下に示す、
submitボタンの下の結果は、URIフィールドで要求されたWebページからパースさ
れたリンクである。

(訳注: spilt()機能があれば、StringTokenizerやItem 18の機能は不要だと思わ
れる。しかし、Merlin以前のjdkでは必要。)

Javaの正規表現は、強力な言語構成要素であり、開発者のためにストリング操作
を強化する。Javaの正規表現を使用すれば、Javaの開発者は、テキスト処理で
Perlプログラマーが何年間も自慢してきた機能を実現することができる。



Java tutorial; Lesson: Regular Expressions
http://java.sun.com/docs/books/tutorial/extra/regex/index.html
Regular Expressions and the Java Programming Language
http://developer.java.sun.com/developer/technicalArticles/releases/1.4regex/
Core Java Technologies Tech Tips, October 8, 2002
http://developer.java.sun.com/developer/JDCTechTips/2002/tt1008.html
パッケージ java.util.regex
http://java.sun.com/j2se/1.4/ja/docs/ja/api/java/util/regex/package-summary.html


O'Reilly 正規表現
http://www.oreilly.co.jp/BOOK/regex2/
http://www.oreilly.com/catalog/regex2/

ORO
http://jakarta.apache.org/oro/index.html
http://www.asahi-net.or.jp/~dp8t-asm/java/tips/RegExp.html
(Struts1.1にはOROが入っている)

Regexp
http://jakarta.apache.org/regexp/index.html