{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# **정규표현식 연습하기**\n", "## **1 잡아라 텍스트 마이닝 with 파이썬**\n", "Regex Tutorials" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'그러면서 \"문재인 대통령은 조국 장관 임명으로 민심을 분열시킨 책임을 엄중히 느끼고 \\n제대로 된 개혁 작업을 추진하기를 바란다\"며 \"특히 검찰개혁이 사법개혁의 전체인양 호도하지 말고 근본적인 \\n사법개혁을 고민하기를 바란다\"고 강조했다. '" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 문장내 (도메인 주소) 부분 제거하기\n", "string_data = \"\"\"그러면서 (taken@kookmin.com) \"문재인 대통령은 조국 장관 임명으로 민심을 분열시킨 책임을 엄중히 느끼고 \n", "제대로 된 개혁 작업을 추진하기를 바란다\"며 \"특히 검찰개혁이 사법개혁의 전체인양 호도하지 말고 근본적인 \n", "사법개혁을 고민하기를 바란다\"고 강조했다. (bright@newsis.com)\"\"\"\n", "token_str = \"\\([A-z0-9\\._+]*@[A-z]+\\.(com|org|net|edu|co.kr)\\)\"\n", "\n", "import re\n", "re.sub(token_str, \"\", string_data)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['com', 'com']" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# .findall 을 사용하면 결과를 찾지 못함\n", "# 제대로 찾지 못한 경우\n", "re.findall(token_str, string_data)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'(taken@kookmin.com)'" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# .search 를 사용하면 제대로 된 결과 1개만 출력\n", "re.search(token_str, string_data).group()" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(taken@kookmin.com)\n", "(bright@newsis.com)\n" ] } ], "source": [ "# .finditer 를 사용하면 여러개를 찾는다\n", "# https://stackoverflow.com/questions/8110059/python-regex-search-and-findall\n", "for match in re.finditer(token_str, string_data):\n", " print (match.group(0))" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['aaaa', 'aabbbb']" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 1개(+) 와 0개(*) 의 포함여부 차이\n", "tokenizer = re.compile(\"a+b*\")\n", "tokenizer.findall(\"aaaa, ccc, bbbb, aabbbb\")" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['abc']" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 시작조건 특정\n", "tokenizer = re.compile(\"^a..\")\n", "tokenizer.findall(\"abc, cba\")" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['aabb', 'aaabb']" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 일치 갯수의 특정\n", "tokenizer = re.compile(\"a{2,3}b{2,3}\")\n", "tokenizer.findall(\"aabb, aaabb, ab, aab\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## **2 김기현의 딥러닝 자연어 분석**\n", "Regex Tutorials" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "010-1234-1234 park\n", "010-1234-1234 park\n" ] }, { "data": { "text/plain": [ "'1232=3124'" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 객체의 치환\n", "import re\n", "p = re.compile(r\"(?P\\w+)\\s+(?P(\\d+)[-]\\d+[-]\\d+)\")\n", "print(p.sub(\"\\g \\g\", \"park 010-1234-1234\"))\n", "\n", "p = re.compile(r\"(?P\\w+)\\s+(?P(\\d+)[-]\\d+[-]\\d+)\")\n", "print(p.sub(\"\\g<2> \\g<1>\", \"park 010-1234-1234\"))\n", "\n", "dot_to_nun = re.compile(r\"(?P(\\d+)).(?P(\\d+))\")\n", "dot_to_nun.sub(\"\\g=\\g\", \"1232.3124\")" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['sales.xls, test.xls']" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import re\n", "re.findall('.+', \"sales.xls, test.xls\")" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['
', '
']" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "re.findall('(
|
)', \"
텍스트
\")" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "010-1234-1234 park\n" ] } ], "source": [ "import re\n", "p = re.compile(r\"(?P\\w+)\\s+(?P(\\d+)[-]\\d+[-]\\d+)\")\n", "print(p.sub(\"\\g \\g\", \"park 010-1234-1234\"))" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['$23.24', '$69.23']" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "text = \"$23.24 의 가격은 $69.23 까지 상승하였습니다\"\n", "p = re.compile(r\"\\$[0-9.]+\")\n", "p.findall(text)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['23.24', '69.23']" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p = re.compile(r\"(?<=\\$)[0-9.]+\")\n", "p.findall(text)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# **Regex 정규식의 사용**\n", "\n", "## **1 Re 모듈의 기본 사용법**\n", "1. **re.findall() :** 조건에 해당되는 모든 객체 추출\n", "1. **re.search() :** () 그룹 검색결과 추출\n", "1. **re.sub() :** 문자열 교체" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ ">>> re.findall() \n", "['sentence', 'sentence', 'sentence']\n", "\n", ">>> re.groups \n", "1st group: Doe\n", "2nd group: John\n", "3rd group: 1111-1212\n", "\n", ">>> re.sub()\n", "Phone Num : 1111-2222-3333 \n", "\n", ">>> Revised contactINFO : Doe, Peter: 1111-1212\n" ] } ], "source": [ "import re\n", "def basicregex():\n", " contactInfo = 'Doe, John: 1111-1212'\n", " line = \"This is test sentence and test sentence is also a sentence.\"\n", " findallobj = re.findall(r'sentence', line) \n", " print (\">>> re.findall() \\n{}\\n\".format(findallobj))\n", " \n", " groupwiseobj = re.search(r'(\\w+), (\\w+): (\\S+)', contactInfo) \n", " print (\">>> re.groups \\n1st group: {}\\n2nd group: {}\\n3rd group: {}\".format(\n", " groupwiseobj.group(1), groupwiseobj.group(2), groupwiseobj.group(3)))\n", " \n", " phone = \"1111-2222-3333 # This is Phone Number\"\n", " num = re.sub(r'#.*$', \"\", phone)\n", " print (\"\\n>>> re.sub()\\nPhone Num : {}\".format(num))\n", "\n", " contactInforevised = re.sub(r'John', \"Peter\", contactInfo)\n", " print (\"\\n>>> Revised contactINFO : \", contactInforevised)\n", " \n", "basicregex()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## **2 .match(), .search()**\n", "1. **.match() :** 문자열 **시작부분의** 일치여부 확인\n", "1. **.search() :** 문자열 **아무 곳** 일치여부 확인" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "No 're.match'!!\n", "re.search: animals\n" ] } ], "source": [ "import re\n", "def searchvsmatch():\n", " line = \"I love animals.\";\n", " matchObj = re.match(r'animals', line, re.M | re.I)\n", " if matchObj:\n", " print (\"match: \", matchObj.group())\n", " else:\n", " print (\"No 're.match'!!\")\n", "\n", " searchObj = re.search(r'animals', line, re.M | re.I)\n", " if searchObj:\n", " print (\"re.search: \", searchObj.group())\n", " else:\n", " print (\"Nothing found!!\")\n", "\n", "searchvsmatch()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## **3 Re 플래그 및 사용법**\n", "1. 기본 플래그 : 정규식 검색시 설정값을 추가할 수 있다\n", "1. [re 플래그 사용예제](https://m.blog.naver.com/PostView.nhn?blogId=happy_jhyo&logNo=70144999358&proxyReferer=https%3A%2F%2Fwww.google.com%2F)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[('about', '12345'), ('b', '444'), ('c', '100')]" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import re\n", "m1 = 'about = 12345 \\n b = 444 \\t c=100'\n", "p1 = r'([a-zA-Z]\\w*)\\s*=\\s*(\\d+)'\n", "re.findall(p1, m1)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('about', '12345')" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cp = re.compile(p1)\n", "m = re.match(cp,m1)\n", "m.groups() # m.group(1), m.group(2)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(['the'], ['the', 'The'])" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# re.I : 대소문자 무시\n", "m1 = 'tTh cat was hungry, they were scare because of The cat'\n", "p1 = re.compile('the')\n", "p2 = re.compile('the', re.I)\n", "\n", "r1 = re.findall(p1, m1)\n", "r2 = re.findall(p2, m1)\n", "r1, r2" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['tTh', 'they']" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# re.M : 각 줄마다 반복\n", "m1 = '''tTh cat was hungry,\n", "they were scare because of The cat'''\n", "p1 = re.compile('^[a-zA-Z]\\w+', re.I|re.M)\n", "r1 = re.findall(p1, m1)\n", "r1" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "([], ['hungry,\\n they'])" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# re.S : 모든 문자에 \\n 등도 포함\n", "m1 = '''tTh cat was hungry,\n", " they were scare because of The cat'''\n", "p1 = re.compile('hungry,.*they', re.I)\n", "p2 = re.compile('hungry,.*they', re.I|re.S)\n", "\n", "r1 = re.findall(p1, m1)\n", "r2 = re.findall(p2, m1)\n", "r1, r2" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'\\n'" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# re.X : 문자열이 아닌 문장을 정규식을 할 수 있다.\n", "s = '''\\n\\ntitle\\n\n", "THis is bodyspam\n", "\\n\\n\n", "'''\n", "p = r'''\\s*.*\\s*.*'''\n", "r = re.match(p, s, re.X)\n", "r.group()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## **4 고급 레벨 정규표현식**\n", "1. **(?=re패턴) Positive LookAhead :** 정의된 패턴 **앞의** 문자열을 추출\n", "1. **(?<=re패턴) Positive LookBehind :** 정의된 패턴 **다음의** 문자열을 추출\n", "1. **(?!re패턴) Negative LookAhead :** 정의된 패턴을 **따르지 않는 앞의** 문자열을 추출\n", "1. **(? {'a','e','l','p'}\n", "def known(words):\n", " return set(w for w in words if w in WORDS)\n", "\n", "known('aple'), P('able')" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['waple', 'aplre', 'apje', 'apkle', 'uple', 'baple', 'ahple']" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 단어 편집거리 측정함수\n", "def edits1(word):\n", " a_z = 'abcdefghijklmnopqrstuvwxyz'\n", " splits = [(word[:i],word[i:]) for i in range(len(word)+1)] # 단어의 분리\n", " deletes = [L+R[1:] for L,R in splits if R] # 예제1) 1개단어 없는 예\n", " transposes = [L+R[1]+R[0]+R[2:] for L,R in splits if len(R)>1] # 예제2) 중간단어 섞인 예\n", " replaces = [L+c+R[1:] for L,R in splits if R for c in a_z] # 예제3) a-z 1개씩 변경 예\n", " inserts = [L+c+R for L,R in splits for c in a_z] # 예제4) a-z 1개씩 추가 예\n", " return set(deletes+transposes+replaces+inserts) # 예제1 ~ 예제4 모두 생성\n", "\n", "list(edits1('aple'))[:7]" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ ". at 0x7f9b0967d518>" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# \"All edits that are two edits away from `word`.\"\n", "def edits2(word): \n", " return (e2 for e1 in edits1(word) for e2 in edits1(e1))\n", "edits2('aple')" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "able\n", "correction\n", "statement\n", "tutor\n", "detective\n" ] } ], "source": [ "# \"Generate possible spelling corrections for word.\"\n", "def candidates(word): \n", " return (known([word]) or known(edits1(word)) or known(edits2(word)) or [word])\n", "\n", "# \"Most probable spelling correction for word.\"\n", "def correction(word): \n", " return max(candidates(word), key=P)\n", "\n", "print (correction('aple'))\n", "print (correction('correcton'))\n", "print (correction('statament'))\n", "print (correction('tutpore'))\n", "print (correction('datactive')) # 갯수는 동일하지만 철자만 다른경우 정확도 높음" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## **6 Word Piece Model 한글실습**\n", "- defaultDict 단어 token 을 만든 뒤,\n", "- Bi-Gram 빈도를 기준으로 단어 Token 을 찾기" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['아 버 지 께 ', '아 버 지 를 ', '아 버 지 에 게 ', '아 버 지 와 ']" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 단어 Token 을 음절단위로 구분하기\n", "data = [\" \".join(list(_)+[\"\"]) \n", " for _ in [\"아버지께\", \"아버지를\", \"아버지에게\", \"아버지와\"]]\n", "data" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "dict_values([5, 2, 6, 3])" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data = {\n", " \"아 버 지 께 \":5,\n", " \"아 버 지 를 \":2,\n", " \"아 버 지 에 게 \":6,\n", " \"아 버 지 와 \":3,\n", "}\n", "data.values()" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from collections import defaultdict\n", "# N-Gram 생성함수\n", "def findNagram(data):\n", " pair = defaultdict(int)\n", " for k, v in data.items():\n", " tokens = k.split()\n", " for i in range(len(tokens)-1):\n", " pair[tuple(tokens[i:i+2])] += v\n", " return pair\n", "\n", "# maxValue 변수를 추가해 반복 횟수를 제한 합니다\n", "def mergeNgram(maxKey, data):\n", " newData = dict()\n", " for k, v in data.items():\n", " newKey = re.sub(\" \".join(maxKey),\n", " \"\".join(maxKey), k)\n", " newData[newKey] = v\n", " return newData\n", "\n", "maxValue = max(data.values())\n", "maxValue" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'아버지 께 ': 5, '아버지 를 ': 2, '아버지 에 게 ': 6, '아버지 와 ': 3}\n" ] }, { "data": { "text/plain": [ "defaultdict(int,\n", " {('아버지', '께'): 5,\n", " ('께', ''): 5,\n", " ('아버지', '를'): 2,\n", " ('를', ''): 2,\n", " ('아버지', '에'): 6,\n", " ('에', '게'): 6,\n", " ('게', ''): 6,\n", " ('아버지', '와'): 3,\n", " ('와', ''): 3})" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 작업을 반복하며 고유한 단어를 찾습니다\n", "for _ in range(1000):\n", " pairList = findNagram(data)\n", " maxKey = max(pairList, key=pairList.get)\n", " #print(maxKey, pairList[maxKey])\n", " \n", " if pairList[maxKey] > maxValue:\n", " data = mergeNgram(maxKey, data)\n", " else: \n", " break\n", "print(data)\n", "pairList" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

\n", "# **손에 잡히는 정규표현식**\n", "## **1 문자 다루기**" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['홈페이지']" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sample = \"\"\"저의 이름은 벤 입니다. \n", "홈페이지 주소는 https://www.forta.com 입니다\n", " \"\"\"\n", "\n", "import re\n", "re.findall('홈페이지', sample)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['저', '의', ' ', '이', '름', '은', ' ', '벤', ' ', '입', '니', '다', '.', ' ', '홈']" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# '.' : 문자, 알파벳, 숫자, 문장부호 모두포함 (공백도 포함)\n", "re.findall('.', sample)[:15]" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['저의', ' 이', '름은', ' 벤', ' 입', '니다', '. ', '홈페', '이지']" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# '..' : 공백포함 2개 단어목록을 추출\n", "re.findall('..', sample)[:9]" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['.', '.', '.', '.', '.']" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 연산기호가 아닌 순수한 \".\" 을 추출합니다.\n", "re.findall('\\.', sample)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['\\n', '\\n']" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "re.findall('\\n', sample)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['저의', '', '이름은', '', '벤', '', '입니다', '', '', '']" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "re.findall('[A-z가-힣]*', sample)[:10]" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['.', 'https', 'www.forta.com', 'a', 'href', 'https', 'www.forta.com', 'a']" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# '.' 을 포함한 문자\n", "re.findall('[A-z.]+', sample)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## **2 문자 집합으로 찾기**\n", "Grouping" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'서울경기도'" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sample = \"\"\"문장에서 '정규식의 활용'을 \n", "파이썬 이외에 다양한 언어에서도 활용 가능합니다\"\"\"\n", "\n", "sample = \"\"\"이번 주문은 처리가 가능합니다.\n", "단 거주지가 서울경기도 에 제한됩니다\"\"\"\n", "\n", "# .* : 탐욕적 수량자 (조건에 포함되는 큰 덩어리를 추출)\n", "re.findall('.*', sample)[0]" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['서울', '경기도']" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# .*? : 게으른 수량자 (조건에 포함되는 작은 덩어리들을 추출)\n", "re.findall('.*?', sample)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['고양이', '고양이']" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sample = \"\"\"고양이 는 강이지와 함께 고양이 새끼들을 키운다\"\"\"\n", "# sample = \"\"\"The cat scattered his food all over the room.\"\"\"\n", "re.findall('[\\b고양이\\b]', sample)\n", "re.findall('고양이', sample)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "re.findall('[\\bcat\\b]', sample)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['http://www', 'https://www']" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sample = \"\"\" http://www.daun.net 또는 https://www.naver.com\"\"\"\n", "re.findall('https?://www.*?', sample)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['19', '20']" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sample = \"\"\" 1999-12-11 년도의 작업이 2019-01-11 작업을 진행합니다 \"\"\"\n", "re.findall('(19|20)[0-9]+', sample)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "' 010-9999-3333 010-5555-3333 010-5554-2351'" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sample = \"\"\" 010-9999-3333 010-5555-3333 010-5554-2351\"\"\"\n", "re.sub('(\\d{3})(-)(\\d{3,4})(-)(\\d{3,4})', '\\g<0>', sample)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(' 010:9999:3333 010:5555:3333 010:5554:2351', 3)" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# \"\\g<인덱스> : 앞에서 추출한 객체들을 재활용시 인덱스값 활용\"\n", "re.subn('(\\d{3})(-)(\\d{3,4})(-)(\\d{3,4})', '\\g<1>:\\g<3>:\\g<5>', sample)" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(' 010:9999:3333 010:5555:3333 010:5554:2351', 3)" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 객체 재활용시 \"인덱스 이름\"을 활용\n", "re.subn('(?P\\d{3})(-)(?P\\d{3,4})(-)(?P\\d{3,4})', '\\g:\\g:\\g', sample)" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['제목을 입력 합니다. ']" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sample = \"\"\" 제목을 입력 합니다. \"\"\"\n", "re.findall('<[titleTITLE]+>.*<[/titleTITLE]+>', sample)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## **실전 블로그 작업 시작하기**\n", "- **식재료** 목록 (원본데이터를 그대로 활용하기)\n", "- **식품** 목록 (한식메뉴 목록 데이터)" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sample = \"\"\" \n", " 재료: 돼지고기, 파, 양파, 호박, 양배추, 전분, 면\n", " 양념: 춘장, 식용유, 간장, 설탕\n", "\"\"\"\n", "re.findall('된장국*?\\w+', sample)" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['sam.xls', 'sax.xls']" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 파일이름 필터링\n", "sample = \"na1.xls na2.xls sa2.xls sam.xls sandwich.xls sax.xls\"\n", "\n", "import re\n", "re.findall('[ns]a[^0-9]\\.xls', sample)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.8" } }, "nbformat": 4, "nbformat_minor": 4 }