詳説 正規表現 第2版

[cover photo]
この商品は絶版になりました


テキストやデータの処理に欠かせない強力なツールとして瞬く間に普及した「正規表現」。現在ではPerl、Java、VB.NETやC#など数多くの言語やツールに標準で装備されています。その幅広い可用性、柔軟性と比類ない強力さにもかかわらず、実際に正規表現を使いこなすことは難しいです。本書は正規表現の概念を詳細に掘り下げる一方で、数多くの言語やツールの実例を示しながら、正規表現についての理解を深める解説書です。第2版では、豊富な実例を使い、詳しくていねいに解説するスタイルはそのままに、Perl5.8の新機能に加え、Javaと.NETの正規表現にもそれぞれ独立した章を設けるなど、全編にわたって大幅に加筆がなされました。正規表現の本質を読み解く決定版です。とくに正規表現を使いこなしていると自負している人にほど読んでほしい本です。

訳者まえがき
はじめに
1章 正規表現とは
        1.1 問題解決の実例
        1.2 言語としての正規表現
                1.2.1 ファイル名の共通点
                1.2.2 言語の共通点
        1.3 正規表現の考え方
                1.3.1 ある程度正規表現の経験がある人のために
                1.3.2 テキストファイルの検索:egrep
        1.4 egrepのメタ文字
                1.4.1 行の先頭と末尾
                1.4.2 文字クラス
                1.4.3 任意の文字とマッチさせる―ドット
                1.4.4 選択
                1.4.5 大文字と小文字の違いを無視する
                1.4.6 単語境界
                1.4.7 これまでのまとめ
                1.4.8 オプション要素
                1.4.9 その他の指定子:繰り返し
                1.4.10 丸括弧と後方参照 ? 
                1.4.11 エスケープ
        1.5 基礎を発展させる
                1.5.1 言語の多様性
                1.5.2 正規表現の目的
                1.5.3 いくつかの追加例
                1.5.4 正規表現の用語
                1.5.5 環境改善
                1.5.6 まとめ
        1.6 筆者の所見
        
2章 基本的な問題例
        2.1 例題について
                2.1.1 Perlの簡単な解説
        2.2 正規表現によるテキストのマッチ
                2.2.1 もっと実際に即した例
                2.2.2 成功マッチの副作用
                2.2.3 絡み合った正規表現
                2.2.4 ひと休み
        2.3 正規表現によるテキスト整形
                2.3.1 例:手紙の定型表現
                2.3.2 例:株価表示の整形
                2.3.3 自動編集
                2.3.4 ちょっとしたメールユーティリティ
                2.3.5 前後読みを使って数字にコンマを加える
                2.3.6 テキストからHTML形式への変換
                2.3.7 重複単語の問題
                
3章 正規表現の種類と機能
        3.1 正規表現の概要
                3.1.1 正規表現の起源
                3.1.2 各種正規表現の概要
        3.2 正規表現の扱い方と注意点
                3.2.1 組み込み方式による正規表現
                3.2.2 手続き方式およびオブジェクト指向型による正規表現
                3.2.3 検索置換の例
                3.2.4 他の言語における検索置換
                3.2.5 正規表現の扱い方と注意点:まとめ
        3.3 文字列、文字エンコーディング、モード
                3.3.1 正規表現を表わす文字列
                3.3.2 文字エンコーディングの問題
                3.3.3 正規表現モードとマッチモード
        3.4 よく使われるメタ文字とその機能
                3.4.1 文字表現
                3.4.2 文字クラスとその類似構文
                3.4.3 アンカーおよびその他の「ゼロ幅の言明」
                3.4.4 コメントとモード修飾子
                3.4.5 グループ化、キャプチャ、条件式、制御式
        3.5 上級者編への指針
        
