みこむらめもむらむらむら

なんかHTML5とかJS勉強とかやりながらめもを綴るブログ

【JavaScript】正規表現で文字を自在に指定する(RegExpオブジェクト)①

はい、やってまいりました正規表現
これ大事と云われていたのでがんばる


正規表現とは

たとえば下記文章から郵便番号だけ取り出したいとする

我が家の郵便番号は111-0500です。
引っ越す前は999-9763でした。

うむうむ

郵便番号自体はシンプルな文字列だが
番号だけを特定するには

  • 先頭から順番に文字を検索する
  • 数値が登場したら、その次とさらに次が数値であるか判定する
  • さらにその次は『-』であるか

のように延々と判定していく必要がある

このような煩雑な手続きを踏むことなく
あいまいな文字列パターンを表現できる記法が
正規表現(Redular Expression)である

たとえば郵便番号は
「0~9の数値3桁」+「-」+「0~9の数値4桁」
というパターンで表せる
正規表現にすると

[0-9]{3}-[0-9]{4}

これを指定し、元の文字列と比較することで
任意の文字列の中から特定のパターンを持つ文字列を
検索することができる

ほっほーうべんり!記法は後述とのこと

JavaScriptで利用が可能な主な正規表現

基本

  • ABC
    • 「ABC」という文字列
  • [ABC]
    • A、B、Cのいずれか1文字
  • [^ABC]
    • A、B、C以外のいずれか1文字
  • [A-Z]
    • A~Zの間の1文字
  • A|B|C
    • A、B、Cのいずれか

量指定

  • X*
    • 0文字以上のX("fe*"は"f"、"fe"、"fee"などにマッチ)
  • X?
    • 0、または1文字のX("fe?"は"f"、"fe"にマッチ"fee"にはアンマッチ)
  • X+
    • 1文字以上のX("fe+"は"fe"、"fee"などにマッチ、"f"にはアンマッチ)
  • X{n}
    • Xとn回一致("[0-9]{3}"は3桁の数字)
  • X{n,}
    • Xとn回以上一致("[0-9]{3,}"は3桁以上の数字)
  • X{m,n}
    • Xとm~n回一致("[0-9]{3,5}"は3~5桁の数字)

位置指定

  • ^
    • 行の先頭に一致
  • $
    • 行の末尾に一致

文字セット

  • .
    • 任意の1文字に一致
  • \w
    • 大文字/小文字の英字、数字、アンダースコア(_)に一致("[A-Za-z0-9]"と同意)
  • \W
    • 文字以外に一致("[^\w]"と同意)
  • \d
    • 数字に一致("[0-9]"と同意)
  • \D
    • 数字に一致("[^0-9]"と同意)
  • \n
    • 改行(ラインフィード)に一致
  • \r
    • 復帰(キャリッジリターン)に一致
  • \t
    • タブ文字に一致
  • \s
    • 空白文字に一致("[\n\r\t\v\f]"と同意)
  • \S
    • 空白以外の文字に一致("[^\s]"と同意)
  • \~
    • 「~」で表される文字

うおー暗記系だーあーあー

たとえば上記をもとにURLを表す正規表現を読み解いてみると‥

http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?
  • http(s)?://
    • 「(s)?」は「s」という文字が0または1回登場する、つまり「http://」か「https://」で始まることを表す
  • ([\w-]+\.)+[\w-]+
    • 英数字、アンダースコア、ハイフンで構成される文字列で、かつ途中にピリオドを含むことを表す
  • (/[\w- ./?%&=]*)?
    • 後続の文字列が英数字、アンダースコア、ハイフン、スラッシュ、ピリオド、その他特殊文字(?、%、&、=)で構成されうることを表す


お、おお‥(・∀・;)
わかった、何とかかろうじてわかった

これは慣れるしかなさそうだ‥
書いてある通りいろんな正規表現を見て
どういう意味かとかなんでそうなるかとかを考えないとだめだ‥
が、がんばります‥

RegExpオブジェクトを生成する方法

RegExpオブジェクトとは、JavaScript正規表現を解析し
文字列検索するための機能を提供する
生成する方法は大きく以下に分類できる

  1. Regオブジェクトのコンストラクタを経由する
  2. 正規表現リテラルを利用する

以下それぞれの構文

var 変数名 = new RegExp('正規表現', 'オプション');  //コンストラクタ
var 変数名 = / 正規表現/ オプション ;  //リテラル表現

正規表現リテラルでは、正規表現全体を
スラッシュ(/)で括らなければならない点に注意
「オプション」は正規表現の挙動を左右するパラメータで
以下のような値を指定できる

  • g
    • 文字列全体に対してマッチングするか(無指定の場合、1度マッチングした時点で処理を終了)
  • i
    • 大文字/小文字を区別するか
  • m
    • 複数行に対応するか(改行コードを行頭/行末と認識)

オプションを複数指定する場合には
"gi"のように並べて記述する

以上をふまえて
URL文字列にマッチングする
RegExpオブジェクトを生成してみると以下のようになる

var p = new RegExp('http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?', 'gi');
var p = /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/gi;

記法そのものについても以下の2つの違いがある

  1. コンストラクタ構文では「\」をエスケープする必要がある
    • コンストラクタ構文では正規表現は文字列として指定している
    • JavaScriptの文字列リテラルにおいて「\」は意味を持った予約字であるため、本来の正規表現パターンである「\w」を認識させるためには「\」を「\\」としてエスケープする必要がある
  2. 正規表現リテラルでは「/」をエスケープする必要がある

RegExpオブジェクトの設定

諸パラメータコンストラクタで指定するほか
各種プロパティ/メソッドでも設定できる
(ただし、一部のパラメータは参照のみで設定は不可)

  • sourse
    • 正規パターンの取得
    • 読み取り専用
  • global
    • グローバル検索("g"オプション)の有効/無効
    • 読み取り専用
  • ignoreCase
    • 大文字/小文字を区別するか("i"オプション)
    • 読み取り専用
  • multiline
  • input
    • 検索対象の文字列
    • 静的プロパティ
  • compile(pattern)


うむー、なんとなく、わかったような、わかってないような
とりあえず具体的にコード書かないとイメージしにくいなあ
次!