正規表現 reモジュール

re モジュール

正規表現に関する様々な関数が用意されている.
オブジェクトにしてコンパイルすることもできるので,もし何度も同じ表現の処理をするなら,オブジェクトを作ってしまった方が良い.

先頭から検索する

re.match('.....



文字列全体を検索する

re.search('exp')

match = re.search(r'\d+\.\d+\.\d+\.\d+', string)


pattern = re.compile(r'\d+\.\d+\.\d+\.\d+')
match = pattern.search(string)




Matchオブジェクト

上記の関数(メソッド)では,マッチした箇所がある場合はMatchオブジェクト,ない場合はNoneが返却される.
例えば,次のようにMatchオブジェクトがあるとする.

m = re.search('exp')


何とマッチしたのか

m.group()


何文字でマッチしたのか

m.start()


特定の文字列以外で始まらない

target_pattern = f'^(?!hoge$)'









・二つの方法がある.
  関数
  正規表現オブジェクトのメソッド

・コンパイルする(オブジェクト作る)
  prog = re.compail(正規表現)
  result = prog.method(str)
  の要領.何回もやるならこっち




・関数
 result = re.func(正規表現, s)
 func: 下記にあるいろんなやつ



・全てをリストで取得: findall()


.: 改行以外全て

^: 文字列の先頭

$: 文字列の末尾,末尾の改行の直前
  foo

*: 直前のやつを0つ以上

?: 直前のやつを 0か1

+: 直前のやつを1つ以上

*, +, ? は貪欲マッチ.
 例えば,"<.*>"は
 "hoge<a>>>h>o>ge"に対して,
 "<a>>>h>o>"がマッチする.
  なるべく多くの文字でマッチする
  <a>だけにする(非貪欲マッチ)には
 後ろに?をつけて
  *?, +?, ??にする

?!:含まない(否定的先読み.)

[]: 文字の集合を指定できる
  [amk]: 'a', 'm', 'k'
  [(+*)]: '(', '+', '*', ')'
  [a-f]: aからf
  [^5]: ’5’以外

\A: 文字列先頭

\Z: 文字列末尾

\b: 空文字列
 \bfoo\b
  o: 'foo', 'foo.',
    '(foo)', 'bar foo baz'
  x: 'foobar', 'foo3'

\s: [ \t\n\r\f\v]

\S: [^ \t\n\r\f\v] 

\w: [a-zA-Z0-9_]

\W: [^a-zA-Z0-9_]

\d: [0-9]

\D: [^0-9]

|: 左 or 右

(): 中身そのまま



(?hoge)
 は拡張記法
 文字列の後に指定文字列がこないやつ
 foo(?!hoge)  foohogeはマッチせず.
  fooがないとマッチせず
 ある文字列が入らない
  ^(?!.*hoge)



・初めに..
 m = re.match(r'...')
 r付けることでrow stringになる


・先頭から一致: match()
 ・matchなし: None
 ・'c','abc' -> matchなし
 ・return Match object
  span=(0, 5)
  match='string'
 ・Match.group()でstr見れる
 ・strの1部分を抜粋する
  (?P<namae>[\w]+)
  って入れておけば,
  m = re.match(r'', s)
  m.group('namae')
  で見れる


・複数文字列
 r'Sunday|Sun|sunday'
 r'\b(Red|red)\b



・文字列全体: search()
 ・matchなし: None
 ・^をつけると先頭のみになる
 ・MULTILINEの場合は
  各行の先頭マッチになる


・変数を用いて検索
 var = [1,2,3]
 re.search(rf'{var}', '245')
 -> 2が当たる
   これ12だと1, 2がマッチする
 普通にstr使えばいいらしい



・正規表現が長すぎ!!
 re.VERBOSE で複数行にできる.
 re.hoge(r"""
  ABCDE:
  (?P<name1>[\w]+)#name
  (?P<name2>[\w]+) #name
  :stack/
  (?P<hg_id>[\d]+) #id
  [\w]""", re.VERBOSE)
 ってやるとOK
   


・split
  [str]
  s = 'My .. name is Mike'
  s.split()
  -> ['My', '..', 'name', ..]

  [re]
  p = re.compile(r'\W+')
  p.split(s)
  ・柔軟にできるように



・置換
  p = re.compile('(b|w|r)')
  p.sub('color', 'b c socks')
  -> 'color color socks'
  ・置換の数を指定
    count=1
  ・いくつ置換したのか
    p.subn(~~)
    -> ('string', cnt: int)


・置換してなんかしたい
  ・数字を見つけて16進数にしたい
  def hexrepl(match):
    v = int(mathc.goup())
    return hex(value)
  p = re.compile(r'\d')
  p.sub(hexrepl, '2 34 test')
   
・<>を探すと, <><><>全体がマッチ
  ・re.match('<.*>', s))
    なるべく大きくマッチ
  ・re.match('<.*?>', s))
    ヒットした時点でマッチ



・例
ABCDEus-east-2:1234567:stack/
ABCDE[\w-]+ :[\d]+ :stack/