4章 正規表現の処理メカニズム
        4.1 エンジン始動!
                4.1.1 2種類のエンジン
                4.1.2 新しい基準
                4.1.3 正規表現エンジンの種類
                4.1.4 振り出しに戻る
                4.1.5 エンジンの種類を見極める
        4.2 マッチの基本原則
                4.2.1 例題について
                4.2.2 第1原則:最初のマッチが優先される
                4.2.3 エンジン部品
                4.2.4 第2原則:標準の量指定子は欲張りである
        4.3 正規表現制御型とテキスト制御型
                4.3.1 NFAエンジン:正規表現制御型
                4.3.2 DFAエンジン:テキスト制御型
                4.3.3 NFAとDFAの比較(ここまでの説明でわかること)
        4.4 バックトラック
                4.4.1 道しるべの喩え
                4.4.2 バックトラックに関する2つの重要事項
                4.4.3 記憶されたステート
                4.4.4 バックトラックと貪欲ぶり
        4.5 貪欲さについてもう少し学ぶ
                4.5.1 貪欲さによる問題
                4.5.2 複数文字からなる「クォート」
                4.5.3 非欲張り量指定子
                4.5.4 欲張りマッチも非欲張りマッチも常にマッチ成功を優先させる
                4.5.5 欲張り、非欲張り、バックトラッキングの本質
                4.5.6 強欲量指定子とアトミックなグループ
                4.5.7 強欲な量指定子、?+、*+、++、{m,n}+
                4.5.8 前後読みのバックトラック
                4.5.9 選択は欲張りか?
                4.5.10 順序つき選択を活用する
        4.6 NFA、DFA、およびPOSIX
                4.6.1 最長最左
                4.6.2 POSIXと最長最左規則
                4.6.3 スピードと効率
                4.6.4 まとめ:DFAとNFAの比較
        4.7 まとめ
        
5章 正規表現の実践技法
        5.1 バランスをとる
        5.2 いくつかの簡単な例
                5.2.1 継続行の例の続き
                5.2.2 IPアドレスとのマッチ
                5.2.3 ファイル名の操作
                5.2.4 対になる括弧類をマッチさせる
                5.2.5 不要なマッチに注意する
                5.2.6 区切られたテキストのマッチ
                5.2.7 自分のデータを把握して仮定を立てる
                5.2.8 先頭と末尾の空白を取り除く
        5.3 HTML関連の例
                5.3.1 HTMLタグをマッチする
                5.3.2 HTMLリンクをマッチする
                5.3.3 URLを調べる
                5.3.4 ホスト名を検査する
                5.3.5 実世界におけるURLの取り出し
        5.4 さまざまなテクニック
                5.4.1 データと同期をとる
                5.4.2 CSVファイルを解析する
                
6章 正規表現を工夫する
        6.1 興味深い例題
                6.1.1 簡単な変更:好手を先に
                6.1.2 効率性と正確さのバランス
                6.1.3 一歩進んだ方法:貪欲さを局所化する
                6.1.4 して、その正体やいかに
        6.2 バックトラックの全体像
                6.2.1 さらに作業を続けるPOSIX NFA
                6.2.2 マッチ不成立で行われる作業
                6.2.3 もっと条件を限定する
                6.2.4 選択は高くつくことがある
        6.3 ベンチマーク
                6.3.1 何を測定しているのかを把握する
                6.3.2 Javaを用いたベンチマーク
                6.3.3 VB.NETを用いたベンチマーク
                6.3.4 Pythonを用いたベンチマーク
                6.3.5 Rubyを用いたベンチマーク
                6.3.6 Tclを用いたベンチマーク
        6.4 よく行われる最適化
                6.4.1 いつも効果があるとは限らない
                6.4.2 実装方法はいろいろ
                6.4.3 正規表現適用の仕組み
                6.4.4 適用前の最適化
                6.4.5 トランスミッションに関する最適化
                6.4.6 正規表現自体の最適化
        6.5 正規表現の高速化技法
                6.5.1 常識的な技法
                6.5.2 リテラルのテキストを表に出す
                6.5.3 アンカーを表に出す
                6.5.4 非欲張りと欲張りのどちらを使うかは対象データによる
                6.5.5 複数の正規表現に分割する
                6.5.6 先頭文字/クラス/部分文字列の識別を模倣する
                6.5.7 アトミックなグループと強欲な量指定子を使う
                6.5.8 エンジンをマッチに導く
        6.6 ループ展開
                6.6.1 これまでの経験に基づいて正規表現を構築する
                6.6.2 本格的な「ループ展開」パターン
                6.6.3 高次元の視点で見る方法
                6.6.4 インターネットホスト名
                6.6.5 考察
                6.6.6 アトミックなグループと強欲な量指定子を使う
                6.6.7 ループ展開の簡単な例
                6.6.8 Cコメントの展開
        6.7 スムーズに流れる正規表現
                6.7.1 マッチするように導くには
                6.7.2 よく制御された正規表現は速い
                6.7.3 まとめ
        6.8 頭を使え!
        
