みなさんにお知らせがあります!
このブログの元になっている資料が公開されました!
私はこれを元に勉強してきたので、皆さんも参考にしてみてください。
さて今回はもっともperlらしいといわれる「正規表現」には入ります!
エンジニア基礎① 1. Perl環境基礎 2. Hello,world! 3. Perl基礎 4. 配列・for文 5. ハッシュ 6. リファレンス 7. サブルーチン 8. ⭐️ 正規表現 ⭐️ 9. Amon2 入門 第一部 10. Amon2 入門 第二部
ゴール🏁(めやす:30分)
- 正規表現がわかる
おさえておきたいこと
正規表現
正規表現とは、幾つかの文字列を一つの形式で表すための表現方法です。正規表現によって、必要としているものを、膨大な文字列の中から自由自在に検出したり、置き換えたりすることができます。例えば、「検索機能」を実装する!ってなったときは、この正規表現を用いれば、「○○を含む検索」などのキーワードの設定ができるわけです!
でも、この正規表現はとても複雑なので、よく使うもの、基本的なものだけを紹介します!
メタ文字
正規表現で、幾つかの文字に対して特別な意味を与えています。これらを「メタ文字」といいます。
. ^ $ [ ] * + ? | ( )
これらのメタ文字を使って、条件にあったものがあるかどうか判定します!
いざスタート!
1. パターンマッチ
◼︎完全一致 eq
my $str = "pattern match!"; if ( $str eq 'match') { print "'$str'できました!\n"; }else{ print "完全一致しませんでした。\n"; }
↓
完全一致しませんでした。
eq
は完全一致か否かをみます。
この場合$str
にmatch
が完全一致しているのかをみているので、表示結果は「完全一致しませんでした。」になります。
◼︎含む =~ /文字/
/含まない !~ /文字/
my $str = "pattern match!"; if ( $str =~ /match/) { print "'$str'は'match'を含みます!\n"; } if ( $str !~ /match/) { print "'$str'は'perl'を含みません。\n"; }
↓
'pattern match!'は'match'を含みます!
=~ /match/
=/ここに入った文字/が含まれると一致
!~ /match/
=/ここに入った文字/が含まれないと一致
含む、含まないは以上のように表記することでパターンマッチすることができます。
2.文字列のマッチ
メタ文字を駆使して文字列を呼び出すことができます。
◼︎文字列の呼び出し
my $word = "五反田にはガイアックスがあるらしい"; if ( $word =~ /五反田(.+)ある/) { print "渋谷$1ない\n"; }
↓
渋谷にはガイアックスがない
(.+)
は任意の文字に一回以上マッチしたものを取得するので、(.+)
には「五反田」と「ある」の間の「にはガイアックスが」が入ります。それを$1
の変数として取得しています。これは複数個連ねることもできます。
◼︎複数個の文字列の呼び出し
my $word = "五反田にはガイアックスというIT系企業が多い"; if ( $word =~ /五反田には(.+)という(.+)/) { print "渋谷には$1はないが、$2\n"; }
↓
渋谷にはガイアックスがないが、IT系企業が多い
前者の(.+)は$1、後者の(.+)は$2と、(.+)が複数ある場合は先頭から順に取得しています。
3.メタ文字
先ほど紹介した以外のよく使うメタ文字一覧
メタ文字 | 役割 |
---|---|
. | ピリオド。ワイルドカード:任意の一文字にマッチ! |
* | 直前におかれているものに0回以上マッチ! |
.* | 任意の文字に任意の回数マッチ! |
+ | 直前に置かれているものに1回以上マッチ! |
.+ | 任意の文字に一回以上マッチ! |
? | 直前のものが、1回現れるか、現れない、の2択! |
( ) | パターンをグループ化にしてマッチ!($1などで後方参照できます) |
(?:) | 後方参照しないグループ化! |
\w | アルファベット, 数字, アンダーバーの1文字 |
\W | アルファベット, 数字, アンダーバー以外の1文字 |
\d | 数字の1文字 |
\D | 数字以外の1文字 |
\s | 空白文字にマッチ |
\S | 空白文字以外にマッチ |
\b | 単語の境界(置いた前後)とマッチ |
\B | 単語の境界以外とマッチ |
^ | 行頭の文字列とマッチ |
$ | 行末の文字列とマッチ |
これらの知識を使って、文字列のパターンマッチをしましょう!
【例1】
複数あるものの中から、必要な情報があるか確認できます。
「y」を含む言葉があるかどうか判定したい時、以下のようにします。
my $color = "red blue orange green yellow black white"; if ( $color =~ /y(.+)/) { print "あてはまるものはあったよ!\n"; }else{ print "あてはまるものはなかったよ!\n"; }
↓
あてはまるものはあったよ!
y(.+)
は「y」と「なんらかの文字を含む」のを条件にしています。
今回は「yellow」があるので、「あてはまるものがあったよ!」に判定されました。
もし「skyblue」があった場合もマッチします!
「y」からはじまる言葉があるかどうかを判定したい時、以下のようにします。
my $color = "red blue orange green yellow black white"; if ( $color =~ /\b(y\S+)/) { print "y からはじまる単語 $1 がありました。\n"; }else{ print "yからはじまる単語は見つかりませんでした。\n"; }
↓
y からはじまる単語 yellow がありました。
これは2行目の(y\S+)
で「yに続く文字が空白文字以外である」ことを判定し、\b(y\S+)
と\b
を付け加えることで、「yの直前になにもなく(=yではじまる)、直後に空白文字以外が続く」ことを判定します。
よって、「yellow」がマッチするのです!
【例2】
もしなにかのサービスで新規ユーザの登録をするとき、よくみかける「アルファベット、数字、アンダーバーのみ使用可」というのもこの正規表現で判定することができます。
my $username = "marimo"; if ( $username =~ /\W/ ){ print "アルファベット、数字、アンダーバーを使用してください。"; }else{ print "登録可能です。"; }
↓
登録可能です。
もし「marimo」ではなく「marimo*」をusernameで使用すると、「アルファベット、数字、アンダーバーを使用してください。」と表示されます!
1行目のmarimo
をmy $input = <STDIN>;
にして試してみてください!
【例3】変数として扱うこともできます。
もしなにかのサービスで子供が安全に使えるように検索機能で「凶暴」という言葉を制限するとします。
my $input = <STDIN>; if ( $input =~ /凶暴/) { print "この言葉は検索できません。\n"; }else{ print "検索結果を表示します。\n"; }
↓凶暴と打った場合
この言葉は検索できません。
↓安全と打った場合
検索結果を表示します。
以上、正規表現を用いた例でした!
4.置換
s/置換したい文字/置換した後の文字/
というふうにおくと置換できます。
my $word = "red blue yellow"; print "$word\n"; $word =~ s/red/orange/; print "$word\n";
↓
red blue yellow orange blue yellow
1行目が置換前、2行目が置換後の文字列が表示されました!
例えば、今日の会議だけ、開始時間が一時的に変更になったとき、2行目を足せば大丈夫!
my $action = "今日の会議は10:00開始です。"; $action =~ s/10:00/12:00/; print "$action\n";
↓
今日の会議は12:00開始です。
--
以上が正規表現になります。
perlでの正規表現は分厚い本が一冊あるほど、奥が深いと言われています。。。
簡単な例を出して考えてみましたが、どんな風に使うか実感わいたでしょうか!?
メタ文字はこのほかにもいっぱいありますので、場合にあったメタ文字を探してくださいね!