第7章   正規表現



やじゅ@静岡Developers勉強会
   正規表現の基礎
    基礎が分からないと本の内容が理解できない。

   正規表現の例
    7.1の例題を検証します。

   その他
    Javascript で正規表現を使うときの補足
   正規表現ってなに?

正規表現とは、簡単に言えば 検索や置換をより便利にするもの
です。
例えば文章中に 「りんご」 と 「みかん」 を検索したいとき、
別々に検索するのは手間だし面倒です。
正規表現で検索に使うキーワードを以下のように書くと

         りんご|みかん

「りんご」と「みかん」を同時に検索する事が出来ます。

javascript 正規表現 チートシート
http://visibone.com/products/bbk14-15_850.jpg
   「|」を使うと複数キーワードで検索できる
    ように、下記の特殊文字には役割がある。

    ¥ / [ ] - ( ) ? + * | . ^ $

正規表現では「メタ文字」と呼んでいる。
メタ文字自身を検索対象とする場合、¥を付ける
例 ¥¥ ,¥[ , ¥+

※メタ(meta-)とは、「高次な-」「超-」「-間の」「-を含んだ」
 「-の後ろの」等の意味の接頭辞。ギリシャ語から
   「.」 … とにかくなんでもいい1文字(改行以外)
    正規表現 み.ん
    対象文字 みかん みしん みりん

   「^」 … 先頭にマッチ  呼び名:ハット
    正規表現 ^みかん
    対象文字 みかん みかん みかん

   「$」 … 末尾にマッチ
    正規表現 みかん$
    対象文字 みかん みかん みかん
   「*」 … 直前の文字を0回以上にマッチ
    正規表現 おー*い    数量詞表現: おー{0,}い
    対象文字 おい おーい おーーい
   「+」 … 直前の文字を1回以上にマッチ
    正規表現 おー+い    数量詞表現: おー{1,}い
    対象文字 おい おーい おーーい
   「?」 …直前の文字を0回又は1回にマッチ
    正規表現 おー?い    数量詞表現: おー{0,1}い
    対象文字 おい おーい おーーい
   「.*」 … なんでもいい文字の連続(最長)
    正規表現 JR .*駅
    対象文字 JR静岡駅から浜松駅まで
    ※可能な限り合致するまでヒットする

   「.*?」 … なんでもいい文字の連続(最短)
    正規表現 JR .*?駅
    対象文字 JR静岡駅から浜松駅まで
    ※可能な限り少ない回数でヒットする
   「|」… いずれかの文字列 (論理和)
    正規表現 みかん|りんご
    対象文字 ばなな みかん ぶどう りんご
   「()」 … グループ化(先優先)
     ()を付けた場合の違い
    正規表現 私はみかん|りんごが好きです
    対象文字 私はみかんが好きです
         私はりんごが好きです

    正規表現 私は(みかん|りんご)が好きです
    対象文字 私はみかんが好きです
         私はりんごが好きです
   「{}」   … 数量詞
    正規表現   w{3}   直前の文字をn回にマッチ
    対象文字   www.ora.com/goodparts/ww
    正規表現   w{2,} 直前の文字をn回以上にマッチ
    対象文字   www.ora.com/goodparts/ww
    正規表現   w{0,3} 直前の文字をn回以上、m回以下にマッチ
    対象文字   www.ora.com/goodparts/ww
   「()」   … グループ化
    正規表現   (じゃ)+ーん
    正規表現   (じゃ){1,}ーん 数量詞に置き換えた場合
    対象文字   じゃーん じゃじゃーん
           じゃじゃじゃーん
   繰り返し回数
    正規表現 (みかん){2,4}
    対象文字 みかんみかんみかんみかんみかん
    指定した回数より多く繰り返している場合には
    繰り返し回数の上限までマッチする。
    正規表現 (みかん){2,4}
    対象文字 みかんみかんみかん
    可能な限り多い回数でマッチする。
    正規表現 (みかん){2,4}
    対象文字 みかんみかんみかんみかんみかんみかん
    5個以上は、パターンの繰り返しでマッチする。
   「[ ]」 …指定内の任意表現   呼び名:ブラケット
    正規表現 今日の天気は[晴曇雨]です
    対象文字 今日の天気は晴です
            今日の天気は曇です
           今日の天気は雨です
           今日の天気は雪です

   「[^ ]」 …指定内の任意以外表現
    正規表現 今日の天気は[^晴曇雨]です   (^が先頭)
    対象文字 今日の天気は雪です

※[ ]の中で ^ が使用された場合は、行の先頭を表す
  ^(ハット) とは意味が異なります。
[ ] と ( | ) の使い方を間違えた場合
 例    [りんご|みかん]
「り」「ん」「ご」「 | 」「み」「か」「ん」
のどれか一文字という意味になる。
   「[A - Z]」 … 英大文字AからZまで のどれか
   「[a-z]」 … 英小文字aからzまで のどれか
   「[0-9]」 … 数字0から9まで のどれか
   「[A - Za-z0-9]」 … 上記を連続して書ける
   「[あ-お]」 … あぃいぅうぇえぉお のどれか
   「[か-こ]」 … かがきぎくぐけげこ のどれか
   「[.*]」 … .か * のいずれかの文字。
    [ ]の中ではメタ文字は普通の文字として認識
    される文字もメタ文字ではない。
    (但し、先頭の^や ] や範囲指定の‐は例外)
   ¥w 英字、数字、アンダースコア。
       [a-zA-Z0-9_] に同じ。
   ¥W 英字、数字、アンダースコア以外の文字。
       [^a-zA-Z0-9_] に同じ。
   ¥d 数字。[0-9] に同じ
   ¥D 数字以外の文字。[^0-9] に同じ。
   ¥n 改行
   ¥s スペース。
   ¥S スペース以外の文字。
   日付を検索する
    正規表現 ¥d{4}¥/¥d{1,2}¥/¥d{1,2}
    対象文字 2011/08/20 2011/8/2
   郵便番号を検索する(厳密ではない)
    正規表現 ¥d{3}-¥d{4}
    対象文字 012-1234
   メールアドレスを検索する (厳密ではない)
    正規表現 ^[¥w_-]+@[¥w¥.-]+¥.¥w{2,}$
    対象文字 microsoft@e-mail.microsoft.com
   「/g」 … Global 複数回マッチする
    正規表現 /みかん/g
    対象文字 みかん りんご みかん
   「/i」 … Insensitive 大文字小文字を区別しない
    正規表現 /ABC/i
    対象文字 abcdef
   「/m」 … Multiline ^と$が行末記号にマッチ
    正規表現 /456/m
    対象文字 123¥n456¥n789      ¥n:改行
