あなたが正規表現の中級者か判別する10問テスト (文字列処理の必須知識)
あなたが,正規表現を扱うプログラマーとして,中級以上の実力を持っているかどうか判定します。
下記に,正規表現に関する10問の質問があります。
いずれも,「文字列を処理する実用的なプログラム」を書く上で必要な知識です。
これから試験を行ないます。 空欄を埋めて下さい。5分以内に回答して下さい。
※空欄は _____ のように下線として示されています。
(問1)
"郵便番号は〒123-4567です。"
という文字列を,str1 とします。
str1 の中に郵便番号が含まれているかどうかを判定したい場合は,
/〒[0-9]{3}-[0-9]{4}/
という正規表現を記述します。
一方,str1 の中から,郵便番号の数値の「123」と「4567」の部分を抽出したい場合は,
/_________/g
という正規表現を記述します。
(問2)
正規表現では,(1)のように,
マッチした全体文字列の中から部分文字列を抽出することができます。
このような操作のことを,
「部分文字列を _____で______ する」 といいます。
(問3)
"私は人間です。俺は日本人でつ。吾輩は猫である。"
という文字列を str2 とします。
str2 に対して,下記の正規表現を実行します。
/(?:吾輩)は(.+)で(?:.+)。/g
この記法の場合,正規表現の実行結果として抽出される部分文字列をすべて列挙すると
_______________ となります。
(問4)
(3)で現れた記法のことを,(2)と対比して
「 _____________ 」 といいます。
(問5)
str2 に対して,下記の正規表現を実行します。
/[^は]+で(?=つ)/g
この記法の場合,正規表現の実行結果として抽出される部分文字列をすべて列挙すると
_______________ となります。
(問6)
(5)で現れた記法のことを,
「 _____________ 」 といいます。
(問7)
JavaまたはJavaScriptに関する記述を含む,下記のような複数の文字列があります。
"私はJavaプログラマだ。"; "あなたはJavaScriptプログラマだ。"; 〜その他〜
これらの文字列の中から,Javaに言及している文字列だけを取捨選択したいとします。
JavaScriptに言及している箇所は無視する必要があります。
その場合,各文字列に対して,下記の正規表現を実行します。
/_________/g
(問8)
(7)で現れた記法のことを,
「 _____________ 」 といいます。
(問9)
ある文字列が,「4ケタの同じ数字を2回繰り返したもの」にマッチするかどうかを判定します。
例えば,「12341234」や「09870987」がマッチします。
その場合,下記の正規表現を実行します。
/_________/g
(問10)
(9)で現れた記法のことを,
「 _____________ 」 といいます。
=== 試験はここまでです。終了後,答案を速やかに提出して下さい。 ===
↑↑ ここから上を印刷して使う。
模範解答とサンプルコード
(1)
〒([0-9]{3})-([0-9]{4})
(2)
括弧によるキャプチャ
※キャプチャという語を使った回答ならOK。
(3)
猫
(4)
キャプチャしない括弧
※類似表現を使った回答ならOK。
(5)
日本人で
※(?=〜)とすると,「後ろに〜が続くもの」だけがキャプチャされる。
(6)
肯定的前方先読み
※または,「ゼロ幅の肯定的先読み」など。
(7)
Java(?!Script)
※(?!〜)とすると,「後ろに〜が続かないもの」だけがキャプチャされる。
(8)
否定的前方先読み
※または,「幅ゼロの否定先読み」など。
(9)
(\d{4})\1
※「\1」は,1個目にキャプチャした括弧の中身を参照できる。
※\d は [0-9] でもOK。
(10)
後方参照
※前方参照でもOK。
回答はここまで。
この回答が正常に動作することを実証するためのサンプルコードを下記に示す。
下記コードを hoge.js で保存して,ダブルクリックすればよい。
(WSH/JScriptとしてすぐに実行される。)
function log( s ){ WScript.Echo( s ); } // 括弧によるキャプチャ /〒([0-9]{3})-([0-9]{4})/.test( "〒234-5678" ); log( RegExp.$1 ); log( RegExp.$2 ); // 234 // 5678 // キャプチャしない括弧 var str2 = "私は人間です。俺は日本人でつ。吾輩は猫である。"; var res = ( /(?:吾輩)は(.+)で(?:.+)。/g ).exec( str2 ); res.shift(); // 配列の先頭の要素は抽出文字列ではなく文字列全体なので削除 log( res.join( "," ) ); // 猫 // 肯定的前方先読み res = str2.match( /[^は]+で(?=つ)/g ); log( res.join( "," ) ); // 日本人で // 否定的前方先読み var s1 = "私はJavaプログラマだ。"; var s2 = "あなたはJavaScriptプログラマだ。"; res = s1.match( /Java(?!Script)/g ); log( res ); // Java res = s2.match( /Java(?!Script)/g ); log( res ); // null // 後方参照または前方参照 var s3 = "12341234"; var s4 = "12345678"; res = s3.match( /(\d{4})\1/g ); log( res ); // 12341234 res = s4.match( /(\d{4})\1/g ); log( res ); // null
参考リンク
最低限,正規表現のマニュアルはちゃんと読んでからプログラミングしてもらおう。
JavaScript正規表現メモ。
http://d.hatena.ne.jp/koseki2/2009053...
- 前提事項のまとめ
RegExp
https://developer.mozilla.org/ja/Core...
- マッチしたものを記憶する括弧のことを,キャプチャする括弧 (capturing parentheses) と呼ぶ
- マッチしても記憶しないのはキャプチャしない括弧 (non-capturing parentheses)
正規表現の解説 上級編
http://www4.ocn.ne.jp/~kaerume/k2e/re...
- PerlやK2Editorでも利用可能な正規表現
- 「(?=pattern)」はゼロ幅の肯定的先読み表現
正規表現で特定の単語を除外したい
http://oshiete.goo.ne.jp/qa/1547202.html
- java(?!script) javaにマッチしてjavascriptにマッチしない。「幅ゼロの否定先読み」という呼び方
ある文字列の左側じゃない(否定)
http://yakinikunotare.boo.jp/orebase/...
- (?!hoge)
JavaScriptの動かないコード (中級編) 正規表現で同じ文字の連続を検出したい - 置換前パターン中での後方参照
http://language-and-engineering.hatenablog.jp/entry/20080927/1222508705
- 括弧でキャプチャ済みの文字列を,評価時に「\1」で参照
- 評価の終了後には「$1」で参照
正規表現の解説 初級編
http://www4.ocn.ne.jp/~kaerume/k2e/re...
- 後方参照(前方参照):グループにマッチした文字列を参照すること。
- ‘後方参照’は‘前方参照’と表現がされる場合があり,同じ事を指す。
- 「マッチした文字列を後から参照する(後ろから参照する)」から‘後方参照’とも呼ぶ。
- 「前にマッチした文字列を参照する(前の方を参照する)」から‘前方参照’とも呼ぶ。
関連する記事:
JavaScriptの動かないコード (中級編) splitで文字列を分割する時のエラー
http://language-and-engineering.hatenablog.jp/entry/20080925/1222262850
JavaScriptの動かないコード (中級編) オブジェクトのプロパティ定義にthisを使って失敗するエラー
http://language-and-engineering.hatenablog.jp/entry/20090221/p1
あなたが理解できない,たった一行のRubyのコード (動的言語に対する静的解析の限界)
http://language-and-engineering.hatenablog.jp/entry/20120619/p1
Word文書を解析して,英単語の出現回数を統計出力するバッチ (英文の用語索引を自動生成)
http://language-and-engineering.hatenablog.jp/entry/20120808/WordCountProgram