正規表現 入門

2,176
-1

Published on

姫路IT系勉強会で発表した内容に加筆・修正を加えたものです.

Published in: Technology
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,176
On Slideshare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
25
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide

正規表現 入門

  1. 1. 正規表現 入門 2013.9.21 @姫路IT系勉強会 Vol.20 @spark6251 (N@N)
  2. 2. 自己紹介 • N@N(@spark6251) • N@N→NOaN→NOAN→ノアン • 明石高専 電気情報工学科四年生 • プログラミングあんまりしてない • たぶんWeb屋
  3. 3. 内容 • 正規表現基礎 • 実用例 • 有限オートマトン • 正規表現の動作原理 • まとめ
  4. 4. 1. 正規表現基礎 • 基本的な正規表現の文法を学ぶ • 問題解決の手法の探索
  5. 5. 目的 • 特定の条件で置換したいとか • 指定した行のテキストだけ出力したいとか • 検索したいとか • 基礎を覚えるだけでも(それなりに広い場所 で)かなり使えるのが正規表現(つよい)
  6. 6. マッチする • .は”任意の1文字にマッチする” • match:釣り合う,相当する. • 意味合い的には一致するが近い • ”一致する”では双方向 • ”マッチする”は片方向
  7. 7. 正規表現とは • 様々な用途に対応できるパターン言語 • パターン言語はパターンを要素とした規則シス テムのようなもの • その言語とパターンそのものが正規表現
  8. 8. 構成 • メタ文字:特殊な意味を持つもの.*とか?とか • リテラル:literal.普通の文字.大文字小文字 は区別される • ファイル名パターンでは*(ワイルドカード)など が存在するが正規表現との違いはメタ文字によ る表現力の差である • Regular expressions are easy!
  9. 9. egrep • 単純なテキストの検索 • 単語とか行だとかは認識しない • 各ファイルの各行でマッチする部分が見つかっ た行を表示する • 最初の引数を文字列パターン,以下の引数を ファイルと認識する.正規表現を使用するなら'' で囲む $ egrep [option] 'regex' file1 file2...
  10. 10. 郵便番号 • テキストから郵便番号を取得したい $ egrep '[0-9]{3}-?[0-9]{4}' file01 • 実際に使用されているのは1000万の内14万程度 • 判別するには何らかのvalidatorが必要 • Number::ZipCode::JPを使いましょう(投げや り)
  11. 11. メタ文字 • 次のページから正規表現のメタ文字についての 解説 • 正規表現を文字通りに解釈する癖を付けよう • 本質的な理解に繋がる • 例,文字通りの解釈,わかりやすい解釈と表記 (一部除く) • また,...は…と同じ扱いとする
  12. 12. 行頭マッチ • ^ • 文字列の先頭と一致 • '^cat' • 行頭があって,その次がc,その次がa,その次 がtになっている行にマッチする • 行頭がcatになっている行にマッチする
  13. 13. 行末マッチ • $ • 文字列の末尾と一致 • 'cat$' • cがあって,その次がa,その次がt,その次が行 末になっている行にマッチする • 行末がcatになっている行にマッチする
  14. 14. 行頭と行末 • '^$' • 行頭の次に行末が続くならマッチする • 空行 • '^cat$' • 行頭の次にc,a,tと続きその次に行末が続くな らマッチする • catだけの行
  15. 15. 行頭と行末 • '^' • 行頭があるならマッチする • 全ての行にマッチする • '$' • 行末があるならマッチする • 全ての行にマッチする
  16. 16. 文字クラス • [...] • 複数の文字のどれか1つにマッチする • 'gr[ae]y' • gの次がr,その次がaかeで,その次がyなら マッチする • grayとgreyにマッチする • gray(主に米),grey(主に英)
  17. 17. 文字クラス • -を使って範囲を示すことができる • '[0123456789]' = '[0-9]' • '[ABCDE...Z]' = '[A-Z]' • '[abcde...z]' = '[a-z]' • '[012...9ABCDEFabcdef]' = '[0-9A-Fa-f]' • 文字クラス内ではメタ文字が異なる • 人名として'[Ss]mith'とした場合blacksmithな どの関係ないものにもマッチすることに注意
  18. 18. 否定文字クラス • [^...] • 含まれていない任意の文字にマッチする • 含まれていなければマッチではないことに注意 (そうだと空行にもマッチしてしまう) • '[^0-9]' • 0か1か2か…9が入っていない任意の文字に マッチする • 数字が入っていない任意の文字にマッチする
  19. 19. egrepの仕様 • $ egrep 'A[^B]' file01 • TAにはマッチしない • Aの次には改行文字が続く • egrepは仕様で正規表現の前に改行文字を取り 除く
  20. 20. 任意の1文字にマッチ • . • 任意の1文字にマッチする • 'A.B' • Aの次に何かしらの文字があって,その次にBが ある
  21. 21. 部分のどれかにマッチ • | • 'or'の意.複数の正規表現を組合せてどれかと マッチする正規表現にする • 'gr[ae]y' = 'gr(a|e)y' = 'gray|grey' • 'gra|ey'はgraとeyにマッチする • '[a|e]'ではa,|,eにマッチする
  22. 22. 大文字小文字の無視 • -iオプション • egrepのオプション • 他の言語の正規表現でもiは大文字小文字を無視 するオプションとなる $ egrep -i 'from|to' file = $ egrep '[Ff][Rr][Oo][Mm]|[Tt][Oo]' file
  23. 23. 単語 • ¥<string¥> • egrepでは精々文字と数字の並びを認識する • the quick brown_ fox's $190.3? $!?. • 赤字が単語と認識される部分である
  24. 24. 量指定子:オプション • ? • colou?rはc, o, l, o, u?, rならマッチ • u?は常に成功する • 直前のサブ式(要素)と0回または1回マッチ • 'colou?r' • colorとcolourにマッチ • '1st|1' = '1(st)?'
  25. 25. 量指定子:繰り返し • + • 直前のサブ式と1回以上マッチ • * • 直前のサブ式と0回以上マッチ • 'A+' = 'AA*' • 'AA*' ≠ '(AA)*'
  26. 26. エスケープ • ¥char • メタ文字をリテラルとして扱う • '¥.' • .にマッチする
  27. 27. egrep - 正規表現 ^ 行頭マッチ $ 行末マッチ . 任意の1文字にマッチ [ABC] A, B, Cのいずれかにマッチ [^ABC] A, B, Cいずれでもないものにマッチ [A-Z] A~Zのいずれかにマッチ [^A-Z] A~Zのいずれでもないものにマッチ c1|c2 c1, c2のいずれかにマッチ
  28. 28. egrep - 正規表現 + 1回以上の繰り返し * 0回以上の繰り返し ? 0回以上1回以下の繰り返し {n} n回繰り返し {n,} n回以上繰り返し {,m} m回以下繰り返し {n,m} n回以上m回以下繰り返し () 範囲の限定 ¥char charをエスケープ
  29. 29. 1. まとめ • 正規表現は非常に便利なツールである • egrepは簡易に検索を行うことができるが正規 表現としては弱い(表で全部ではない,はず) • 正規表現の基礎は大体こんな感じ • 方言が豊富なので簡単に話せない(つらい) • 正規表現で遊びたければPerlを使おう!
  30. 30. 2. 実用例 • 注意:Perl5とかの話
  31. 31. テキストエディタで置換 • notepadでは正規表現による置換はできない • notepad++とかgedit(プラグイン)だとか秀 丸エディタだとかの(まともな)テキストエ ディタにはあるので使おう
  32. 32. Perlで正規表現 • マッチ(mは省略可) • m/regex/mods • 置換 • s/regex/replacement/mods • パターンマッチ演算子 • value =~ /regex/mods • マッチすれば1,しなければ"" • if文で特定の奴のみ……とか
  33. 33. 修飾子(mods) • /i 大文字小文字無視 • /x フリーフォーマット(文字クラス外の空白無 視) • /g 繰り返しマッチ
  34. 34. 後方参照 • 後方参照自体はただの正規表現 • カッコでグループ化した文字列を後に参照 • ¥<(.*?)>.*?</¥1>¥ • <a>sdad</a>や<list>dfasj</list>にマッチ
  35. 35. 特殊変数 • 正規表現外で参照 if($str =~ /(.*)?/) { print $1; # ()の中身 }
  36. 36. Perlワンライナー $ perl [option] '[perlScript]' file01 • -e:文字列をスクリプトとして実行 • -n:1行ずつ処理 • -p:出力 • -l:強制改行 • -i:出力先を入力ファイル自身にする
  37. 37. バックアップ $ perl -i'*.back' -e '[perlScript]' file
  38. 38. 一括置換 $ find . -type f -print0 | xargs -0 sed -i -e 's/foo/bar/g' gitにも対応させたい $ git grep -l 'foo' | xargs -0 sed -i -e 's/foo/bar/g' $ git ls-files -z | xargs -0 sed -i -e 's/foo/bar/g' findを使うと.gitを巻き込むっぽい
  39. 39. 3. 有限オートマトン • モデルの一つ • 有限個の”状態”の内1つの状態を取り,条件等に より他の状態に移動することを”遷移”という • 様々な分野に応用されている • 正規表現エンジンにも関わるので紹介 • 深夜テンションで作ってたのでこのへんからお かしくなりだした
  40. 40. オートマトンとは • 自動羊肉
  41. 41. オートマトンとは • automaton:自動(制御)装置 • 自動で動く機械を”状態”と”遷移”という考え方で 理解し設計に応用しようというもの • 入力の最後で決められた状態(つまり成功)を ”受容”や”受理” • (状態と遷移の概念さえ理解すればオートマト ンの基礎的な話は終わってしまう(!))
  42. 42. 有限オートマトンの分類 • 更に2種類に分類できる • 決定性有限オートマトン (Deterministic Finite Automaton:DFA) • 非決定性有限オートマトン (Nondeterministic Finite Automaton:NFA) • 説明は後に譲る
  43. 43. 状態 • 例えば健康状態(良好,普通,不調) • 例えば気温(30℃,29℃,28℃) • 例えば自販機に入れた金額(100円,110円) • 感覚的に理解してしまえば良い,とりあえず状 態である
  44. 44. 遷移 • 良好→普通 • 29℃→30℃,29℃→28℃ • 100円→110円 • イベントや条件によってある状態から別の状態 に移動することを遷移という
  45. 45. 状態遷移図 • 有限オートマトンをグラフィカルにしたもの • DFA,NFA,ムーア・マシンで用いる状態遷移 図とミーリ・マシンで用いる状態遷移図がある • 0を出力するアイドル状態からスタートボタン を押すとLEDが”点灯し1を出力”,以降はスイッ チの入力によって”消灯し0を出力”,”点灯し1を 出力”を繰り返すもので状態遷移図を描く • 状態と遷移が定義されたものを状態機械という • 正規表現に関わるのはムーア・マシンのものの みなのでミーリ・マシンのものについては割愛
  46. 46. ムーア・マシン アイドル 0 スタート LED点灯 1 LED消灯 0 スイッチ スイッチ
  47. 47. 言語 • 文字列の集合を言語という(ここで言う集合は 数学的な集合) • つまり文字列が言語に所属するか判定可能 • 英語は複雑なので状態機械を用いる • 次に例を示す
  48. 48. 状態機械の例 • abcという文字列からなる言語 • {abc} • abcとxyzという文字列からなる言語 • {abc, xyz} • 3文字以上のaからなる全ての文字列 • {aaa, aaaa, aaaaa...} • abもしくはcdが2回以上繰り返される文字列か らなる言語 • {abab, abcd, cdcdcd...}
  49. 49. 正規言語 • 大体先ほどの操作で得られる言語を正規言語と いう.正確には以下の性質を満たすものである • DFAによって受理可能 • NFAによって受理可能 • 正規表現で記述可能 • 正規文法から生成可能 • 読み取り専用チューリングマシンで受理可能 • 以上5項目は全て等価である
  50. 50. 特殊な文字列 • 空文字列 • 長さが0の文字列 • λやεで表記.本スライドではεで統一 • 空言語(くうげんご) • 数学的な集合の空集合に相当 • φ • 空文字列からなる言語を{ε},空言語からなる 言語をφ
  51. 51. DFA,NFA • 決定性とは遷移先が必ず1つに決まっているこ とを意味する • (決定的,非決定的という表記もする) • つまりDFAでは各状態において遷移先は1つに 決まっているが,NFAではそうではない • またNFAで実現可能なものはDFAで実現可能 (受理能力に差はない)
  52. 52. DFA,NFA A A A DFA NFA A
  53. 53. DFA - 判定方法 • まずは判定方法を決める必要があるが,以下の 通りとする • 文字列の先頭から1文字ずつ調べ,その文字に よって状態を遷移させる • 文字列が終わったとき予め決めておいた状態な らばこの言語に所属していると判定する • もう少し詳細に次に記す
  54. 54. DFA - 判定方法 • 遷移の条件は文字である • 開始状態を1つ決める(ここから始める).最 初の矢印が記す • 終了状態を決める.複数でも良いし,開始状態 と重なっても良い.二重丸で表記 • また,それをオートマトンと呼ぶ • 以下に手順を記す
  55. 55. DFA - 手順 1. 文字列を取得する 2. オートマトンを開始状態から始める 3. 文字列の先頭から1文字ずつ取り出す 4. 取り出した文字によって遷移 5. 繰り返し 6. 文字列の末尾に到達したとき終了状態ならば言 語に所属している
  56. 56. DFA - 言語に所属しない条件 • 終了状態で終了しない(通りすぎても駄目) • 遷移先が示されない • ABCという文字列に対し受理する,しないもの の状態遷移図を次に描く
  57. 57. DFA - 判定 A B C A B C 受理する 受理しない A B C
  58. 58. NFA - 手順 • 基本はDFAに準拠する 1. 遷移先が複数ある際それぞれに複製したものを 送る 2. 同時にDFAと同様に手順 3. 1つでも終了状態になったものがあれば言語に 所属 • ABCという文字列に対し受理する,しないもの の状態遷移図を次に描く
  59. 59. NFA - 判定 A B A 受理する 受理しない B C A B A B C
  60. 60. NFAの意義 • 先に目的の言語を考えてからそれを受理する オートマトンを構成しようとした際,NFAがあ れば機械的に構成可能である. つまり正規表現からDFAを構成とか • DFAよりも状態数が少なくなるものがある
  61. 61. ε-NFA • 空文字列に対しての状態遷移が存在する可能性 がある(存在しなくても良い). • 言語の表現能力がNFAに等しい.つまりDFAに 等しい.
  62. 62. ε-NFA - 手順 1. 1文字取り出す 2. 取り出した文字によって遷移する前に次の状態 に移る 3. 文字によって遷移 • 2の動作をε遷移という.これも非決定性 • ACという文字列に対し受理する,しないものの 状態遷移図を次に描く
  63. 63. ε-NFA - 判定 A B A 受理する 受理しない B C A ε A B C
  64. 64. ε-NFAの意義 • 正規表現から直接DFAに変換するのは難しい • 正規表現→ε-NFA→NFA→DFAと変換する
  65. 65. 4. 正規表現の動作原理 • 2で記したものを踏まえて正規表現の動作を簡 潔に記す • あくまで根幹の大まかな動作であり,動作全て を表したわけではないことに注意
  66. 66. 正規表現エンジン • 3(2)種類ある • NFA(従来型NFA)(正規表現主導) • POSIX NFA • DFA(テキスト主導) • NFA:.NET言語,PHP,Ruby,Perl, Python,GNU Emacs,sed,vi,ほとんどの grep • DFA:awk,lex,flex,ほとんどのegrep • NFAの方が多い
  67. 67. POSIX NFA • DFAとNFAの開発が進みやたらとでかくなって しまったところに現れたのがPOSIX標準 • メタ文字や機能,結果の明確化 • POSIX準拠:POSIX標準準拠の正規表現エンジ ンに期待して良い動作 • POSIX準拠にした結果少々ややこしくなったも のも.遅くもなった
  68. 68. NFA or others • 'nfa|nfa not' • nfa notに適用する • nfaにしかマッチしないならNFA(従来型NFA)
  69. 69. POSIX NFA or DFA • 'X(.+)+X' • '=XX====================='に適用 • 時間がかかればNFA(POSIX NFA) • すぐに終わればDFA • オーバーフローなどの警告がでたらNFA
  70. 70. 原則 1. 最初にマッチしたものが優先される 2. 標準の量指定子は欲張りである • 欲張りとは最大のテキストでマッチしようとす る,という意味である • a bad dabに'a.*b'を適用すると全体にマッチ (最初にマッチしたものであり欲張りである)
  71. 71. 最適化について • ここでは最適化については考慮しない • まず文字列の先頭でマッチしない場合次の位地, 次の位地と進めて試行するが'^.*'などの正規 表現では無意味である • 最適化によりエンジンで判断できるがここでは 無視する
  72. 72. NFA(正規表現主導) • tonightという文字列 • 'to(nite|knight|night)'という正規表現 • 評価の順はt,o,(nite),(knight),(night)で ある • 1つずつ順に正規表現を試していく
  73. 73. バックトラック • NFAの根幹はバックトラックである • 少なくともマッチが見つかるまで必要な限り全 ての順列を試す • 'to(nite|knight|night)'に対しtoniまでいっ て次が不一致であればtoまで戻りtokn……と試 していく
  74. 74. DFA(テキスト主導) • tonightという文字列 • 'to(nite|knight|night)'という正規表現 • t,oと評価したあとnを評価する.この時点で 一致するのは(nite)か(night)である. • (knight)はnを評価した時点でマッチしないこと がわかるので除外される • 並列に処理していく感じ • 決定的である.高々一回しか評価されない
  75. 75. DFAとNFAの比較 • DFAは並列に処理するので高速であり安定して いる.但し表現の幅は狭い • NFAは順に正規表現を評価するため正規表現の 書き方によって仕事量が増大する • バックトラックを根幹としている.最小量指定 子など様々な表現ができる • 「NFAは複製するんだしNFAが並列に処理する んじゃないの?」←正規表現の動作を追うとわ かる
  76. 76. POSIX NFAと従来型NFA • POSIX NFAは最長のマッチを返す • 最左最長原則:同じ位置から複数マッチが始ま れば最も長いテキストにマッチするものを返す • 効率が問題になってくる • 従来型NFAはかなり幅広い表現が可能である. 正規表現エンジンの中で最も表現力が高い
  77. 77. Tcl • NFAエンジンのような表現をもちPOSIX NFA の最左最長原則をサポートする.且つNFAエン ジンの問題を受けない • Henry Spencer(初期の正規表現の開発と普及 に関する偉大な人物)によるもの
  78. 78. 5. まとめ • 正規表現つおい • 少し覚えればかなり使える • Perlのワンライナーで一括置換とかやって楽に • 正規表現の話が半分ぐらいしかない気がするの で土下座 • というか入門じゃないので土下座 • 結局対象者が不透明なので土下座
  79. 79. 御清聴ありがとうございました

×