正規表現は2つの方法で生成できる。
/ /
で囲む(Rubyとほぼ同じ)。new Regxp('.*')
のように書く。
\
(または
‘¥’)の扱いが煩雑になる欠点もあり、動的にパターンを生成する必要がある場合を除いて、リテラルを使う方が楽だろう。'abc'
typeof 'abc' // => String
/abc/
typeof /abc/ // => Object
/abc/.constructor.name // => 'RegExp'
RubyやPythonではすべてのデータがオブジェクトだが、JavaScriptではオブジェクトとプリミティブ型に分類される。
typeof 値
という式でそのデータがどんな種類であるかが得られる。
オブジェクトについては、constructor属性(これも何かのオブジェクト;実は関数)の、さらにname属性が、オブジェクトの種類を表す。
'abc'=='abc'
'abc'==='abc'
'abc'==/abc/
'abc'.match(/abc/)
/abc/.test('abc')
/abc/.exec('abc')
マッチングは(専用演算子はない)メソッドで行う。
String.prototype.match
:RegExpを渡し、結果の配列を返す。RegExp.prototype.test
:Stringを渡し、TrueまたはFalseを返す。RegExp.prototype.exec
:Stringを渡し、結果の配列またはnullを返す。以下のような式を、結果を予想しながらREPLに入れてみて下さい。
let s = "abc"
s.match(/a/)
s.match(/b/)
s.match(/.a/) # aの左に文字はない
s.match(/.b/) # . は a にマッチ
s.match(/./)
s.match(/.../)
s.match(/..../)
この先は主に1.を使った例を示す。
let s="abcde"
s.match(/a...e/)
s.match(/ab[cde]/
s.match(/a.*e/)
s.match(/^b/)
キャプチャの方法は他の多くの言語と同様、正規表現の中で後で(マッチ相手を)参照したい部分を
( )
で囲む。
後方参照の方法は2つ提供されている。
matchオブジェクト(実体は配列)の、0にマッチした全体、1以降に(括弧の数に応じて)キャプチャされた部分文字列(マッチ相手)が格納されている。
RegExpオブジェクトの属性にセットされる。RegExp.$1, RegExp.$2, ...
といったフィールド名でアクセスできる。
let peer='proxy:3128'
var host, port
// を前提として、
peer.match(/(\S+):(\d+)/) &&
([host,port] = [RegExp.$1, RegExp.$2])
// または
let r=peer.match(/(\S+):(\d+)/)
if(r) [host,port]=[r[1],r[2]]
let peer='proxy:3128'
// または正規表現を使わない書き方もある
peer.includes(':') &&
[host,port]=peer.split(':')
URLを分割するパターン:
var host,resource
let url='http://www2.nagano.ac.jp/hiraoka/NP/'
url.match(/\S+:\/\/(\S+?)(\/.*)/) &&
([host,resource]=[RegExp.$1, RegExp.$2])
/ /
で囲むが、パターンの中に文字としての’/‘を含む場合は、正規表現リテラル終了の’/’だと解釈されないよう\
を前置して「エスケープ」(特殊文字の意味をキャンセルさせる)する。