文字列 a の中で、「1 □ 3」のような並びを見つける。
=~
演算子はないので、メソッドでマッチングを行う。var s="abcde12345"
s.search(/1.3/) // => 0 // 見つかれなければ -1
s.match(/1.3/) // => [ ... ] // マッチ失敗なら null
/1.4/.test(s) // => false
/1.4/.exec(s) // => null // マッチすれば.matchと同様の配列を返す
? :
などの条件式に使うとうまくいかないので注意 (if( s.match(/1.3/ >= 0) ...
のように使うことになる)。正規表現の体系は言語によらずほぼ同じ(Unixで使われ始め、Perl言語で充実された、 その流れを汲んでいるという点で共通なので)。
/abc/i
のように閉じスラッシュの後ろに置く文字)も概ね同じ。JSでは(RegExpオブジェクト生成時には文字列の形から出発するが) 正規表現リテラルの記法としては / /
で囲む記法だけであり、 %記法のような複雑化回避策がないので、正規表現の中に ‘/’ を含ませるためには バックスラッシュでエスケープするしかない。
”alphabet” =~ /ab/
// 文字列の中に ab という文字の並びがあるかどうか
var s="abcde"
s.search(/a/) // => 0 a が見つかる(0文字目に)
s.search(/ef/) // => 4
s.search(/x/) // => -1 見つからない(マッチしない)
まず準備:
WORDS.txtを読み込んで、各行の内容(単語)を要素とする配列を作っておき (変数 w に文字列の配列が設定されることになる)、 これを使って以降の練習を試みる。
var w
require('fs').
readFile('WORDS.txt','utf-8',(err,txt)=>{
w=txt.split(/\r?\n/)
})
JSには RubyのArray#grep に相当するものはないので、
w.filter(e=>e.match(/^a/))
のように(若干面倒だが)関数を渡してfilterを動作させる、か、
const grep=(a,rgx)=>a.filter(e=>e.match(rgx))
を予め定義しておいて、
grep(w,/^a/)
と呼び出す使い方になるだろう。
なお、上の grep は、
function grep(a,rgx) {
return a.filter(e=>e.match(rgx))
}
と定義してもいい。
また、
Array.prototype.grep = function (rgx) {
return this.filter(e=>e.match(rgx))
}
と定義すると、
w.grep(/^a/)
のように本編(Rubyを使う)と同様の呼出し方ができる(下の練習ではこれを使って書く)。
node.js は、非常に長い配列を値として出力しそうになると、
... 23902 more items
]
のように省略を試みるが、それでも長い出力が煩わしいときには、
w.grep(/^a/).length
で、とりあえず長さ(マッチした数)を出力させるといい。
以下の条件を満たす単語がいくつあるか調べて見る(前節の w から出発したコードを示す)。
10文字の単語(11 12等についても)
or 10文字以上の単語
すべて大文字から成る単語
数字を含む単語
英数字以外の文字を含むもの
e(E) で始まりe(E)で終わるもの(ケースを区別しないマッチ)
最初の文字と最後の文字が同じもの
最後の2文字が最初の2文字の逆転になっているもの
barbar のように 同じ並びの繰り返しになっている単語
正規表現の練習については、本編に示した解答例(の正規表現)が RubyでもJavaScriptでもそのまま当てはまるので、そちらを参照いただくことにしてここでは省略する。