본문 바로가기

프로그래머/Python

[파이썬] 파이썬 정리 for me (feat. FastCampus)

###파이썬 간단 정리

본 내용은 패스트캠퍼스 파이썬 기초 내용을 요약정리한 것입니다.


텍스트 입력에서...

**python** is really *cool*

- python 
    - pandas
        - depth1
        - depth2
    - numpy
- java
- c++
- golang

1. python
2. java
3. c++

> 파이썬은 재밌다고 하더라...

$y = 3x$

위아래 ```을 붙이면 코드 형태로 출력

a = 10
print(a)

링크 만들기

[파이썬 공식 페이지] https://www.python.org

[파이썬 공식 페이지] https://www.python.org


함수의 이해 및 활용, 기본 파라미터, 키워드

def add(x,y):
    n = x+y
    return n

파라미터가 필요 없는 경우

def test():
    print('haha')
    print('good')
    return 100

a = test()
print(a)

haha
good
100


  • 함수의 파라미터에 기본 값 지정 가능
  • 파라미터를 명시하지 않을 경우, 지정된 기본 값으로 대체
def add(x,y, z=5):
    n = x+y+z
    return n

add(10, 20)

35


내장 함수인 print 같은 경우도 default 값이 정해져 있고, 바꿀 수 있다.

print(1,2,3, sep='!', end='%%%')
print(2,3,4)

1!2!3%%%2 3 4


  • 디폴트 파라미터 뒤에 일반 파라미터가 위치할 수 없음

  • e.g) 올바른 예

    def test(a, b, c = 1)
    def test(a, b = 1, c = 2)
    def test(a = 1, b = 1, c = 3)

  • e.g) 올바르지 않은 예

    def test(a, b = 1, c)
    def test(a = 1, b, c)


keyword parameter(키워드 파라미터)

  • 파이썬의 경우, 파라미터에 값을 전달 할 때, 파라미터 이름을 명시하여 전달 가능
  • 파라미터 이름을 사용하지 않을 경우, 기본적으로 순서에 맞게 전달
    def test(x,y,z):
      a = x + y + z
      return a
    

test(x=10, z=3, y=50)

> 63

---
키워드 파라미터의 경우 조금 더 명시적으로 함수를 이해할 수 있음
```python
def weird_multiply(x,y):
    if x > 10:
        return
    print(x + y)
    return (x+2)*y

c = weird_multiply(12, 5)
print(c)

return 만 존재하면 None을 반환

def weird_multiply(x,y):
    if x > 10:
        return x + y

c = weird_multiply(2, 5)
print(c)

None


return 없이 함수가 종료된 경우에도 None을 반환

def add_mul(x,y):
    s = x + y
    m = x * y

    return s, m

c = add_mul(20, 3)
print(type(c))
print(c)
 <class 'tuple'     >

(23, 60)


복수값 반환의 경우 튜플을 사용해 반환됨
multiple return (복수값 반환)

  • tuple 반환을 하여 복수 개의 값 리턴 가능
def add_mul(x,y):
    s = x + y
    m = x * y

    return s, m

a, b = add_mul(20, 3)
print(a, b)

21

num1 = 10
num2 = 30

def test(num1, num2):
    print(num1, num2)
    return num1 + num2

test(30, 40)

print(num1, num2)

30 40
10 30


variable length argument(가변길이 인자)

  • 전달되는 파라미터의 개수가 고정적이지 않은 경우 사용
  • e.g)
    • print 함수
    • format 함수

      args, *kwargs
      *args : 파라미터를 튜플의 형태로 전달
      *kwargs: 파라미터를 딕셔너리 형태로 전달(네임드 파라미터)

def test(*x):
    print(type(x))

test(10,20,30)
 <class 'tuple'     >

parameter 앞에 *를 붙이게 되면, 가변길이 함수가 되고, 함수 내부적으로는 parameter를 튜플로 인식함
관례적으로 args를 씀

def test(*args):
    for item in args:
        print(item)

test(10, 30, 50)

keywork parameter(키워드 파라미터)

  • **가 붙은 경우에는 키워드 파라미터로 인식
  • 즉 함수 호출 시, 파라미터의 이름과 값을 함께 전달 가능
  • 보통 kwargs로 씀
    def test2(**x):
      print(type(x))
    

test2()

