###### tags: `python`
# 正則表達式(regular expression/regex)

在不可思議的情況下精準完成所要的字串處理,大概就是regex讓很多人產生的印象
## 一般情況的比對
```python=
msg = 'Please call my secretary using 0930-919-919 or 0952-001-001'
for i in range(len(msg)):
substring = msg[i:i+12]
print(i, substring)
```
## re.search: 找出第一個符合條件的內容
```python=
import re
msg1 = 'Please call my secretary using 0930-919-919 or 0952-001-001'
msg2 = '你好這是我的手機號碼: 0982-123-123'
msg3 = '10個Q&A快速認識Docker'
def parseString(string):
# phone_rule = re.compile(r'\d\d\d\d-\d\d\d-\d\d\d')
# phone_num = phone_rule.search(string)
# pattern = r'\d\d\d\d-\d\d\d-\d\d\d'
pattern = r'\d{4}-\d{3}-\d{3}'
phone_num = re.search(pattern, string)
if phone_num != None:
print('電話號碼: %s' % phone_num)
#print('\t', phone_num.group(), '\t', type(phone_num.group()))
else:
print('%s 不含電話號碼' % string)
parseString(msg1)
parseString(msg2)
parseString(msg3)
```
## re.findall: 找出所有符合的資料
```python=
import re
msg1 = 'Please call my secretary using 0930-919-919 or 0952-001-001'
msg2 = '你好這是我的手機號碼: 0982-123-123'
msg3 = '10個Q&A快速認識Docker'
def parseString(string):
# phone_rule = re.compile(r'\d\d\d\d-\d\d\d-\d\d\d')
# phone_num = phone_rule.findall(string)
pattern = r'\d{4}-\d{3}-\d{3}'
phone_num = re.findall(pattern, string)
print('電話號碼: %s, \t %s' % (phone_num, type(phone_num)))
parseString(msg1)
parseString(msg2)
parseString(msg3)
```
## 從文字檔讀取所需資料
users.txt 所有資料皆從網路上取得並加以移除變更部份資料
```
林XX 光X國O 校長 2058800#810 ta003stex@gmail.com
李XX 澳X國O 校長 24972000#130 scoutlex208@gmail.com
姜XX 和X國O 校長 26631400#201 cmx773@gmail.com
蔡XX 無 abc1414g@yahoo.com.tw
簡XX 北X國O 教師 0917511200 slchienx20@yahoo.com.tw
```
```python=
# Open file
import re
f = open('users.txt', 'r', encoding='utf8')
# Feed the file text into findall(); it returns a list of all the found strings
strings = re.findall(r'([\w\.-]+)@([\w\.-]+)', f.read())
print(strings)
```
## 擷取符合標準內容中的部份內容
```python=
import re
msg1 = 'Please call my secretary using 0930-919-919 or 0952-001-001'
msg2 = '你好這是我的手機號碼: 0982-123-123'
msg3 = '10個Q&A快速認識Docker'
def parseString(string):
# pattern = r'\d{4}-\d{3}-\d{3}'
# pattern = r'(\d{4})-\d{3}-\d{3}'
pattern = r'(\d{4})-(\d{3}-\d{3})'
phone_num = re.findall(pattern, string)
return phone_num
# print('電話號碼: %s, \t %s' % (phone_num, type(phone_num)))
phone_num1 = parseString(msg1)
print(phone_num1)
phone_num2 = parseString(msg2)
print(phone_num2)
phone_num3 = parseString(msg3)
print(phone_num3)
print()
print(phone_num1[0])
print(phone_num1[0][0])
```
## 取得match物件的值:group()
```python=
import re
msg1 = 'Please call my secretary using 0930-919-919 or 0952-001001'
msg2 = '你好這是我的手機號碼: 0982-123-123'
def parseString(string):
pattern = r'(\d{4})-(\d{3}\d{3})'
phone_num = re.search(pattern, string)
return phone_num
phone = parseString(msg1)
print(phone)
print(phone.group())
print(phone.group(0))
print(phone.group(1))
print(phone.group(2))
print()
first_num, second_num = phone.groups()
print("first_num: ", first_num)
print("second_num: ", second_num)
```
```python=
str = 'purple alice-b@google.com monkey dishwasher'
match = re.search(r'([\w.-]+)@([\w.-]+)', str)
if match:
print(match.group()) ## 'alice-b@google.com' (the whole match)
print(match.group(1)) ## 'alice-b' (the username, group 1)
print(match.group(2)) ## 'google.com' (the host, group 2)
```
## 多重指定:groups()
```python=
import re
phone = '(02)1234-5678'
pattern = r'(\(\d{2}\))(\d{4})-(\d{4})' # 在這個例子中,不能有空格
phone_num = re.search(pattern, phone)
area_num, local_num1, local_num2 = phone_num.groups() # 多重指定
print("area_num: ", area_num)
print("local_num1: ", local_num1)
print("local_num2: ", local_num2)
```
```python=
import re
num1 = '0212345678'
num2 = '02-12345678'
num3 = '(02)12345678'
num4 = '(02)1234-5678'
# pattern = r'\d\d\d\d\d\d\d\d\d\d'
pattern = r'\d{10}'
result = re.search(pattern, num)
print(result.group())
# pattern = r'\d\d-\d\d\d\d\d\d\d\d'
pattern = r'\d{2}-\d{8}'
result = re.search(pattern, num2)
print(result.group())
# pattern = r'(\(\d\d\))\d\d\d\d\d\d\d\d'
pattern = r'(\(\d{2}\))\d{8}'
result = re.search(pattern, num3)
print(result.group())
pattern = r'(\(\d{2}\))\d{4}-\d{4}'
result = re.search(pattern, num4)
print(result.group())
```
## 其中之一:|
```python=
import re
msg = 'A mouse, plural mice, is a small rodent characteristically having a pointed snout, small rounded ears, a body-length scaly tail and a high breeding rate. The best known mouse species is the common house mouse (Mus musculus). It is also a popular pet. In some places, certain kinds of field mice are locally common. They are known to invade homes for food and shelter.'
pattern = 'mouse|mice' # | 前後不要留空白
results = re.findall(pattern, msg)
print('關於老鼠出現的次數: ', len(results))
print(results)
```
```python=
import re
pattern = "Johnson|Johnnason|Johnnathan"
testString = "Johnson, Johnnason and Johnnathan will attend my party tonight"
matchArray = re.findall(pattern, testString)
print(matchArray)
pattern = "John(son|nason|nathan)"
matchArray = re.findall(pattern, testString)
print(matchArray)
```
## 多個分組的管道搜尋
```python=
import re
msg = "Rabbits and hares are in the same taxonomic family, Leporidae, but they are in different genera. There are 11 genera within the family, but the term “true hares” refers only to species in the genus Lepus; all others are rabbits. Also, the American Rabbit Breeders Association (ARBA) recognizes 49 rabbit breeds."
pattern = '(rabbits|rabbit)' # | 前後不要留空白
results = re.findall(pattern, msg, re.I) # re.I 不管大小寫
print('關於老鼠出現的次數: ', len(results))
print(results)
# 順序導致取出結果有差
pattern = '(rabbit|rabbits)' # | 前後不要留空白
results = re.findall(pattern, msg, re.I) # re.I 不管大小寫
print('關於老鼠出現的次數: ', len(results))
print(results)
print()
msg = 'Johnson, Johnnason and Johnnathan will attend my party tonight.'
pattern = 'John(son|nason|nathan)'
results = re.findall(pattern, msg)
print(results)
pattern ="Johnson|Johnnason|Johnnathan"
results = re.findall(pattern, msg)
print(results)
```
## 可有可無:?
```python=
import re
regex = re.compile("<[bi]>(\*)</[bi]>")
testString = "This is optional section which shows a more advanced regular expression technique not needed for the exercises. Suppose you have text with tags in it: <b>foo</b> and <i>so on</i>"
matchArray = regex.findall(testString)
print(matchArray)
```
## 練習
```python=
import re
regex = re.compile("")
testString = "This is optional section which shows a more advanced regular expression technique not needed for the exercises. Suppose you have text with tags in it: <b>foo</b> and <i>so on</i>"
matchArray = regex.findall(testString)
print(matchArray)
```
```python=
import re
testString = """
<html>
<p>hello</p>
<a href="http://tw.yahoo.com">yahoo site</a>
<b>2018/12/1<b>
</html>"""
regex = re.compile("") # 只找<a>, <p>內的內容
matchArray = regex.findall(testString)
print(matchArray)
regex = re.compile("") # 所有
matchArray = regex.findall(testString)
print(matchArray)
```
## 參考資料
- [Regular Expression介紹](http://120.105.184.250/cswang/thit/Linux/RegularExpression.htm)
- [Python Regular Expressions](https://developers.google.com/edu/python/regular-expressions)
- [https://Debuggex.com](https://www.debuggex.com/#cheatsheet)
- [RegexOne](https://regexone.com/) 很好的練習
- [Python Regular Expressions](https://developers.google.com/edu/python/regular-expressions)
- [正規表示式 - 線上產生器](https://cloudlab.tw/wp/sampleFiles/RegExp/)
- [Regex Generator](https://regex-generator.olafneumann.org/)