7章 Perl
        7.1 言語の一部としての正規表現
                7.1.1 Perlの最大の長所
                7.1.2 Perlの最大の弱点
        7.2 Perl正規表現の特性
                7.2.1 正規表現オペランドと正規表現リテラル
                7.2.2 正規表現リテラルの解析方法
                7.2.3 正規表現修飾子
        7.3 正規表現関連のPerl作法
                7.3.1 式のコンテキスト
                7.3.2 動的スコープと正規表現マッチの効果
                7.3.3 マッチによって変更される特殊変数
        7.4 qr/…/演算子と正規表現オブジェクト
                7.4.1 正規表現オブジェクトの構築と使用
                7.4.2 正規表現オブジェクトの中身を確認する
                7.4.3 正規表現オブジェクトを用いて効率アップを図る
        7.5 マッチ演算子
                7.5.1 マッチの正規表現オペランド
                7.5.2 マッチ対象オペランドの指定
                7.5.3 正規表現演算子のさまざまな使い方
                7.5.4 繰り返しマッチ:スカラーコンテキスト(/g修飾子あり)
                7.5.5 マッチ演算子と環境との関係
        7.6 置換演算子
                7.6.1 置換オペランド
                7.6.2 /e修飾子
                7.6.3 コンテキストと戻り値
        7.7 split演算子
                7.7.1 基本知識
                7.7.2 空要素を返す
                7.7.3 splitの特殊なマッチオペランド
                7.7.4 splitのマッチオペランドの中でキャプチャ用括弧を使う
        7.8 Perlの新機能を使う
                7.8.1 動的正規表現を使って入れ子構造をマッチする
                7.8.2 埋め込みコード構文を使用する
                7.8.3 埋め込みコード構文の中でlocalを使う
                7.8.4 埋め込みコードとmy変数に関する注意事項
                7.8.5 埋め込みコードを使って入れ子構造をマッチする
                7.8.6 正規表現リテラルのオーバーロード
                7.8.7 正規表現リテラルオーバーロード機能の問題点
                7.8.8 名前つきキャプチャを模倣する
        7.9 Perlにおける効率の問題
                7.9.1 “やり方は1つだけではない”
                7.9.2 正規表現のコンパイル、qr/…/、/o修飾子、および効率性
                7.9.3 “マッチ前”コピーを理解する
                7.9.4 Study関数
                7.9.5 ベンチマーク
                7.9.6 正規表現のデバッグ情報
        7.10 まとめ
        
8章 Java
        8.1 正規表現パッケージの評価基準
                8.1.1 技術的な問題
                8.1.2 社会的および政治的な問題
        8.2 オブジェクトモデル
                8.2.1 いくつかの抽象的なオブジェクトモデル
                8.2.2 複雑さを増すモデル
        8.3 パッケージ、パッケージ、パッケージ
                8.3.1 多くのパッケージが“Perl5”の機能を提供している理由
                8.3.2 嘘、ひどい嘘、ベンチマーク
                8.3.3 お勧め
        8.4 Sunの正規表現パッケージ
                8.4.1 正規表現の種類
                8.4.2 java.util.regexを使う
                8.4.3 Pattern.compile()ファクトリ
                8.4.4 Matcherオブジェクト
                8.4.5 Patternのその他のメソッド
        8.5 Jakarta-OROクイックガイド
                8.5.1 OROのPerl5Util
                8.5.2 簡単なPerl5Utilリファレンス
                8.5.3 OROの基本クラスを使う
                
9章 .NET
        9.1 .NET正規表現の機能
                9.1.1 さらなる留意事項
        9.2 .NETの正規表現を使う
                9.2.1 正規表現クイックガイド
                9.2.2 パッケージの概要
                9.2.3 コアオブジェクトの概要
        9.3 コアオブジェクトの詳細
                9.3.1 Regexオブジェクトを生成する
                9.3.2 Regexオブジェクトを使う
                9.3.3 Matchオブジェクトを使う
                9.3.4 Groupオブジェクトを使う
        9.4 静的な「利便性」関数
                9.4.1 正規表現のキャッシング
        9.5 支援関数
        9.6 .NET正規表現の高度な機能
                9.6.1 正規表現アセンブリ
                9.6.2 入れ子構造をマッチする
                9.6.3 Captureオブジェクト
                
索引

ここで紹介する正誤表には、書籍発行後に気づいた誤植や更新された情報を掲載しています。以下のリストに記載の年月は、正誤表を作成し、増刷書籍を印刷した月です。お手持ちの書籍では、すでに修正が施されている場合がありますので、書籍最終ページの奥付でお手持ちの書籍の刷版、刷り年月日をご確認の上、ご利用ください。

P.103 para2
(誤) この文字はUnicodeでは%vuc(0061)(%rlit{a})と%vuc(0300)(%rlit(`))
の2つのコード点を組み合わせとして表現(エンコード)される。
(正) この文字はUnicodeでは%vuc(0061)(%rlit{a})と%vuc(0300)(%rlit(`))
の2つのコード点の組み合わせとして表現(エンコード)される。