```python
def test2(**kwargs):
    for key, value in kwargs.items():
        print("key: ", key, ", value: ", value)

test2(a=1, b=2, c=3, d=4, name='bob')

key: a , value: 1
key: b , value: 2
key: c , value: 3
key: d , value: 4
key: name , value: bob


.format()을 쓰게 되면, {}이 placeholder로 동작

a = '오늘 온도: {}도, 강수확률은: {}%'.format(20, 50)
print(a)

오늘 온도: 20도, 강수확률은: 50%

a = '오늘 온도: {today_temp}도, 강수확률은: {today_rain}%'.format(today_temp = 20, today_rain = 50)
print(a)

오늘 온도: 20도, 강수확률은: 50%

이런식으로, 가변 길이 keyword parameter로 무자열을 만들면 더 편함


함수의 이해 및 활용 - 람다 함수

람다 함수 이해 및 사용

  • 단일문으로 표현되는 익명함수
  • 익명함수란 이름이 없는 구현체만 존재하는 간단한 함수를 의미
  • 코드 상에서 한번만 사용되는 기능이 있을 때, 굳이 함수로 만들지 않고 1회성으로 만들어서 쓸 때 사용
    square = lambda x:x**2
    type(square)

    function

    25

  • square(5)

lambda 입력 : 출력

def add(x,y):
    return x+y

add2 = lambda x, y:x+y
add2(10, 20)

30


기존 sort 함수는 알파벳 대로 정렬
기존 함수 안의 key parameter 활용

def str_len(s):
    return len(s)

strings = ['bob', 'charles', 'alexander3', 'teddy']
strings.sort(key=str_len)

print(strings)

['bob', 'teddy', 'charles', 'alexander3']

strings = ['bob', 'charles', 'alexander3', 'teddy']
strings.sort(key=lambda s:len(s))

print(strings)

['bob', 'teddy', 'charles', 'alexander3']

filter, map, reduce

  • lambda가 유용하게 사용되는 3가지 대표적 함수
  • 함수형 프로그래밍의 기본 요소이기도 함
  • filter : 특정 조건을 만족하는 요소만 남기고 필터링
  • map : 각 원소를 주어진 수식에 따라 변형하여 새로운 리스트를 반환
  • reduce : 차례대로 앞 2개의 원소를 가지고 연산. 연산의 결과가 또 다음 연산의 입력으로 진행됨. 따라서 마지막까지 진행되면 최종 출력은 한 개의 값만 남게 됨

filter, map은 기본 내장 함수
filter(함수, 리스트). 함수가 리스트에 불려서 참이면 살아남고, 거짓이면 필터링

nums = [1,2,3,6,8,9,10,11,13,15]
list(filter(lambda n:n&2==0, nums))

[1, 8, 9, 13]

nums = [1,2,3,6,8,9,10,11,13,15]
list(map(lambda n:n**2, nums))

[1, 4, 9, 36, 64, 81, 100, 121, 169, 225]

list(map(lambda n:n%2==0, nums))

[False, True, False, True, True, False, True, False, False, False]


import functools

a = [1,3,5,8]

functools.reduce(lambda x,y:x+y, a)

17


####함수의 이해 및 활용 - 함수 연습 분제 풀이

  1. 주어진 숫자 리스트의 평균을 구하는 함수를 출력하시오

  2. 해당 숫자가 소수인지 아닌지 판별하시오

  3. 2부터 해당 숫자사이에 소수가 몇 개인지 출력하는 함수를 구하시오

    def mean(nums):
     # _sum = 0
     # for i in nums:
     #     _sum += i
    
     return sum(nums) / len(nums)
    
    

print(mean([1,2,3]))
print(mean([1,2,3,4,5]))
print(mean([1,2,3.0,3.9,8.7]))

> 2.0
3.0
3.72

#### 파이썬 모듈 - 모듈의 이해 및 사용과 import 방법
import : import를 사용하여 해당 모듈 전체를 import
from import : 해당 모듈에서 특정한 타입만 import
*import : 해당 모듈 내에 정의된 모든 것을 import. 일반적으로 사용이 권장되지 않음
as : 모듈 import시 alias(별명) 지정 가능

#### 클래스 & 오브젝트 이해하기
'인간'이라는 타입(class)
실제로 존재하는 객체(object)

__init__(self)
- 생성자, 클래스 인스턴스가 생성될 때 호출됨
- self 인자는 항상 첫번째에 오며 자기 자신을 가리킴
- 이름이 꼭 self일 필요는 없지만, 관례적으로 self 사용
- 생성자에서는 해당 클래스가 다루는 데이터를 정의
    - 이 데이터를 멤버 변수 또는 속성이라고 함
```python
class Person:
    def __init__(self):
        print(self, 'is generated')

