1. 初識(shí)正則表達(dá)式
1.1 介紹
- 步驟介紹
正則表達(dá)式入門(mén)及應(yīng)用
正則表達(dá)式的進(jìn)階
正則表達(dá)式案例
1.2 正則表達(dá)式基本操作
- 什么是正則表達(dá)式
正則表達(dá)式(regex
)是一些由字符和特殊符號(hào)組成的字符串细层。
正則表達(dá)式是能按照某種模式匹配一系列有相似特征的字符串毒姨。 - 正則表達(dá)式中的符號(hào)
符號(hào) | 描述 | 示例 |
---|---|---|
literal |
匹配文本字符串的字面值literal
|
foo |
re1|re2 |
匹配正則表達(dá)式re1 或者re2
|
foo|bar |
. |
匹配任何字符(除了\n 之外) |
b.b |
^ |
匹配字符串起始部分 | ^Dear |
$ |
匹配字符串終止部分 | /bin/*sh$ |
* |
匹配0 次或多次前面出現(xiàn)的正則表達(dá)式 |
[A-Za-z0-9]* |
+ |
匹配1 次或多次前面出現(xiàn)的正則表達(dá)式 |
[a-z]+\.com |
? |
匹配0 次或1 次前面出現(xiàn)的正則表達(dá)式,或指明非貪婪限模式匹配炮温。 |
goo? |
{N} |
匹配N 次前面出現(xiàn)的正則表達(dá)式 |
[0-9]{3} |
{M, N} |
匹配M-N 次前面出現(xiàn)的正則表達(dá)式 |
[0-9]{5,9} |
[...] |
匹配來(lái)自字符集的任意單一字符 | [aeiou] |
[x-y] |
匹配x~y 范圍中的任意單一字符 |
[0-9],[A-Za-z] |
[^...] |
不匹配此字符集中出現(xiàn)的任何一個(gè)字符摧莽,包括某一范圍的字符(如果此字符集中出現(xiàn)) | [^aeiou],[^A-Za-z0-9] |
(...) |
匹配封閉的正則表達(dá)式颠放,然后另存為子組 | ([0-9]{3}?,f(oo|u)bar |
貪婪模式:在整個(gè)表達(dá)式匹配成功的前提下岖是,盡可能多的匹配字符轴咱。
非貪婪模式:在整個(gè)表達(dá)式匹配成功的前提下,盡可能少的匹配字符剪廉。
注釋:默認(rèn)是貪婪模式娃循。
- 正則表達(dá)式中的特殊字符
\d
- 匹配一個(gè)數(shù)字字符。等價(jià)于[0-9]
\D
- 匹配一個(gè)非數(shù)字字符斗蒋。等價(jià)于[^0-9]
\w
- 匹配包括下劃線的任何單詞字符捌斧。等價(jià)于[A-Za-z0-9_]
\W
- 匹配任何非單詞字符。等價(jià)于[^A-Za-z0-9_]
\s
- 匹配任何不可見(jiàn)字符泉沾,包括空格捞蚂、制表符、換頁(yè)符等
\S
- 匹配任何可見(jiàn)字符
\b
- 匹配一個(gè)單詞的邊界
\B
- 匹配非單詞邊界
\n
- 匹配一個(gè)換行符 - 修飾符
re.I
-使匹配對(duì)大小寫(xiě)不敏感
re.L
-做本地化識(shí)別(locale-aware
)匹配
re.M
-多行匹配跷究,影響^
和$
re.S
-使.
匹配包括換行在內(nèi)的所有字符
1.3 正則表達(dá)式應(yīng)用
- 身份證號(hào)碼匹配
區(qū)域編號(hào)姓迅、出生年份、出生日期俊马、性別(倒數(shù)第二位)
(\d{6})(\d{4})((\d{2})(\d{2}))\d{2}\d([0-9]|X)
- 電子郵箱表達(dá)式匹配
[a-zA-Z0-9_-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*(\.[a-zA-Z]{2,5})
- 貪婪模式與非貪婪模式
import re
content = "abcabca"
regex1 = re.compile('ab.*a')
regex2 = re.compile('ab.*?a')
print(regex1.match(content).group()) # abcabca
print(regex2.match(content).group()) # abca
1.4 正則表達(dá)式進(jìn)階
- 使用
re
模塊直接匹配
import re
print(re.match('hello', 'hello world')) # <re.Match object; span=(0, 5), match='hello'>
- 先編譯再匹配
import re
# 將正則表達(dá)式編譯
pattern = re.compile('hello')
# 通過(guò)match進(jìn)行匹配
result = pattern.match('hello world')
print(result) # <re.Match object; span=(0, 5), match='hello'>
注釋:先編譯再匹配的方式性能較高丁存。
- 匹配不到則返回
None
import re
pattern = re.compile('hello')
print(pattern.match('Hello')) # None
- 忽略大小寫(xiě)
import re
pattern = re.compile('hello', re.I)
print(pattern.match('Hello')) # <re.Match object; span=(0, 5), match='Hello'>
-
r
轉(zhuǎn)義
使用Python
的r
前綴,就不用考慮轉(zhuǎn)義的問(wèn)題了潭袱。
import re
pattern1 = re.compile('A\\b')
pattern2 = re.compile(r'A\b')
print(pattern1.match('A\b'))
# <re.Match object; span=(0, 1), match='A'>
print(pattern1.match('A\b'))
# <re.Match object; span=(0, 1), match='A'>
注釋:pattern1
和pattern2
寫(xiě)法等價(jià)柱嫌。
-
findall
方法
import re
content = 'a1B22ccc333D4'
p2 = re.compile(r'[a-z]+', re.I)
print(p2.findall(content)) # ['a', 'B', 'ccc', 'D']
print(re.findall(r'[a-z]+', content, re.I)) # ['a', 'B', 'ccc', 'D']
print(re.findall(r'([a-z])\d', content, re.I)) # ['a', 'B', 'c', 'D']
print(re.findall(r'([a-z]+)(\d)', content, re.I)) # [('a', '1'), ('B', '2'), ('ccc', '3'), ('D', '4')]
注釋:group
與findall
結(jié)合使用時(shí),findall
可以匹配組內(nèi)字符串屯换。
-
search
方法
import re
content = 'hello world!'
regex = re.compile(r'world')
print(regex.search(content))
# <re.Match object; span=(6, 11), match='world'>
print(re.search(r'world', content))
# <re.Match object; span=(6, 11), match='world'>
-
match()
與search()
的區(qū)別
match()
函數(shù)只檢測(cè)字符串開(kāi)頭位置是否匹配编丘,匹配成功返回結(jié)果。用于判斷字符串開(kāi)頭或整個(gè)字符串是否匹配彤悔,速度快嘉抓。
search()
會(huì)整個(gè)字符串查找,直到找到一個(gè)匹配。
import re
content = 'hello world!'
print(re.search(r'hello', content))
# <re.Match object; span=(0, 5), match='hello'>
print(re.search(r'world', content))
# <re.Match object; span=(6, 11), match='world'>
print(re.match(r'hello', content))
# <re.Match object; span=(0, 5), match='hello'>
print(re.match(r'world', content))
# None
-
group()
和groups()
的使用
import re
result = re.search(r'world', 'hello world!')
print(result)
# <re.Match object; span=(6, 11), match='world'>
print(result.group()) # world
print(result.groups()) # ()
identity = '411423202010060028'
regex = re.compile(r'(\d{6})(?P<year>\d{4})((?P<month>\d{2})(?P<day>\d{2}))\d{2}\d(?P<sex>[0-9]|X)')
result = regex.search(identity)
print(result.group()) # 411423202010060028
print(result.group(2)) # 2020
print(result.groups()) # ('411423', '2020', '1006', '10', '06', '8')
print(result.groupdict())
# {'year': '2020', 'month': '10', 'day': '06', 'sex': '8'}
注釋:(?P<name>regex)
表示給組regex
命名為name
晕窑。
-
split()
正則切割
import re
s = 'one1two22three333four4five5six6'
print(re.split(r'\d+', s))
# ['one', 'two', 'three', 'four', 'five', 'six', '']
-
sub()
正則替換
import re
# 字符替換
s = 'one1two22three333four4five5six6'
s1 = re.sub(r'\d+', '@', s)
print(s1)
# one@two@three@four@five@six@
# 分組替換
s2 = 'hello world'
s3 = re.sub(r'(\w+) (\w+)', r'\2 \1', s2)
print(s3) # world hello
# 復(fù)雜替換
s3 = 'hello world'
s4 = re.sub(r'(\w+) (\w+)', lambda m: m.group(2).upper() + ' ' + m.group(1).upper(), s2)
print(s4) # WORLD HELLO
1.5 正則表達(dá)式綜合實(shí)戰(zhàn)
- 匹配
html
字符串中的圖片src
import re
with open('src.html', encoding='utf-8') as f:
html = f.read()
regex = re.compile(r'<img.+?src="(.+?)".+?>')
images = regex.findall(html)
for ls in images:
print(ls)
注釋:?
實(shí)現(xiàn)非貪婪匹配抑片。findall
獲取group
內(nèi)字符串。
2. 綜合實(shí)戰(zhàn) - 飛機(jī)大戰(zhàn)
2.1 介紹
- 目標(biāo)
掌握面向?qū)ο?/strong>分析和開(kāi)發(fā)的思想
能對(duì)項(xiàng)目進(jìn)行拆分杨赤,進(jìn)行模塊化開(kāi)發(fā)
了解項(xiàng)目開(kāi)發(fā)的基本流程
理解并運(yùn)用Python
包敞斋、模塊相關(guān)知識(shí)
理解并運(yùn)用文件讀寫(xiě)截汪,函數(shù)式編程
理解簡(jiǎn)單2d游戲開(kāi)發(fā)的基本思路
掌握IDE調(diào)試技巧 - 重難點(diǎn)技能
面向?qū)ο蠓治黾伴_(kāi)發(fā)方法
Python
包與模塊:標(biāo)準(zhǔn)模塊和第三方模塊的使用
Python
多線程、多進(jìn)程的運(yùn)用
游戲開(kāi)發(fā)入門(mén)及對(duì)Pygame
的使用
2.2 Pygame介紹及使用
-
Pygame
介紹
2D
游戲開(kāi)發(fā)工具包植捎。 -
Pygame
文檔
http://www.pygame.org/docs/ -
Pygame
安裝
(1) 創(chuàng)建項(xiàng)目
image.png
(2) 安裝pygame
(PlaneWars) ? PlaneWars pip install pygame
Collecting pygame
Downloading https://files.pythonhosted.org/packages/32/37/453bbb62f90feff2a2b75fc739b674319f5f6a8789d5d21c6d2d7d42face/pygame-1.9.6-cp37-cp37m-macosx_10_11_intel.whl (4.9MB)
100% |████████████████████████████████| 4.9MB 1.5MB/s
Installing collected packages: pygame
Successfully installed pygame-1.9.6
(PlaneWars) ? PlaneWars python
import sys, pygame
# 1. pygame初始化
pygame.init()
size = width, height = 320, 240 # 元組衙解,等價(jià)于(320, 240)
speed = [2, 2]
black = 0, 0, 0 # 元組,等價(jià)于(0, 0, 0)
# 2. 創(chuàng)建窗口對(duì)象
screen = pygame.display.set_mode(size)
# 獲取圖片對(duì)象
ball = pygame.image.load("intro_ball.gif")
# 獲取圖片對(duì)象位置
ballrect = ball.get_rect()
# 3. 游戲主循環(huán)
while 1:
# 處理游戲事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# 更新游戲狀態(tài)(圖片對(duì)象位置)
ballrect = ballrect.move(speed)
if ballrect.left < 0 or ballrect.right > width:
speed[0] = -speed[0]
if ballrect.top < 0 or ballrect.bottom > height:
speed[1] = -speed[1]
# 窗口視圖繪制
screen.fill(black) # 使用黑色填充窗口
screen.blit(ball, ballrect) # 指定位置繪制圖片
pygame.display.flip() # 更新窗口
- 游戲中的圖片
(1) 圖片加載
bg = pygame.image.load(url)
(2) 獲取圖片尺寸
rect = bg.get_rect()
(3) 圖片移動(dòng)
rect.move((x, y))
(4) 圖片繪制
screen.blit(ball, (x, y)/rect)
import sys, pygame
# 初始化
pygame.init()
# 屏幕對(duì)象
screen = pygame.display.set_mode((500, 500))
# 加載圖片
ball = pygame.image.load('intro_ball.gif')
# 獲取圖片位置
rect = ball.get_rect()
while True:
# 處理事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# 繪制
screen.blit(ball, rect)
screen.blit(ball, rect.move([50, 50]))
screen.blit(ball, (100, 100))
pygame.display.flip()
注釋:pygame.display.set_mode()
和pygame.image.load()
方法返回值都是Surface
對(duì)象焰枢。Surface.get_size()
方法可以獲取尺寸蚓峦。
-
Surface
對(duì)象與Rect
對(duì)象
(1)Surface
對(duì)象
pygame.Surface.get_size
pygame.Surface.get_width
pygame.Surface.get_height
pygame.Surface.get_rect
(2)Rect
對(duì)象
pygame.Rect.move
Rect
對(duì)象具有幾個(gè)虛擬屬性,可用于移動(dòng)和對(duì)齊Rect
x
,y
,top
,left
,bottom
,right
,topleft
,bottomleft
,topright
,bottomright
,midtop
,midleft
,midbottom
,midright
,center
,centerx
,centery
,size
,width
,height
,w
,h
其中济锄,尺寸初始信息為圖片原始尺寸大小暑椰,位置初始信息為(0, 0)
。 - 游戲中的顏色和形狀
import sys, pygame
# 初始化
pygame.init()
# 屏幕對(duì)象
screen = pygame.display.set_mode((500, 500))
red = pygame.Color(255, 0, 0)
while True:
# 處理事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# 直線
pygame.draw.line(screen, red, (10, 10), (80, 80), 5)
# 矩形
pygame.draw.rect(screen, red, (100, 100, 50, 50), 1)
# 圓
pygame.draw.circle(screen, red, (300, 300), 50, 10)
pygame.display.flip()
- 游戲中的文字
import sys, pygame
pygame.init()
screen = pygame.display.set_mode((500, 500))
red = pygame.Color(255, 0, 0)
font = pygame.font.Font('./static/hwxw.ttf', 60) # 字體文件 字體大小
text = font.render('華文新魏', True, red, (255, 255, 255)) # 文字 平滑字體 文字顏色 背景顏色
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.blit(text, (20, 100))
pygame.display.flip()
注釋:顏色可以用pygame.Color(R, G, B)
生成荐绝,也可以用(R, G, B)
元組表示一汽。
- 游戲中的音樂(lè)
import sys, pygame
pygame.init()
screen = pygame.display.set_mode((500, 500))
pygame.mixer.music.load('./static/bg_music.mp3') # 加載音樂(lè)
pygame.mixer.music.set_volume(0.5) # 設(shè)置音量(0-1)
pygame.mixer.music.play(-1) # 循環(huán)播放
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
注釋:game.mixer.music
用來(lái)播放背景音樂(lè)。
- 游戲中的音效
import pygame
pygame.init()
sound = pygame.mixer.Sound('./static/bullet.wav')
sound.play()
while True:
pass
注釋:pygame.mixer.Sound()
播放音效低滩。音頻可以可以是OGG
音頻文件或者WAV
音頻文件
- 游戲中的動(dòng)畫(huà)切換
import sys, pygame
pygame.init()
screen = pygame.display.set_mode((500, 500))
hero1 = pygame.image.load('./static/hero1.png')
hero2 = pygame.image.load('./static/hero2.png')
clock = pygame.time.Clock()
count = 1
while True:
clock.tick(60) # 設(shè)置動(dòng)畫(huà)幀數(shù)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill((255, 255, 255))
# 等價(jià)寫(xiě)法: screen.fill(pygame.Color(255, 255, 255))
if count % 2 == 0:
screen.blit(hero1, (100, 100))
else:
screen.blit(hero2, (100, 100))
count += 1
pygame.display.flip()
- 精靈角虫、精靈組與碰撞檢測(cè)
(1) 兩個(gè)精靈之間的矩形檢測(cè)
pygame.sprite.collide_rect
pygame.sprite.collide_rect_ratio
(2) 兩個(gè)精靈之間的圓形檢測(cè)
pygame.sprite.collide_circle
pygame.sprite.collide_circle_ratio
(3) 兩個(gè)精靈之間的像素遮罩檢測(cè)
pygame.sprite.collide_mask
(4) 精靈與精靈組之間的碰撞檢測(cè)
pygame.sprite.spritecollide
(5) 兩個(gè)精靈組之間的碰撞檢測(cè)
pygame.sprite.groupcollide
(6) 將精靈從所有精靈組中刪除
pygame.sprite.Sprite.kill
(7) 刪除所有精靈
pygame.sprite.Group.empty
import sys, pygame
# 初始化
pygame.init()
# 屏幕對(duì)象
screen = pygame.display.set_mode((500, 500))
class Block(pygame.sprite.Sprite):
def __init__(self, color, x, y, width, height):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([width, height])
self.image.fill(color)
self.rect = pygame.Rect(x, y, width, height)
def move(self, x, y):
self.rect = self.rect.move(x, y)
s1 = Block((255, 0, 0), 50, 50, 50, 50)
s2 = Block((0, 255, 0), 90, 90, 100, 50)
while True:
# 處理事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.blit(s1.image, s1.rect)
screen.blit(s2.image, s2.rect)
# 矩形檢測(cè)碰撞
result1 = pygame.sprite.collide_rect(s1, s2)
# 使用縮放為一定比例的圓,檢測(cè)兩個(gè)小精靈之間的碰撞
result2 = pygame.sprite.collide_circle_ratio(0.5)(s1, s2)
print(result1, result2) # 1 False
pygame.display.flip()
2.3 實(shí)戰(zhàn):飛機(jī)大戰(zhàn)游戲
- 開(kāi)發(fā)步驟
面向?qū)ο箜?xiàng)目分析
項(xiàng)目初始化
載入我方飛機(jī)
載入敵方飛機(jī)
碰撞檢測(cè)委造、爆炸效果及音效
成績(jī)統(tǒng)計(jì) - 項(xiàng)目擴(kuò)展完善
使用多線程/多進(jìn)程來(lái)擴(kuò)展敵機(jī)數(shù)量
爆炸效果延時(shí)展示
添加游戲暫停功能
添加中型敵機(jī),大型敵機(jī)
添加多條生命
記錄玩家的多條分?jǐn)?shù)記錄
敵機(jī)發(fā)射子彈 - 代碼地址
https://github.com/nmwei/PlaneWars
https://github.com/nmwei/MyPlaneWars