P.104 para2
(誤) チェックするのに一苦労するテキストを作成する人たちがいるが、この問題
はそのようなテキストを作成してしまうことに原因の1つがあると考えられる。
(正) こうした文字はテキスト作成者も混同していることがあるため、それらを含
むテキストを正規表現でチェックするのには苦労させられる。

p.130 表3-14注
(誤) GNU awkでは、置換文字列内で、全体マッチを表す?&が使える。また、
gensub関数では、置換文字列に?0(または?&)、およびす?1、?2等が使える。
(正) GNU awkでは、置換文字列内で、全体マッチを表す?&が使える。また、
gensub関数では、置換文字列に?0(または?&)、および?1、?2等が使える。

p.132 para5 update!
(誤) 「番号づけの数字の中にゼロがあるようなものだ」。
(正) 「数字の中にゼロがあるようなものだ」。

p.150 原注 update!
(誤) 「決定論的」という言葉はきわめて重要だ。
(正) 「決定性」という言葉はきわめて重要だ。

p.162 para -2 update!
(誤) もっとはっきり言ってしまえば、%re{[1-9]}によるマッチ部分を譲ることによっ
て全体マッチが不成功となるならそれでもかまわない、
(正) もっとはっきり言ってしまえば、%re{[1-9]}によるマッチ部分を譲らないことに
よって全体マッチが不成功となるならそれでもかまわない、

p.168 para2 update!
(誤) この正規表現では選択の後には何もないので、%re{tour}マッチした瞬間に
正規表現全体が終了する。
(正) この正規表現では選択の後には何もないので、%re{tour}がマッチした瞬間
に正規表現全体が終了する。

P.168 para4
(誤) DFAやPOSIX DFAの選択は欲張りなので
(正) DFAやPOSIX NFAの選択は欲張りなので

p.169 para 4 update!
(誤) %litNorm{Jan>SP>31}という1月の日付をマッチさせたい場合を考えてみよ
う。%re{Jan [0123][0-9]}では不十分だ。これだと、%lit{Jan00}
や%lit{Jan39}といった日付が許されてしまう上、%lit{Jan7}
は認されない。
(正) %litNorm{Jan31}という形式の1月の日付をマッチさせたい場合を
考えてみよう。%re{Jan [0123][0-9]}といった安易な表現では不十分だ。これだ
と、許されるべきではない%lit{Jan00}や%lit{Jan39}といった
日付が許されてしまう。その上、許されるべき%lit{Jan7}が許されない。

P.200 para 1 update!
(誤) たとえが次のような具合だ。
(正) たとえば次のような具合だ。

P.203 5.4.1.1タイトル
(誤) 先読みを用いてマッチの同期をとる
(正) マッチの同期をとる

P.205 para5
(誤) これにより、直前の...が目的の郵便番号の位置だけで、あるいはマッチす
る番号がなくなったときに終了するということを利用する。
(正) これは、直前の...がマッチを終える位置が、目的の郵便番号の直前、ある
いはデータの終わりに到達したときだけであるという事実をうまく利用したものである。

P.206 para -2
(誤)
TenThousand
10000
2710
空のフィールド

(正)
Ten●Thousand
10000
●2710●
空のフィールド

(注)●は空白(半角スペース)を表す

P.213 コラム記事 
サンプルコード3〜7行目を削除

P.222 para4 
(誤) 図5-3のAからBまでのマッチを
(正) 図6-3のAからBまでのマッチを

P.332 para3
(誤) たとえば、このコードを%code[m/^?( $NestedGuts ?)$/x]の一部として使用
し、それを%lit[(this is missing the close]というテキストに適用すると、前に進ん
ではバックトラックする動きを延々と繰り返す。アトミックグループを使用すれ
ば、(バックトラック先となる)余分なステートが削除されるのでそのようなことは
なくなる。
(正) たとえば、この正規表現オブジェクトを%code[m/^?( $NestedGuts ?)$/x]の
ように使用し、それを%lit[(this is missing the close]というテキストに適用する場
合を考える。このとき、もしアトミックなグループによって余分なステートを削除し
ないと、前に進んではバックトラックする動きを延々と繰り返すことになる。

Feedback

皆さんのご意見をお聞かせください。ご購入いただいた書籍やオライリー・ジャパンへのご感想やご意見、ご提案などをお聞かせください。より良い書籍づくりやサービス改良のための参考にさせていただきます。
[feedbackページへ]