p1 = Person()

<main.Person object at 0x7fe9068fc9b0> is generated

class Person:
    def __init__(self):
        print(self, 'is generated')
        self.name = 'Kate'
        self.age = 10

p1 = Person()

# p1.name = 'aaron'
# p1.age = 20

print(p1.name, p1.age)

<main.Person object at 0x7fe9067bd438> is generated
Kate 10

class Person:
    def __init__(self, name, age):
        print(self, 'is generated')
        self.name = name
        self.age = age

p1 = Person('Bob', 30)

# p1.name = 'aaron'
# p1.age = 20

print(p1.name, p1.age)

<main.Person object at 0x7fe9067a82e8> is generated
Bob 30

self

  • 파이썬의 method는 항상 첫번째 인자로 self 전달

  • self는 현재 해당 메소드가 호출되는 객체 자신을 가리킴

  • C++ / C#, Java의 this에 해당

  • 역시, 이름이 self일 필요는 없으나, 위치는 항상 맨 처음의 parameter이며 관례적으로 self 사용

    class Person:
      def __init__(self, name, age):
          print(self, 'is generated')
          self.name = name
          self.age = age
    
      def sleep(self):
          print(self.name, '은 잠을 잡니다.')
    

p1 = Person('Bob', 30)

p1.name = 'aaron'

p1.age = 20

print(p1)

p1.sleep()

> <__main__.Person object at 0x7fe9067a8ac8> is generated
<__main__.Person object at 0x7fe9067a8ac8>
Bob 은 잠을 잡니다.

#### 클래스와 인스턴스 - method, static method 정의 및 사용하기
method 정의
- 멤버함수라고도 하며, 해당 클래스의 object에서만 호출 가능
- method는 객체 레벨에서 호출되며, 해당 객체의 속성에 대한 연산을 행함
- {obj}.{method}() 형태로 호출됨
```python
class Counter:
    def __init__(self):
        self.num = 0
    def print_current_value(self):
        print('현재값은: ', self.num)

c1 = Counter()
c1.print_current_value()

c2 = Counter()
c2.print_current_value()

현재값은: 0
현재값은: 0

method type

  • instance method - 객체로 호출

    • method는 객체 레벨로 호출되기 때문에, 해당 method를 호출한 객체에만 영향을 미침
  • class method(static method) - class로 호출

    • 클래스 method의 경우, 클래스 레벨로 호출되기 때문에, 클래스 멤버 변수만 변경 가능

      class Math:
      def add(self, a, b):
        return a + b
      
      def multiply(self, a, b):
        return  a * b
      

m = Math()
m.add(10, 20)
m.multiply(10, 20)

>200

이 클래스는 속성이 없음(self)가 할일이 없음
- instance level의 method를 생성할 필요가 없음
- 내부적으로 유지할 데이터가 없음. 전달된 데이터에 대해 처리해서 반환만 해주면 됨

@static method를 붙여주게 되면, class method 혹은 static method라고 불리우며, class 이름으로 바로 함수를 호출할 수 있음
대부분 utility성 기능을 가진 함수들에서 많이 사용됨. 어떠한 기능을 하나의 단위로 묶고 싶은데, 그 기능들이 내부적인 속성을 유지할 필요가 없는 경우

#### 클래스 상속의 이해(코드를 재사용하기 2)
class inheritance(상속)
- 기존에 정의해둔 클래스의 기능을 그대로 물려받을 수 있다
- 기존 클래스에 기능 일부를 추가하거나, 변경하여 새로운 클래스를 정의한다
- 코드를 재사용할 수 있게 된다
- 상속 받고자 하는 대상인 기존 클래스는 parent, super base class라고 부른다
- 상속 받는 새로운 클래스는 child, sub, derived class라고 부른다
- 의미적으로 is-a 관계를 갖는다
```python
class Math:
    @staticmethod
    def add(self, a, b):
        return a + b

    @staticmethod
    def multiply(self, a, b):
        return  a * b

