Upload
y-torazuka
View
730
Download
1
Embed Size (px)
DESCRIPTION
社内読書会での発表資料。
Citation preview
7章 正規表現『JavaScript The Good Parts』読書会
2013/04/11 @torazuka
(おまけ)実行環境
• Node.js
• mocha
• expect.js
• Sublime Text 2
•サンプルコード• https://bitbucket.org/torazuka/learning_jsgp
今回の範囲「7章正規表現」
7.1 正規表現の例7.2 正規表現の構築7.3 正規表現の構成要素
JavaScriptの正規表現
regexp.execregexp.teststring.matchstring.replacestring.searchstring.split → くわしくは8章で
文字列操作より正規表現を使った方がパフォーマンスが良いことが多い
正規表現が利用できるメソッド
正規表現はメンテナンスやデバッグが難しくなりやすいため,本章では著者が単純化したルールを紹介する簡潔さを多少犠牲にする代わりに,多少簡単に扱えるように
7.1正規表現の例 (その1)
/^(?:([A-Za-z]+):)?(¥/{0,3})([0-9.¥-A-Za-z]+)(?::(¥d+))?(?:¥/([^?#]*))?(?:¥?([^#]*))?(?:#(.*))?$/
1行で記述する (上の正規表現リテラルは本来1行で書く)
空白が意味を持つ (テキトーに空白を入れてはいけない)
URIをマッチするための正規表現:
7.1正規表現の例―全体
/^(?:([A-Za-z]+):)?(¥/{0,3})([0-9.¥-A-Za-z]+)(?::(¥d+))?(?:¥/([^?#]*))?(?:¥?([^#]*))?(?:#(.*))?$/
/…/が正規表現の全体
^は文字列のはじまり,$は文字列のおわり余計なものが最初,あるいは最後に付いていないことを保証する
(…)はキャプチャグループマッチした文字列を配列に格納する.最初のindexは1キャプチャグループ末尾の?は,そのキャプチャグループを省略可能という意味
7.1正規表現の例― http:
/^(?:([A-Za-z]+):)?(¥/{0,3})([0-9.¥-A-Za-z]+)(?::(¥d+))?(?:¥/([^?#]*))?(?:¥?([^#]*))?(?:#(.*))?$/
[…]は文字クラス
:はコロン文字
(?:…)は非キャプチャグループマッチした文字列を配列に格納しない.使わない文字列は,非キャプチャグループにするとパフォーマンス上よい
-は範囲を表わす.上の場合,AからZとaからzにマッチする
+は直前の文字クラスが1回以上出てくるときにマッチする
7.1正規表現の例― ///
/^(?:([A-Za-z]+):)?(¥/{0,3})([0-9.¥-A-Za-z]+)(?::(¥d+))?(?:¥/([^?#]*))?(?:¥?([^#]*))?(?:#(.*))?$/
{0,3}は直前の文字が0回,1回,2回,3回連続するとマッチする
(…)はキャプチャグループ
¥/はスラッシュ文字正規表現の終わりでないことを示すためエスケープする
7.1正規表現の例― www.ora.com
/^(?:([A-Za-z]+):)?(¥/{0,3})([0-9.¥-A-Za-z]+)(?::(¥d+))?(?:¥/([^?#]*))?(?:¥?([^#]*))?(?:#(.*))?$/
(…)はキャプチャグループ
.はピリオド文字¥-はハイフン文字範囲を表わすハイフンでないことを示すためエスケープする
+は直前の文字クラスが1回以上出てくるときにマッチする
7.1正規表現の例― :80
/^(?:([A-Za-z]+):)?(¥/{0,3})([0-9.¥-A-Za-z]+)(?::(¥d+))?(?:¥/([^?#]*))?(?:¥?([^#]*))?(?:#(.*))?$/
(?:…)は非キャプチャグループ末尾に?があるので省略可能
2つ目の:はコロン文字
+は直前の文字クラスが1回以上出てくるときにマッチする
¥dは数字
7.1正規表現の例― /goodparts
/^(?:([A-Za-z]+):)?(¥/{0,3})([0-9.¥-A-Za-z]+)(?::(¥d+))?(?:¥/([^?#]*))?(?:¥?([^#]*))?(?:#(.*))?$/
(?:…)は非キャプチャグループ末尾に?があるので省略可能
¥/はスラッシュ文字
*は直前の文字クラスの0回または1回以上の繰り返しにマッチする
^?#は「?と#を除くすべての文字」
7.1正規表現の例― ?q
/^(?:([A-Za-z]+):)?(¥/{0,3})([0-9.¥-A-Za-z]+)(?::(¥d+))?(?:¥/([^?#]*))?(?:¥?([^#]*))?(?:#(.*))?$/
(?:…)は非キャプチャグループ末尾に?があるので省略可能
¥?は?文字
*は直前の文字クラスの0回または1回以上の繰り返しにマッチする
^#は「#を除くすべての文字」
7.1正規表現の例― #fragment
/^(?:([A-Za-z]+):)?(¥/{0,3})([0-9.¥-A-Za-z]+)(?::(¥d+))?(?:¥/([^?#]*))?(?:¥?([^#]*))?(?:#(.*))?$/
(?:…)は非キャプチャグループ末尾に?があるので省略可能
#はシャープ文字
*は直前の文字クラスの0回または1回以上の繰り返しにマッチする
.は「改行文字以外のすべての文字」
7.1正規表現の例―良い正規表現
正規表現の機能は,各処理系の間で互換性が低い入れ子部分の実行速度が遅い処理系もある複雑さを避けることは大事
• 短く,シンプルに• 正しく動くと確信できる• 必要なときに修正できる
7.1正規表現の例 (その2)
/^-?¥d+(?:¥.¥d*)?(?:e[+¥-]?¥d+)?$/i
さっきより短い!ガンバ!
数字をマッチするための正規表現:
7.1正規表現の例 (その2)
/^-?¥d+(?:¥.¥d*)?(?:e[+¥-]?¥d+)?$/i
/^…$/でテキスト全体が正規表現の適用範囲となる“もしこれらを付けなかった場合は、この正規表現は文字列の中に数値が含まれているかどうかを調べるものになる”
iはアルファベットの大文字小文字を区別しないためのフラグここでは,eとEを両方マッチさせるために使っている[Ee]や(?:E|e)でも同じことができるが,iフラグを使う方が簡潔
7.1正規表現の例 (その2)
/^-?¥d+(?:¥.¥d*)?(?:e[+¥-]?¥d+)?$/i
-?は,ハイフン文字を省略できるという意味
¥dは数字. [0-9]と同じ
+は直前の文字クラスが1回以上出てくるときにマッチする
7.1正規表現の例 (その2)
/^-?¥d+(?:¥.¥d*)?(?:e[+¥-]?¥d+)?$/i
¥. はピリオド文字.ここでは小数点にマッチさせる意図
¥dは数字
*は直前の文字クラスの0回または1回以上の繰り返しにマッチする
(?:…)は非キャプチャグループマッチした文字列を配列に格納しない.
7.1正規表現の例 (その2)
/^-?¥d+(?:¥.¥d*)?(?:e[+¥-]?¥d+)?$/i
+¥-は正負記号
¥dは数字
(?:…)は非キャプチャグループ
eはアルファベットのe
+は直前の文字クラスが1回以上出てくるときにマッチする
7.2正規表現の構築
RegExpオブジェクトを生成する方法
1. 正規表現リテラルを利用 (推奨)2. RegExpコンストラクタ関数を利用
プログラミング時に確定できないデータを使って,実行時に正規表現を生成する場合に便利
• 2の方法を使うとき,バックスラッシュとダブルクォーテーションとクォーテーションは,エスケープする必要がある
• 同じ正規表現リテラルで生成されたRegExpオブジェクトは,単一のインスタンスを共有する
留意点
7.2正規表現の構築
正規表現リテラルのフラグ• g 複数回マッチする• i大文字と小文字を区別しない• m ^と$が行末記号にマッチする ?
RegExpオブジェクトのプロパティ
• global(役割はフラグgに同じ)• ignoreCase(フラグiに同じ)• muitiline(フラグmに同じ)• lastIndex次回のexecメソッドのマッチの開始点.初期値は0• source ソース文字列
複数行に渡るマッチ対象を扱える(例: import文や設定ファイルなど)
7.3正規表現の構成要素
7.3.1 選択肢
7.3.2正規表現シーケンス
7.3.2正規表現シーケンス
7.3.3正規表現因子
7.3.3正規表現因子
7.3.1 選択肢
|(タテ棒)で分割された1つ以上の正規表現シーケンスが,選択肢を構成するいずれかのシーケンスにマッチするとき,その正規表現にマッチする書かれた順にチェックされる
7.3.2 正規表現シーケンス
1つ以上の正規表現因子が,正規表現シーケンスを構成する
因子がいくつ続くかを数量詞で示す(c.f. 7.3.8)数量詞が指定されていないときは1個とみなす
7.3.3正規表現因子
• 文字• カッコで囲まれたグループ• 文字クラス• エスケープシーケンス
数字とアルファベット以外は,直前に¥をつけることで,その文字自身とみなす
ピリオド,キャロット,ドル文字は,エスケープしない場合に次の意味を持つ
• . 改行文字以外の文字• ^ lastIndexが0 のとき,テキストの先頭部分にマッチする
mフラグがセットされているときは,改行文字にもマッチする• $ テキストの末尾部分にマッチする
mフラグがセットされているときは,改行文字にもマッチする
7.3.4エスケープ
• ¥f改ページ• ¥n改行文字• ¥r キャリッジリターン• ¥t タブ文字• ¥u ユニコード文字の16進数表現• ¥b バックスペース
• ¥d数字,¥D数字以外• ¥s空白文字,¥S 空白文字以外
• ¥w [0-9A-Za-z_]と同じ• ¥b 単語境界
多言語アプリケーションでは実用的でないので,用途に応じたものを自分で定義する(¥wと¥bは良いパーツではない)
• ¥1第1番目のキャプチャグループ
7.3.5正規表現グループ
• キャプチャグループ(...) マッチした文字列はキャプチャ(配列に格納)される• 非キャプチャグループ(?:...) されない
• 肯定先読み(?=...) グループにマッチした後,走査位置を巻き戻す• 否定先読み(?!...) グループのマッチに失敗した場合のみ走査を続行する
次の2つは「良いパーツ」ではない
→サンプルコード参照
7.3.6正規表現クラス
• [...] 文字のセットを表わす
• 簡潔に書ける
• (?:a|e|i|o|u)
• [aeiou]
• 文字の範囲を指定できる
• (?:!|"|#|¥$|%|&|'|¥(|¥)|¥*|¥+|,|-|¥.|¥/|:|;|<|=|>|@|¥[|¥¥|]|¥^|_|` |¥{|¥||¥}|~)
• [!-¥/:-@¥[-`{-~]
• 補集合を表現できる
• [^ではじめる
便利な点
7.3.7正規表現クラスにおけるエスケープ
「正規表現因子におけるエスケープ」との違いに注意
¥bはバックスペースを表わす
次の文字は正規表現クラスの中ではエスケープしなければならない
- / [ ¥ ] ^
7.3.8数量詞
正規表現因子の後につけて,因子がいくつ連続したときにマッチするかを示す
マッチの処理は貪欲.数量詞の後ろに?をつけると貪欲でなくなる
/www//w{3}/ // 上と同じ
/w{3, 6}/ // wが3~6回連続したときにマッチする/w{0,}/ // *と同じ/w{1,}/ // +と同じ