AWTとSwingのペイント(paint)の仕組み Java API javadoc改善運動! Javaの手帖 Javaの手帖--GUI分冊 /ひとつ上をゆくJavaの教科書 「JavaServer Faces完全ガイド」補遺
javacのエラーメッセージ解説 「Javaの哲学」の恥かき 「Javaによるテキスト処理」の恥かき 「モア・サーブレット」の恥かき 恥かきのホームページ フォーラム「JavaBeginner」
UIDefaultsのkeyとデフォルト値「コア・サーブレット」の恥かき comp.lang.java.guiのFAQ日本語訳 「入門 正規表現」 「Javaネットワークプログラミングの真髄」 「Java並行処理プログラミング」

[NEW][HOME][正規表現Q&A掲示板]

入門 正規表現--follow-up

--update 080612--

[著者へのmail]を歓迎します★

  1. 080612
    ■正誤表:
    080612【読者(中村種治さん)のご指摘】:

    p058:かっこを使って注記文を追加します:
    【誤】同じものが取り出されます。
    【正】同じものが取り出されます。(なお、正規表現の一部の実装では、前方参照や後方参照の中で+や*による不特定な量指定ができません。上の例は、前方/後方参照の中で不特定な量指定ができる実装を想定しています。)


    080527【読者(中村種治さん)のご指摘】:

    p062, 上から4行目「表現ですね。」の下の空行部分に下記の文を挿入します。
    [以下新規挿入稿]
    <空行>
    ※:上記に関する訂正注記
    (1)片仮名の指定について
     015ページの脚注で述べたように、[ア-ン]という指定では、ァ、ヶ、ヴなど一部の特殊な片仮名が含まれません。実用上とくに困るのが、この範囲指定にオンビキ(音引き)、すなわち'ー'が含まれないことです。そこで、オンビキまで含めて指定したいときには、 [ア-ン]ではなく[ア-ー]を使ってください(Unicodeの場合)。なお、[ァ-ヾ]と指定すると、Unicodeが片仮名として定義している文字がすべて含まれます。[ア-ー]というやや狭い指定でも、その中にはナカグロ(中黒)すなわち'・'まで含まれてしまいます(えっ、それって片仮名?…でも実用上は片仮名に含めたほうが便利ですね)。なおShift_JISなどでは、簡単な範囲指定の中にオンビキやナカグロを含めることはできません。
    <空行>
    (2)否定形の前方/後方参照の落とし穴
     (?!大会)は、「直後に‘大会’がない」という前方参照なので、[ア-ー]+(?!大会)という正規表現では“スポーツ大会”の‘スポーツ’は拾いません。ところが、最後の3文字:‘ツ大会’は、ご覧のとおり、‘大会’ではないので、この否定指定に当てはまりません。そこで、‘スポーツ’は拾われませんが‘スポー’が拾われてしまいます。
     これと同じ事情で、(?<!高級な?)は「直前に‘高級’または‘高級な’がない」という後方参照なので、(?<!高級な?)[ア-ー]+という正規表現では“高級なミンク”の‘ミンク’は拾いません。ところが、最初の4文字:‘高級なミ’は、ご覧のとおり、‘高級な’ではないので、この否定指定に当てはまりません。そこで、‘ミンク’は拾われませんが‘ンク’が拾われてしまいます。
     このような結果を防ぐためには、[ア-ー]+(?![ア-ー]|大会)や(?<!高級な?|[ア-ー])[ア-ー]+のように、否定対象の中に片仮名を含めてやる必要があります。そうすると、上の‘ツ’や‘ミ’が否定対象になるので、‘スポー’や‘ンク’は拾われなくなります。
     この件に限らず、肯定はそれそのものをずばり指定しますが、否定に当てはまるものはけっこういろいろ、いろんなものがあります。言い換えると、否定は幅が広いです。否定形は要注意です。
    <空行>


    080501【私(著者)が発見】:

    p119, 下2〜3行....捕捉グループの数は2桁でも3桁でもOKだ!
    [誤]実は$nで指定できる番号は0から9までなので,
    [正]しかしこの正規表現には18番目の捕捉グループはないので,

    (注記:\nや$nのnがどんなに大きくても、実際にその番号の捕捉グループが正規表現中にあれば、捕捉グループの番号として扱われます。詳細はMatcherクラスのappendReplacement()メソッドのドキュメンテーションに書かれています。うろ覚えの--間違った--知識で文章を書いてはいけませんね!。…関連記事を[Q&A掲示板]に掲載しました(日付:2008/05/02「捕捉グループがたくさんあるときの問題」)。)



    080409【読者(myakuraさん)からのご指摘】:

    p031, 最下行....「アラビア数字」を「ローマ数字」と誤記
    [誤]ローマ数字で,
    [正]アラビア数字で,


    080301【著者自身による誤記の発見】:

    p090, 下から12行....\d/dと誤記
    [誤]/d{1,3}
    [正]\d{1,3}

    p112, 下から12行....Javaの文末のセミコロン
    [誤]html.replaceAll("<div\\s", "$0class=\"clrr\" ")
    [正]html.replaceAll("<div\\s", "$0class=\"clrr\" ");


    p004 最下行:かっこ内に注記を追加します:
    【誤】期待いたします。
    【正】期待いたします。(なお、著者による本書のサポートページhttp://homepage1.nifty.com/algafield/regex/で、正誤表などを随時更新して提供します。)


  2. 080308
    ■追記項目:

    080308【トラブルと主な原因[3]に追記】:

    p155 [3-c]の次に以下を追加します:
    
    [3-d] .(ドット)のうかつな濫用
     本書p040の最後には、“正規表現の上手な使い方のコツのひとつは、
    「具体的に特定できる場合は特定せよ…不特定な文字指定や量指定に安
    易に頼るな」です”と書いています。またp089 6.3>>[なるべく具体
    的に]では“正規表現の賢い使い方の原則の第一は、具体的な指定がで
    きる部分は具体的に指定すること”と書いています。正規表現の文字指
    定の中で、もっとも具体的でないものは、「文字ならなんでもよい」を
    指定するドットです。長大な入力文字列に対して.*Xと指定すると、正
    規表現エンジンはその文字列を全部読んでから後戻りをしてXを探しま
    す。こんなとき、たとえば[^。、]*Xのように文字の条件をより具体的
    に指定できるのではないか?とよーく考えてください。
     p154 [2-c]では、*(アスタリスク)は「無」ともマッチするので
    危険、と書きましたが、より具体的に文字を指定できる場合のうかつ
    な.*(ドットとアスタリスク)の使用は、上で説明したように、入力
    のサイズが大きいときには実行効率の問題ももたらします。
    
    080424【「オーバラッピング・マッチ」に追記】:

    p130 コラムの最後に以下を追加します:
    
     なお、Javaなどのプログラミング言語を使って自作のプログラムか
    ら正規表現を使うときは、正規表現の対象テキスト中の「次回の探索
    開始位置」を自由に指定できる(たとえば補足グループnとの前回の
    マッチの初端位置)ので、以上のような工夫に頼らなくても、オーバ
    ラッピング・マッチを比較的楽に行えます。
     たとえば、ofによる連結語を、sprinkling of the blood of Jesus Christ
    から探すとき、オーバラッピング・マッチなら'sprinkling of the blood'と
    'blood of Jesus'の両方を拾えますが、正規表現のふつうの使い方で
    は、次の探索がbloodの直後からになるので、'blood of Jesus'が
    拾えません。
    
    080426【トラブルと主な原因[1]に追記】:

    p152 [1-e]の次に以下を追加します:
    
    [1-f] 改行文字をリテラルで指定するときは要注意
     正規表現の標準的な使い方では、行頭は'^'、行末は'$'で指定します。
    これらはプラットホームの違い(Windows, UNIX/Linux/BSD, Mac, etc.)
    に左右されず、普遍的です。対象テキストが複数行のときも、(?m)を指
    定すると各行の行頭行末をこれらの正規表現文字で指定できます(本書
    5.7節)。
     しかし、正規表現中に改行文字をリテラルで書かなければならないと
    きには、対象テキストがどのプラットホームの上で作られたのかを認識
    ・意識しないと、“正しい正規表現を書いたつもりなのにマッチしない”
    という現象に泣かされます。Windowsの上で作られた/生成されたテキス
    トは、行末の改行文字が'\r\n'(carriage returnとnewline, 文字コー
    ドで0x0d, 0x0a)です。LinuxなどUNIX系のプラットホームでは'\n'です。
    Macは'\r'です。そこでもちろん、たとえばWindows上で作られたテキス
    トに対し改行を'\n'で指定すると、正規表現のそのほかの部分が完全に
    正しくても、ノーマッチになってしまいます。
     …。でも、こんなややこしい話を記憶する苦労を背負うより、「正規
    表現の中では改行文字を(なるべく)リテラルで書かない」ようにする
    のがベターですね。
    



AWTとSwingのペイント(paint)の仕組み Java API javadoc改善運動! Javaの手帖 Javaの手帖--GUI分冊 /ひとつ上をゆくJavaの教科書 「JavaServer Faces完全ガイド」補遺
javacのエラーメッセージ解説 「Javaの哲学」の恥かき 「Javaによるテキスト処理」の恥かき 「モア・サーブレット」の恥かき 恥かきのホームページ フォーラム「JavaBeginner」
UIDefaultsのkeyとデフォルト値「コア・サーブレット」の恥かき comp.lang.java.guiのFAQ日本語訳 「入門 正規表現」 「Javaネットワークプログラミングの真髄」 「Java並行処理プログラミング」