# m = Math()
m.add(10, 20)
m.multiply(10, 20)

200

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def eat(self, food):
        print('{}은 {}를 먹습니다.'.format(self.name, food))

    def sleep(self, minute):
        print('{}은 {}분동안 잡니다.'.format(self.name, minute))

    def work(self, minute):
        pass

class Student(Person):
    def __init__(self, name, age):
        self.name = name
        self.age = age

class Employee(Person):
    def __init__(self, name, age):
        self.name = name
        self.age = age

bob = Student('Bob', 25)
bob.eat('BBQ')
bob.sleep(30)
bob.work(60)

Bob은 BBQ를 먹습니다.
Bob은 30분동안 잡니다.

method override

  • 부모 클래스의 method를 재정의

  • 하위 클래스(자식 클래스)의 인스턴스로 호출 시, 재정의된 메소드가 호출됨

    class Person:
      def __init__(self, name, age):
          self.name = name
          self.age = age
    
      def eat(self, food):
          print('{}은 {}를 먹습니다.'.format(self.name, food))
    
      def sleep(self, minute):
          print('{}은 {}분동안 잡니다.'.format(self.name, minute))
    
      def work(self, minute):
          pass
    

class Student(Person):
def init(self, name, age):
self.name = name
self.age = age

def work(self, minute):
    print('{}은 {}분동안 공부합니다.'.format(self.name, minute))

bob = Student('Bob', 25)
bob.eat('BBQ')
bob.sleep(30)
bob.work(60)

> Bob은 BBQ를 먹습니다.
Bob은 30분동안 잡니다.
Bob은 60분동안 공부합니다.
```python
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def eat(self, food):
        print('{}은 {}를 먹습니다.'.format(self.name, food))

    def sleep(self, minute):
        print('{}은 {}분동안 잡니다.'.format(self.name, minute))

    def work(self, minute):
        pass

class Student(Person):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def work(self, minute):
        super().work(minute)
        print('{}은 {}분동안 공부합니다.'.format(self.name, minute))

class Employee(Person):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def work(self, minute):
        super().work(minute)
        print('{}은 {}분동안 업무를 합니다.'.format(self.name, minute))

bob = Student('Bob', 25)
bob.eat('BBQ')
bob.sleep(30)
bob.work(60)
print('\n')
mary = Employee('Mary', 25)
mary.eat('Salad')
mary.sleep(30)
mary.work(60)

Bob은 BBQ를 먹습니다.
Bob은 30분동안 잡니다.
Bob은 60분동안 공부합니다.

Mary은 Salad를 먹습니다.
Mary은 30분동안 잡니다.
Mary은 60분동안 업무를 합니다.

super

  • 하위 클래스(자식 클래스)에서 부모 클래스의 method를 호출할 때 사용

  • super().{상속 받을 method}({상속 받을 파라미터})

    class father():
      def __init__(self, who):
          self.who = who
    
      def handsome(self):
          print("{}를 닮아 잘생겼다".format(self.who))
    

class sister(father):
def init(self, who, where):
super().init(who)
self.where = where

def choice(self):
    print("{} 말이야.".format(self.where))

def handsome(self):
    super().handsome()
    self.choice()

girl = sister("아빠", "얼굴")
girl.handsome()

> 아빠를 닮아 잘생겼다
얼굴 말이야.

#### 클래스 연산자 재정의 이해 및 사용
special method
- __ 로 시작 __로 끝나는 특수함수
- 해당 method들을 구현하면, custom 객체에 여러가지 파이썬 내장 함수나 연산자를 적용 가능
```python
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def print_pt(self):
        print('({}, {})'.format(self.x, self.y))

p1 = Point(3,4)
p2 = Point(2,7)

p1.print_pt()
p2.print_pt()

(3, 4)
(2, 7)

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self):
        return '({}, {})'.format(self.x, self.y)

p1 = Point(3,4)
p2 = Point(2,7)

print(p1)
print(p2)

(3, 4)
(2, 7)

custom class도 파이썬의 기본 타입처럼 자유롭게 쓸 수 있음

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self):
        return '({}, {})'.format(self.x, self.y)

    def __add__(self, pt):
        new_x = self.x + pt.x
        new_y = self.y + pt.y
        return Point(new_x, new_y)

    def __sub__(self, pt):
        new_x = self.x - pt.x
        new_y = self.y - pt.y
        return Point(new_x, new_y)

