正規表現レベルがUPした!!
こんなHTMLから、input要素のうちtype属性がtextのもののname属性値を表示せよ、というのがあった場合どうするか。当然期待値は「name」と「age」です。
名前:<input type="text" name="name" style="field"> <br> 性別:男<input type="radio" name="sex" value="1"> 女<input type="radio" name="sex" value="2"> <br> 年齢:<input type="text" name="age" style="field"> <br>
パターンとして、こんなのが思いつく。「m」は複数行に渡るものをパターンマッチングさせる時に指定するもので、ruby特有のもの(多分。他の言語だとどうかは分からない)。
/<input type="text".*name="(.*)".*>/m
しかしこれだと、1行目の<から最後の行のbrの>まで全部がパターンマッチングするんです。「.*」だからね。けどどうしたらいいのさ。。
・・・っていうのが今までのワタシ。この類の正規表現はいつも諦めてた。しかし今日からのワタシは違う。これが解けたのだ!パターンはこれ。
/<input type="text".*?name="(.*?)".*?>/m
ポイントは「.*」のあとに「?」が入っているところ。
実はこの「?」は、直前の文字が0回か1回の出現をあらわすマッチング記号ではない。
正規表現には最短一致という考え方と最長一致という考え方があるようで、デフォルトは最長一致になっているそう。これを最短一致にするための指定がこの「?」なのです。
というわけで、name、ageと出力するためのrubyプログラムを以下に書いておきます。冒頭のHTMLがhtml_txt変数に格納されてます。
puts html_txt.scan(/<input type="text".*?name="(.*?)".*?>/m).join(", ")
Thanx!
これに気づいたのは以下を見て。嗚呼、長年のもやもやが解けました!ありがとうございます。
http://ja.doukaku.org/comment/6544/
あと正規表現の確認する時、これ便利♪
http://www.rubular.com/