🌟

正規表現について( 練習問題あり)

に公開

正規表現について

結構前に、個人的な勉強会で正規表現についての講義を行いました。
そこで留めておくのなんだかもったいない気がしたので、その時の資料をここに残そうと思います。

正規表現とは?

正規表現(Regular Expression)とは、文字列のパターンを表現するための「特別な記号を使った文字列」です。
テキストの検索、抽出、置換などに使われ、Linuxのgrepコマンドや、プログラミング(Perl、Python、sed、awkなど)でもよく使われます。

正規表現を扱うためのメタ文字の意味

正規表現において、メタ文字は、パターンマッチングを行うために使用される特別な文字です。

メタ文字 意味
. 任意の1文字にマッチ
* 直前の要素を0回以上繰り返す
+ 直前の要素を1回以上繰り返す
? 直前の要素を0回または1回出現
[] 角括弧内の任意の1文字にマッチ
^ 行の先頭にマッチ(文字クラス内では否定)
$ 行の末尾にマッチ
\ エスケープ(特殊文字を文字として扱う)
| 選択(OR条件)
() グループ化、キャプチャ

Pythonで正規表現を扱う例

import re
lines = [
    "a",
    "abc",
    "a2c",
    "abcdef",
    "123-4567",
    "dog",
    "dogcat",
    "dag",
    "apple",
    "appleeee",
    "banana",
    "orange",
    "testtest",
    "wowwow",
    "aabccc",
    "cccaaabccc"
    "aaabccc",
    "cdefg",
    "car",
    "a car is fast",
    "scar"
]

例1:行頭がaで始まる文字列にマッチ

# 対象パターン定義
pattern = r'^a.*' 

for line in lines:
    if re.search(pattern, line):
        print(line)

# メタ文字解説:
# ^ : 行の先頭にマッチ
# . : 任意の1文字にマッチ
# * : 直前の要素を0回以上繰り返す
# 対象パターン定義
pattern = r'^a*' 

for line in lines:
    if re.search(pattern, line):
        print(line)

# メタ文字解説:
# ^ : 行の先頭にマッチ
# . : 任意の1文字にマッチ
# * : 直前の要素を0回以上繰り返す

例2:「a」が1回以上の後に「b」がくる文字列

# 対象パターン定義
pattern = r'a+b'

# 文字列リストから、パターンと一致するものを出力
for line in lines:
    if re.search(pattern, line):
        print(line)

# メタ文字解説:
# + : 直前の要素を1回以上繰り返す

例3:「dag」または「dog」にマッチ

# 対象パターン定義
pattern = r'd[ao]g'

# 文字列リストから、パターンと一致するものを出力
for line in lines:
    if re.search(pattern, line):
        print(line)

# メタ文字解説:
# [] : 角括弧内の任意の1文字にマッチ

例4:appleだけに一致

# 対象パターン定義
pattern = r'^apple$'

# 文字列リストから、パターンと一致するものを出力
for line in lines:
    if re.search(pattern, line):
        print(line)

# メタ文字解説:
# ^ : 行の先頭にマッチ
# $ : 行の末尾にマッチ
# $があるので,appleeeeeなどは引っかからない

例5:「abc」か「cde」が単語として含まれる


# 対象パターン定義
pattern = r'(abc|cde)'

for line in lines:
    if re.search(pattern, line):
        print(line)

# メタ文字解説:
# () : グループ化

Pythonで正規表現を扱う問題

lines = [
    "cat",
    "caterpillar",
    "dog",
    "dogma",
    "catalog",
    "bird",
    "bat",
    "battle",
    "car",
    "cart",
    "carbon",
    "category",
    "dogged",
    "battalion",
    "cartoon",
    "carbonara",
    "cattle",
    "doghouse",
    "carpenter",
    "batman"
]

問題1: 「cat」という文字列を含むものを抽出してください。

pattern = r""
for line in lines:
    if re.search(pattern, line):
        print(line)

問題2: 「dog」で始まる文字列を抽出してください。

pattern = r""
for line in lines:
    if re.search(pattern, line):
        print(line)

問題3: 「bat」で始まり、後に何か文字が続く文字列を抽出してください。

pattern = r""
for line in lines:
    if re.search(pattern, line):
        print(line)

問題4: 文字列が「car」で始まり「n」で終わるものを抽出してください。

pattern = r""
for line in lines:
    if re.search(pattern, line):
        print(line)

問題5:「cat」または「dog」で始まり、その後に任意の英小文字が続く文字列を抽出してください。

pattern = r""
for line in lines:
    if re.search(pattern, line):
        print(line)

問題6: 「cat」だけ抽出してください

pattern = r""
for line in lines:
    if re.search(pattern, line):
        print(line)

答え

  • 問題1
    答え:cat
    メタ文字解説
    特になし

  • 問題2
    答え: ^dog
    メタ文字解説
    ^ : 行の先頭にマッチ

  • 問題3
    答え: ^bat.+
    メタ文字解説:
    ^ : 行の先頭にマッチ
    + : 直前の要素を1回以上繰り返す
    . : 任意の1文字にマッチ

  • 問題4
    答え:^car.*n$
    メタ文字解説:
    ^ : 行の先頭にマッチ
    $ : 行の末尾にマッチ
    . : 任意の1文字にマッチ
    * : 直前の要素を0回以上繰り返す

  • 問題5
    答え:^(cat|dog)[a-z]+
    メタ文字解説:
    ^ : 行の先頭にマッチ
    () : グループ化
    [] : 角括弧内の任意の1文字にマッチ
    * : 直前の要素を0回以上繰り返す

  • 問題6
    答え:^cat$
    メタ文字解説:
    ^ : 行の先頭にマッチ
    $ : 行の末尾にマッチ

Discussion