p1 = Point(3,4)
p2 = Point(2,7)

p3 = p1 + p2
p4 = p1 - p2

print(p1)
print(p2)
print(p3)
print(p4)

(3, 4)
(2, 7)
(5, 11)
(1, -3)

클래스 연습문제 풀이

  • 복소수 클래스 정의
  • 덧셈, 뺄셈, 곱셈 연산자 지원
  • 길이 (복소수의 크기) 지원
  • 복소수 출력 '1+4j'와 같이 표현
  • 비교 연산 ==, != 지원
  • ==, <=, <, > 지원
  • 절대값 지원
    import math
    

class ComplexNumber:
def init(self, real, img):
self.real = real
self.img = img
def add(self, cn):
return ComplexNumber(self.real + cn.real, self.img + cn.img)
def sub(self, cn):
return ComplexNumber(self.real - cn.real, self.img - cn.img)
def str(self):
if self.img >= 0:
return '{} + {}j'.format(self.real, self.img)
else:
return '{} - {}j'.format(self.real, abs(self.img))
def mul(self, x):
if type(x) == int:
return ComplexNumber(self.real * x, self.img * x)
elif type(x) == ComplexNumber:
return ComplexNumber(self.real * x.real - self.img * x.img,
self.real * x.img + self.img * x.real)
def eq(self, cn):
return self.real == cn.real and self.img == cn.img
def ne(self, cn):
return not (self.real == cn.real and self.img == cn.img)
def len(self):
return self.real ** 2 + self.img ** 2
def abs(self):
return math.sqrt(self.real ** 2 + self.img ** 2)

a = ComplexNumber(1,2)
b = ComplexNumber(3,4)

print(a+b)
print(a * ComplexNumber(1,2))
print(a != b)
print(abs(-4))
print(abs(a))
print(len(a))

> 4 + 6j
-3 + 4j
True
4
2.23606797749979
5
```python
a = 'abcdef\n'
print(a)

b = r'abcdef\n'
print(b)

abcdef
abcdef\n


정규표현식 – 01. 정규포현식과 re 모듈의 사용

정규표현식(re)에 대한 이해 및 숙지

  • 정규 표현식
    • regular expression
    • 특정한 패턴과 일치하는 문자열을 ‘검색’, ‘치환’, ‘제거’하는 기능을 지원
    • 정규표헌식의 도움 없이 패턴을 찾는 작업(rule 기반)은 불완전하거나, 작업의 cost가 높음
    • e.g) 이메일 형식 판별, 전화번호 형식 판별, 숫자로만 이루어진 문자열 등
  • raw string
    • 문자열 앞에 r이 붙으면 해당 문자열이 구성된 그대로 문자열로 변환

raw stream
기본 패턴

  • a, X, 9 등등 문자 하나하나의 character 들은 정확히 해당 문자와 일치
    • e.g) 패턴 test는 test문자열과 일치
    • 대소문자의 경우 기본적으로 구별하나, 구별하지 않도록 설정 가능
  • 몇몇 문자들에 대해서는 예외가 존재하는데, 이들은 특별한 의미로 사용됨
    • . ^ $ * + ? { } [ ] \ | ( )
  • . - 어떤 한개의 character와 일치(newline 제외)
  • \w - 문자 character와 일치
  • \s - 공백 문자와 일치
  • \t, \n, \r - tab, newline, return
  • \d - 숫자 character와 일치
  • ^ = 시작, $ = 끝 각각 문자열의 시작과 끝을 의미
  • \가 붙으면 스페셜한 의미가 없어짐.

search method

  • 첫번째로 패턴을 찾으면 match 객체를 반환
  • 패턴을 찾지 못하면 None 반환
    import re
    

re.search({찾을 문자열}, {찾을 대상})

m = re.search(r'abc', 'abcdef')
print(m)
print(m.start())
print(m.end())
print(m.group())

> <_sre.SRE_Match object; span=(0, 3), match='abc'>
0
3
abc

앞에는 찾을 문자열, 뒤에는 찾을 대상
start, end는 해당하는 index 반환, group는 검색된 패턴을 가져옴
```python
m = re.search(r'abc', '123abdef')
print(m)

None

m = re.search(r'\d\d', '112abcdef119')
print(m)