本の例題
var parse_url = /^(?:([A-Za-z]+):)?(¥/{0,3})([0-9.¥-A-Za-
z]+)(?::(¥d+))?(?:¥/([^?#]*))?(?:¥?([^#]*))?(?:#(.*))?$/;

var url = "http://www.ora.com:80/goodparts?q#fragment";var result =
parse_url.exec(url);

var names = ['url', 'scheme', 'slash', 'host', 'port', 'path', 'query', 'hash'];
var blanks = '     ';
var i;
for (i = 0; i < names.length; i += 1) {
   document.writeln(names[i] + ':' +
         blanks.substring(names[i].length), result[i]);
}
http://bit.ly/mZLwEJ   コピペ先
   url: http://www.ora.com:80/goodparts?q#fragment
   scheme: http
   slash: //
   host: www.ora.com
   port: 80
   path: goodparts
   query: q
   hash: fragment

result[0] には、対象文字列のURLがセット
   scheme: http
    正規表現 ^(?:([A-Za-z]+):)?
    結果 http

    「(?:)」… 非キャプチャグループ
    (…) で囲まれるとキャプチャグループに入る
    マッチした文字列をコピーし結果の配列に格納
     非キャプチャグループはグループ化だけを行う

    正規表現 ^(([A-Za-z]+):)? ?:を外す
    結果 http:             「:」 が入る
str = "http://www.ora.com:80/goodparts?q#fragment";
ret = str.match(/^(?:([A-Za-z]+):)?/)
alert("1番目:" + ret[0] + "¥n" +
      "2番目:" + ret[1] + "¥n");
   slash: //
    正規表現 (¥/{0,3})
    結果 //
   host: www.ora.com
    正規表現 ([0-9.¥-A-Za-z]+)
    結果 www.ora.com
   port: 80
    正規表現 (?::(¥d+))?
    結果 80
   path: goodparts
    正規表現 (?:¥/([^?#]*))?
    結果 goodparts
   query: q
    正規表現 (?:¥?([^#]*))?
    結果 q
   hash: fragment
    正規表現 (?:#(.*))?
    結果 fragment
   キャプチャ
xx = “12:34:56”.match(/(¥d+):(¥d+):(¥d+)/);
document.write(RegExp.$1 + “<br>”); // → 12
document.write(RegExp.$2 + “<br>”); // → 34
document.write(RegExp.$3 + “<br>”); // → 56
   非キャプチャ
xx = “12:34:56”.match(/(?:¥d+):(¥d+):(¥d+)/);
document.write(RegExp.$1 + “<br>”); // →34
document.write(RegExp.$2 + “<br>”); // → 56
   肯定先読み
alert(“abc”.replace(/ab(?=c)/,“@”));   // → @c
   否定先読み
alert(“abc”.replace(/ab(?!d)/,“@”));   // → @c
   [^ABC]*? … 文字1つ1つ を除外
    正規表現 JR[^静岡]*?駅
    結果 JR静岡駅 JR浜松駅 JR三島駅 JR岡山駅
    これだとJR岡山駅があると対象外となる

   ((?!ABC).)*? … 文字列 を除外 (?!ABC).*?変更
    正規表現 JR((?!静岡).)*?駅
    結果 JR静岡駅 JR浜松駅 JR三島駅 JR岡山駅
    これだとJR東静岡駅があると対象外となる
"abc123def".match(/(123)/);
document.write(RegExp.lastMatch + “<br>”);      // → 123
document.write(RegExp.leftContext + “<br>”);     // → abc
document.write(RegExp.rightContext + “<br>”);   // → def
document.write(RegExp.lastParen + “<br>”);      // → 123

lastMatch、leftContext、rightContext、lastParen は
それぞれ、$&、$`、$'、$+ の省略形を用いることもできます。

re = new RegExp("123");
"abc123def".match(re);
document.write(RegExp.index);               // → 3
document.write(RegExp.lastIndex);           // → 6
document.write(re.lastIndex);               // → 6
ご清聴ありがとうございましたm(_ _)m

JavaScriptの正規表現

  • 1.
    第7章 正規表現 やじゅ@静岡Developers勉強会
  • 2.
    正規表現の基礎 基礎が分からないと本の内容が理解できない。  正規表現の例 7.1の例題を検証します。  その他 Javascript で正規表現を使うときの補足
  • 3.
    正規表現ってなに? 正規表現とは、簡単に言えば 検索や置換をより便利にするもの です。 例えば文章中に 「りんご」 と 「みかん」 を検索したいとき、 別々に検索するのは手間だし面倒です。 正規表現で検索に使うキーワードを以下のように書くと りんご|みかん 「りんご」と「みかん」を同時に検索する事が出来ます。 javascript 正規表現 チートシート http://visibone.com/products/bbk14-15_850.jpg
  • 5.
    「|」を使うと複数キーワードで検索できる ように、下記の特殊文字には役割がある。 ¥ / [ ] - ( ) ? + * | . ^ $ 正規表現では「メタ文字」と呼んでいる。 メタ文字自身を検索対象とする場合、¥を付ける 例 ¥¥ ,¥[ , ¥+ ※メタ(meta-)とは、「高次な-」「超-」「-間の」「-を含んだ」 「-の後ろの」等の意味の接頭辞。ギリシャ語から
  • 6.
    「.」 … とにかくなんでもいい1文字(改行以外) 正規表現 み.ん 対象文字 みかん みしん みりん  「^」 … 先頭にマッチ 呼び名:ハット 正規表現 ^みかん 対象文字 みかん みかん みかん  「$」 … 末尾にマッチ 正規表現 みかん$ 対象文字 みかん みかん みかん
  • 7.
    「*」 … 直前の文字を0回以上にマッチ 正規表現 おー*い 数量詞表現: おー{0,}い 対象文字 おい おーい おーーい  「+」 … 直前の文字を1回以上にマッチ 正規表現 おー+い 数量詞表現: おー{1,}い 対象文字 おい おーい おーーい  「?」 …直前の文字を0回又は1回にマッチ 正規表現 おー?い 数量詞表現: おー{0,1}い 対象文字 おい おーい おーーい
  • 8.
    「.*」 … なんでもいい文字の連続(最長) 正規表現 JR .*駅 対象文字 JR静岡駅から浜松駅まで ※可能な限り合致するまでヒットする  「.*?」 … なんでもいい文字の連続(最短) 正規表現 JR .*?駅 対象文字 JR静岡駅から浜松駅まで ※可能な限り少ない回数でヒットする
  • 9.
    「|」… いずれかの文字列 (論理和) 正規表現 みかん|りんご 対象文字 ばなな みかん ぶどう りんご  「()」 … グループ化(先優先) ()を付けた場合の違い 正規表現 私はみかん|りんごが好きです 対象文字 私はみかんが好きです 私はりんごが好きです 正規表現 私は(みかん|りんご)が好きです 対象文字 私はみかんが好きです 私はりんごが好きです
  • 10.
    「{}」 … 数量詞 正規表現 w{3} 直前の文字をn回にマッチ 対象文字 www.ora.com/goodparts/ww 正規表現 w{2,} 直前の文字をn回以上にマッチ 対象文字 www.ora.com/goodparts/ww 正規表現 w{0,3} 直前の文字をn回以上、m回以下にマッチ 対象文字 www.ora.com/goodparts/ww  「()」 … グループ化 正規表現 (じゃ)+ーん 正規表現 (じゃ){1,}ーん 数量詞に置き換えた場合 対象文字 じゃーん じゃじゃーん じゃじゃじゃーん
  • 11.
    繰り返し回数 正規表現 (みかん){2,4} 対象文字 みかんみかんみかんみかんみかん 指定した回数より多く繰り返している場合には 繰り返し回数の上限までマッチする。 正規表現 (みかん){2,4} 対象文字 みかんみかんみかん 可能な限り多い回数でマッチする。 正規表現 (みかん){2,4} 対象文字 みかんみかんみかんみかんみかんみかん 5個以上は、パターンの繰り返しでマッチする。
  • 12.
    「[ ]」 …指定内の任意表現 呼び名:ブラケット 正規表現 今日の天気は[晴曇雨]です 対象文字 今日の天気は晴です 今日の天気は曇です 今日の天気は雨です 今日の天気は雪です  「[^ ]」 …指定内の任意以外表現 正規表現 今日の天気は[^晴曇雨]です (^が先頭) 対象文字 今日の天気は雪です ※[ ]の中で ^ が使用された場合は、行の先頭を表す ^(ハット) とは意味が異なります。
  • 13.
    [ ] と( | ) の使い方を間違えた場合 例 [りんご|みかん] 「り」「ん」「ご」「 | 」「み」「か」「ん」 のどれか一文字という意味になる。
  • 14.
    「[A - Z]」 … 英大文字AからZまで のどれか  「[a-z]」 … 英小文字aからzまで のどれか  「[0-9]」 … 数字0から9まで のどれか  「[A - Za-z0-9]」 … 上記を連続して書ける  「[あ-お]」 … あぃいぅうぇえぉお のどれか  「[か-こ]」 … かがきぎくぐけげこ のどれか  「[.*]」 … .か * のいずれかの文字。 [ ]の中ではメタ文字は普通の文字として認識 される文字もメタ文字ではない。 (但し、先頭の^や ] や範囲指定の‐は例外)
  • 15.
    ¥w 英字、数字、アンダースコア。 [a-zA-Z0-9_] に同じ。  ¥W 英字、数字、アンダースコア以外の文字。 [^a-zA-Z0-9_] に同じ。  ¥d 数字。[0-9] に同じ  ¥D 数字以外の文字。[^0-9] に同じ。  ¥n 改行  ¥s スペース。  ¥S スペース以外の文字。
  • 16.
    日付を検索する 正規表現 ¥d{4}¥/¥d{1,2}¥/¥d{1,2} 対象文字 2011/08/20 2011/8/2  郵便番号を検索する(厳密ではない) 正規表現 ¥d{3}-¥d{4} 対象文字 012-1234  メールアドレスを検索する (厳密ではない) 正規表現 ^[¥w_-]+@[¥w¥.-]+¥.¥w{2,}$ 対象文字 microsoft@e-mail.microsoft.com
  • 17.
    「/g」 … Global 複数回マッチする 正規表現 /みかん/g 対象文字 みかん りんご みかん  「/i」 … Insensitive 大文字小文字を区別しない 正規表現 /ABC/i 対象文字 abcdef  「/m」 … Multiline ^と$が行末記号にマッチ 正規表現 /456/m 対象文字 123¥n456¥n789 ¥n:改行
  • 18.
    本の例題 var parse_url =/^(?:([A-Za-z]+):)?(¥/{0,3})([0-9.¥-A-Za- z]+)(?::(¥d+))?(?:¥/([^?#]*))?(?:¥?([^#]*))?(?:#(.*))?$/; var url = "http://www.ora.com:80/goodparts?q#fragment";var result = parse_url.exec(url); var names = ['url', 'scheme', 'slash', 'host', 'port', 'path', 'query', 'hash']; var blanks = ' '; var i; for (i = 0; i < names.length; i += 1) { document.writeln(names[i] + ':' + blanks.substring(names[i].length), result[i]); }
  • 19.
  • 20.
    url: http://www.ora.com:80/goodparts?q#fragment  scheme: http  slash: //  host: www.ora.com  port: 80  path: goodparts  query: q  hash: fragment result[0] には、対象文字列のURLがセット
  • 21.
    scheme: http 正規表現 ^(?:([A-Za-z]+):)? 結果 http  「(?:)」… 非キャプチャグループ (…) で囲まれるとキャプチャグループに入る マッチした文字列をコピーし結果の配列に格納 非キャプチャグループはグループ化だけを行う 正規表現 ^(([A-Za-z]+):)? ?:を外す 結果 http: 「:」 が入る
  • 22.
    str = "http://www.ora.com:80/goodparts?q#fragment"; ret= str.match(/^(?:([A-Za-z]+):)?/) alert("1番目:" + ret[0] + "¥n" + "2番目:" + ret[1] + "¥n");
  • 23.
    slash: // 正規表現 (¥/{0,3}) 結果 //  host: www.ora.com 正規表現 ([0-9.¥-A-Za-z]+) 結果 www.ora.com  port: 80 正規表現 (?::(¥d+))? 結果 80
  • 24.
    path: goodparts 正規表現 (?:¥/([^?#]*))? 結果 goodparts  query: q 正規表現 (?:¥?([^#]*))? 結果 q  hash: fragment 正規表現 (?:#(.*))? 結果 fragment
  • 25.
    キャプチャ xx = “12:34:56”.match(/(¥d+):(¥d+):(¥d+)/); document.write(RegExp.$1 + “<br>”); // → 12 document.write(RegExp.$2 + “<br>”); // → 34 document.write(RegExp.$3 + “<br>”); // → 56  非キャプチャ xx = “12:34:56”.match(/(?:¥d+):(¥d+):(¥d+)/); document.write(RegExp.$1 + “<br>”); // →34 document.write(RegExp.$2 + “<br>”); // → 56  肯定先読み alert(“abc”.replace(/ab(?=c)/,“@”)); // → @c  否定先読み alert(“abc”.replace(/ab(?!d)/,“@”)); // → @c
  • 26.
    [^ABC]*? … 文字1つ1つ を除外 正規表現 JR[^静岡]*?駅 結果 JR静岡駅 JR浜松駅 JR三島駅 JR岡山駅 これだとJR岡山駅があると対象外となる  ((?!ABC).)*? … 文字列 を除外 (?!ABC).*?変更 正規表現 JR((?!静岡).)*?駅 結果 JR静岡駅 JR浜松駅 JR三島駅 JR岡山駅 これだとJR東静岡駅があると対象外となる
  • 27.
    "abc123def".match(/(123)/); document.write(RegExp.lastMatch + “<br>”); // → 123 document.write(RegExp.leftContext + “<br>”); // → abc document.write(RegExp.rightContext + “<br>”); // → def document.write(RegExp.lastParen + “<br>”); // → 123 lastMatch、leftContext、rightContext、lastParen は それぞれ、$&、$`、$'、$+ の省略形を用いることもできます。 re = new RegExp("123"); "abc123def".match(re); document.write(RegExp.index); // → 3 document.write(RegExp.lastIndex); // → 6 document.write(re.lastIndex); // → 6
  • 28.