<_sre.SRE_Match object; span=(0, 2), match='11'>

search 함수는 가장 먼저 나오는 패턴을 찾는다. 숫자 2개가 연달아 오는 패턴

m = re.search(r'\d\d\d\w', '112abcdef119')
m

<_sre.SRE_Match object; span=(0, 4), match='112a'>

m = re.search(r'..\w\w', '@#$%ABCDabcd')
m

<_sre.SRE_Match object; span=(2, 6), match='$%AB'>


####[ ] 문자들의 범위를 나타내기 위해 사용

  • 내부의 메타 캐릭터는 캐릭터 자체를 나타냄
  • [abck] : a or b or c or k
  • [abc.^] : a or b or c or . or ^
  • [a-d] : -와 함께 사용되면 해당 문자 사이의 범위에 속하는 문자 중 하나
  • [0-9] : 모든 숫자
  • [a-z] : 모든 소문자
  • [A-Z] : 모든 대문자
  • [a-zA-Z0-9] : 모든 알파벳 문자 및 숫자
  • [^0-9] : ^가 맨 앞에 사용되는 경우 해당 문자 패턴이 아닌 것과 매칭
    re.search(r'[cbm]at', 'cat')

    <_sre.SRE_Match object; span=(0, 3), match='cat'>

    <_sre.SRE_Match object; span=(0, 5), match='1haha'>

    <_sre.SRE_Match object; span=(0, 5), match='^aron'>

    <_sre.SRE_Match object; span=(0, 5), match='0aron'>

  • # abc가 아닌 것과 매칭 re.search(r'[^abc]aron', '0aron')
  • re.search(r'[abc^]aron', '^aron')
  • re.search(r'[0-9]haha', '1hahah')
  1. 다른 문자와 함께 사용되어 특수한 의미를 지님
  • \d : [0-9]와 동일
  • \D : [^0-9]와 동일
  • \s : 공백 문자
  • \S : 공백이 아닌 문자
  • \w : 알파벳 대소문자, 숫자와 동일 [a-zA-Z0-9]
  • \W : [^a-zA-Z0-9] 와 동일
  1. 메타 캐릭터가 캐릭터 자체를 표현하도록 할 경우 사용
  • \ . , \ \
    re.search(r'\sand', 'apple and banana')
    <_sre.SRE_Match object; span=(5, 9), match=' and'>
    re.search(r'\Sand', 'apple and banana')
    re.search(r'.and', 'pand')

    <_sre.SRE_Match object; span=(0, 4), match='pand'>

  • re.search(r'\.and', 'pand')

반복 패턴

  • 패턴 뒤에 위치하는 *, +, ?는 해당 패턴이 반복적으로 존재하는지 검사
    • '+' -> 1번 이상의 패턴이 발생
    • '*' -> 0번 이상의 패턴이 발생
    • '?' -> - 혹은 1번의 패턴이 발생
  • 반복 패턴의 경우 greedy하게 검색 함, 즉 가능한 많은 부분이 매칭되도록 함
    • e.g) a[bcd]*b 패턴을 abcbdccb에서 검색하는 경우
      • ab, abcb, abcbdccb 전부 가능. 하지만 최대한 많은 부분이 매칭된 abcbdccb가 검색된 패턴
        re.search(r'a[bcd]*b', 'abcbdccb')

        <_sre.SRE_Match object; span=(0, 8), match='abcbdccb'>

A로 시작하고 bcd 중에 하나가 0번 이상 반복되고, b로 끝난 패턴

re.search(r'b\w+a', 'banana')

<_sre.SRE_Match object; span=(0, 6), match='banana'>

re.search(r'i+', 'piigiii')

<_sre.SRE_Match object; span=(1, 3), match='ii'>

가장 빨리 match되는 것을 찾고 끝냄

re.search(r'pi+g', 'pig')

<_sre.SRE_Match object; span=(0, 3), match='pig'>

re.search(r'pi*g', 'pig')

<_sre.SRE_Match object; span=(0, 3), match='pig'>

re.search(r'pi+g', 'pg')
re.search(r'pi*g', 'pg')

<_sre.SRE_Match object; span=(0, 2), match='pg'>

re.search(r'https?', 'httpk://www.naver.com')

<_sre.SRE_Match object; span=(0, 4), match='http'>

S는 없어도 관계 없음

re.search(r'b\w+a', 'cabana')

<_sre.SRE_Match object; span=(2, 6), match='bana'>

re.search(r'^b\w+a', 'cabana')

문자열의 끝이 a로 끝나야 함
grouping

  • ()를 사용하여 그루핑
  • 매칭 결과를 각 그룹별로 분리 가능
  • 패턴 명시할 때, 각 그룹을 괄호 안에 넣어 분리하여 사용
    m = re.search(r'\w+@.+', 'test@gmail.com')
    m

    <_sre.SRE_Match object; span=(0, 14), match='test@gmail.com'>

문자열 한 번 이상, @, 어떤 문자든 한 번 이상

m = re.search(r'(\w+)@(.+)', 'test@gmail.com')
print(m.group(1))
print(m.group(2))
print(m.group(0))

test
gmail.com
test@gmail.com

{}

  • *, +, ? 을 사용하여 반복적인 패턴을 찾는 것이 가능하나, 반복의 횟수 제한은 불가
  • 패턴 뒤에 위치하는 중괄호 {}에 숫자를 명시하면 해당 숫자 만큼의 반복인 경우에만 매칭
  • {4} - 4번 반복
  • {3, 4} - 3~4번 반복
    re.search('pi{3}g', 'piiig')

    <_sre.SRE_Match object; span=(0, 5), match='piiig'>

미니멈 매칭(non-greedy way)

  • 기본적으로 *, +, ? 를 사용하면 greedy(맥시멈 매칭)하게 동작함
  • *?, +?을 이용하여 해당 기능을 구현
    re.search(r'<.+>', '<html>haha</html>')

    <_sre.SRE_Match object; span=(0, 17), match='haha'>

    <_sre.SRE_Match object; span=(0, 6), match=''>

  • # *?, +?을 쓰면 미니멈 매칭 re.search(r'<.+?>', '<html>haha</html>')

{}?

  • {m,n}의 경우 m번에서 n번 반복하나 greedy하게 동작
  • {m,n}?로 사용하면 non-greedy하게 동작. 즉, 최소 m번만 매칭하면 만족
    re.search(r'a{3,5}', 'aaaaa')

    <_sre.SRE_Match object; span=(0, 5), match='aaaaa'>

    <_sre.SRE_Match object; span=(0, 3), match='aaa'>

    match
  • re.match(r'\d\d\d', 'my number is 123')
  • re.search(r'a{3,5}?', 'aaaaa')
  • search와 유사하나, 주어진 문자열의 시작부터 비교하여 패턴이 있는지 확인
  • 시작부터 해당 패턴이 존재하지 않는다면 None 반환
    re.match(r'\d\d\d', '123 is my number')

    <_sre.SRE_Match object; span=(0, 3), match='123'>

    <_sre.SRE_Match object; span=(0, 3), match='123'>

  • # ^ = 시작, % = 끝 re.search(r'^\d\d\d', '123 is my number')

findall

  • search가 최초로 매칭되는 패턴만 반환한다면, findall은 매칭되는 전체의 패턴을 반환
  • 매칭되는 모든 결과를 리스트 형태로 반환
    re.findall(r'[\w-]+@[\w.]+', 'test@gmail.com haha test2@gmail.com nice test')

    ['test@gmail.com', 'test2@gmail.com']

sub

  • 주어진 문자열에서 일치하는 모든 패턴을 replace
  • 그 결과를 문자열로 다시 반환함
  • 두번째 인자는 특정 문자열이 될 수도 있고, 함수가 될 수도 있음
  • count가 0인 경우는 전체를, 1 이상이면 해당 숫자만큼 치환 됨
    re.sub(r'[\w-]+@[\w.]+', 'great', 'test@gmail.com haha test2@gmail.com nice test')

    'great haha great nice test'

    'great haha test2@gmail.com nice test'

  • re.sub(r'[\w-]+@[\w.]+', 'great', 'test@gmail.com haha test2@gmail.com nice test', count=1)

compile

  • 동일한 정규표현식을 매번 다시 쓰기 번거로움을 해결
  • compile로 해당 표현식을 re.RegexObject 객체로 저장하여 사용 가능
    email_reg = re.compile(r'[\w-]+@[\w.]+')
    

email_reg.search('test@gmail.com haha good')

> <_sre.SRE_Match object; span=(0, 14), match='test@gmail.com'>