python正則

re模塊操作

在Python中需要通過正則表達(dá)式對字符串進(jìn)行匹配的時(shí)候器予,可以使用一個(gè)模塊勾习,名字為re

  1. re模塊的使用過程

    #coding=utf-8

    # 導(dǎo)入re模塊
    import re

    # 使用match方法進(jìn)行匹配操作
    result = re.match(正則表達(dá)式,要匹配的字符串)

    # 如果上一步匹配到數(shù)據(jù)的話湾盒,可以使用group方法來提取數(shù)據(jù)
    result.group()

  2. re模塊示例(匹配以itcast開頭的語句)

    #coding=utf-8

    import re

    result = re.match("itcast","itcast.cn")

    result.group()

運(yùn)行結(jié)果為:

itcast

  1. 說明

    re.match() 能夠匹配出以xxx開頭的字符串

匹配單個(gè)字符

在上一小節(jié)中,了解到通過re模塊能夠完成使用正則表達(dá)式來匹配字符串

本小節(jié)俐载,將要講解正則表達(dá)式的單字符匹配
字符 功能
. 匹配任意1個(gè)字符(除了\n)
[ ] 匹配[ ]中列舉的字符
\d 匹配數(shù)字捏萍,即0-9
\D 匹配非數(shù)字,即不是數(shù)字
\s 匹配空白项炼,即 空格,tab鍵
\S 匹配非空白
\w 匹配單詞字符,即a-z墨坚、A-Z亏拉、0-9、_
\W 匹配非單詞字符
示例1: .

#coding=utf-8

import re

ret = re.match(".","M")
print(ret.group())

ret = re.match("t.o","too")
print(ret.group())

ret = re.match("t.o","two")
print(ret.group())

運(yùn)行結(jié)果:

M
too
two

示例2:[ ]

#coding=utf-8

import re

如果hello的首字符小寫,那么正則表達(dá)式需要小寫的h

ret = re.match("h","hello Python")
print(ret.group())

如果hello的首字符大寫爆班,那么正則表達(dá)式需要大寫的H

ret = re.match("H","Hello Python")
print(ret.group())

大小寫h都可以的情況

ret = re.match("[hH]","hello Python")
print(ret.group())
ret = re.match("[hH]","Hello Python")
print(ret.group())
ret = re.match("[hH]ello Python","Hello Python")
print(ret.group())

匹配0到9第一種寫法

ret = re.match("[0123456789]Hello Python","7Hello Python")
print(ret.group())

匹配0到9第二種寫法

ret = re.match("[0-9]Hello Python","7Hello Python")
print(ret.group())

ret = re.match("[0-35-9]Hello Python","7Hello Python")
print(ret.group())

下面這個(gè)正則不能夠匹配到數(shù)字4后众,因此ret為None

ret = re.match("[0-35-9]Hello Python","4Hello Python")
# print(ret.group())

運(yùn)行結(jié)果:

h
H
h
H
Hello Python
7Hello Python
7Hello Python
7Hello Python

示例3:\d

#coding=utf-8

import re

普通的匹配方式

ret = re.match("嫦娥1號","嫦娥1號發(fā)射成功")
print(ret.group())

ret = re.match("嫦娥2號","嫦娥2號發(fā)射成功")
print(ret.group())

ret = re.match("嫦娥3號","嫦娥3號發(fā)射成功")
print(ret.group())

使用\d進(jìn)行匹配

ret = re.match("嫦娥\d號","嫦娥1號發(fā)射成功")
print(ret.group())

ret = re.match("嫦娥\d號","嫦娥2號發(fā)射成功")
print(ret.group())

ret = re.match("嫦娥\d號","嫦娥3號發(fā)射成功")
print(ret.group())

運(yùn)行結(jié)果:

嫦娥1號
嫦娥2號
嫦娥3號
嫦娥1號
嫦娥2號
嫦娥3號
匹配多個(gè)字符

匹配多個(gè)字符的相關(guān)格式
字符 功能

  • 匹配前一個(gè)字符出現(xiàn)0次或者無限次,即可有可無
  • 匹配前一個(gè)字符出現(xiàn)1次或者無限次,即至少有1次
    ? 匹配前一個(gè)字符出現(xiàn)1次或者0次抗碰,即要么有1次,要么沒有
    {m} 匹配前一個(gè)字符出現(xiàn)m次
    {m,n} 匹配前一個(gè)字符出現(xiàn)從m到n次
    示例1:*

需求:匹配出是复,一個(gè)字符串第一個(gè)字母為大小字符,后面都是小寫字母并且這些小寫字母可有可無

#coding=utf-8
import re

ret = re.match("[A-Z][a-z]*","M")
print(ret.group())

ret = re.match("[A-Z][a-z]*","MnnM")
print(ret.group())

ret = re.match("[A-Z][a-z]*","Aabcdef")
print(ret.group())

運(yùn)行結(jié)果:

M
Mnn
Aabcdef

示例2:+

需求:匹配出,變量名是否有效

#coding=utf-8
import re

names = ["name1", "_name", "2_name", "name"]

for name in names:
ret = re.match("[a-zA-Z_]+[\w]*",name)
if ret:
print("變量名 %s 符合要求" % ret.group())
else:
print("變量名 %s 非法" % name)

運(yùn)行結(jié)果:

變量名 name1 符合要求
變量名 _name 符合要求
變量名 2_name 非法
變量名 name 符合要求

示例3:?

需求:匹配出,0到99之間的數(shù)字

#coding=utf-8
import re

ret = re.match("[1-9]?[0-9]","7")
print(ret.group())

ret = re.match("[1-9]?\d","33")
print(ret.group())

ret = re.match("[1-9]?\d","09")
print(ret.group())

運(yùn)行結(jié)果:

7
33
0 # 這個(gè)結(jié)果并不是想要的,利用$才能解決

示例4:{m}

需求:匹配出罪帖,8到20位的密碼炸客,可以是大小寫英文字母抖所、數(shù)字蟆炊、下劃線

#coding=utf-8
import re

ret = re.match("[a-zA-Z0-9_]{6}","12a3g45678")
print(ret.group())

ret = re.match("[a-zA-Z0-9_]{8,20}","1ad12f23s34455ff66")
print(ret.group())

運(yùn)行結(jié)果:

12a3g4
1ad12f23s34455ff66

匹配開頭結(jié)尾
字符 功能
^ 匹配字符串開頭
匹配字符串結(jié)尾 示例1:

需求:匹配163.com的郵箱地址

#coding=utf-8

import re

email_list = ["xiaoWang@163.com", "xiaoWang@163.comheihei", ".com.xiaowang@qq.com"]

for email in email_list:
ret = re.match("[\w]{4,20}@163.com", email)
if ret:
print("%s 是符合規(guī)定的郵件地址,匹配后的結(jié)果是:%s" % (email, ret.group()))
else:
print("%s 不符合要求" % email)

運(yùn)行結(jié)果:

xiaoWang@163.com 是符合規(guī)定的郵件地址,匹配后的結(jié)果是:xiaoWang@163.com
xiaoWang@163.comheihei 是符合規(guī)定的郵件地址,匹配后的結(jié)果是:xiaoWang@163.com
.com.xiaowang@qq.com 不符合要求

完善后

email_list = ["xiaoWang@163.com", "xiaoWang@163.comheihei", ".com.xiaowang@qq.com"]

for email in email_list:
ret = re.match("[\w]{4,20}@163.com$", email)
if ret:
print("%s 是符合規(guī)定的郵件地址,匹配后的結(jié)果是:%s" % (email, ret.group()))
else:
print("%s 不符合要求" % email)

運(yùn)行結(jié)果:

xiaoWang@163.com 是符合規(guī)定的郵件地址,匹配后的結(jié)果是:xiaoWang@163.com
xiaoWang@163.comheihei 不符合要求
.com.xiaowang@qq.com 不符合要求

匹配分組

字符 功能
匹配左右任意一個(gè)表達(dá)式
(ab) 將括號中字符作為一個(gè)分組
\num 引用分組num匹配到的字符串
(?P<name>) 分組起別名
(?P=name) 引用別名為name分組匹配到的字符串

示例1:|

需求:匹配出0-100之間的數(shù)字

\#coding=utf-8

import re

ret = re.match("[1-9]?\d","8")
print(ret.group())  # 8

ret = re.match("[1-9]?\d","78")
print(ret.group())  # 78

# 不正確的情況
ret = re.match("[1-9]?\d","08")
print(ret.group())  # 0

# 修正之后的
ret = re.match("[1-9]?\d$","08")
if ret:
    print(ret.group())
else:
    print("不在0-100之間")

# 添加|
ret = re.match("[1-9]?\d$|100","8")
print(ret.group())  # 8

ret = re.match("[1-9]?\d$|100","78")
print(ret.group())  # 78

ret = re.match("[1-9]?\d$|100","08")
# print(ret.group())  # 不是0-100之間

ret = re.match("[1-9]?\d$|100","100")
print(ret.group())  # 100

示例2:( )

需求:匹配出163稽莉、126、qq郵箱

#coding=utf-8

import re

ret = re.match("\w{4,20}@163\.com", "test@163.com")
print(ret.group())  # test@163.com

ret = re.match("\w{4,20}@(163|126|qq)\.com", "test@126.com")
print(ret.group())  # test@126.com

ret = re.match("\w{4,20}@(163|126|qq)\.com", "test@qq.com")
print(ret.group())  # test@qq.com

ret = re.match("\w{4,20}@(163|126|qq)\.com", "test@gmail.com")
if ret:
    print(ret.group())
else:
    print("不是163涩搓、126污秆、qq郵箱")  # 不是163、126昧甘、qq郵箱

不是以4良拼、7結(jié)尾的手機(jī)號碼(11位)

import re

tels = ["13100001234", "18912344321", "10086", "18800007777"]

for tel in tels:
    ret = re.match("1\d{9}[0-35-68-9]", tel)
    if ret:
        print(ret.group())
    else:
        print("%s 不是想要的手機(jī)號" % tel)

提取區(qū)號和電話號碼

>>> ret = re.match("([^-]*)-(\d+)","010-12345678")
>>> ret.group()
'010-12345678'
>>> ret.group(1)
'010'
>>> ret.group(2)
'12345678'

示例3:\

需求:匹配出<html>hh</html>

#coding=utf-8

import re

# 能夠完成對正確的字符串的匹配
ret = re.match("<[a-zA-Z]*>\w*</[a-zA-Z]*>", "<html>hh</html>")
print(ret.group())

# 如果遇到非正常的html格式字符串,匹配出錯(cuò)
ret = re.match("<[a-zA-Z]*>\w*</[a-zA-Z]*>", "<html>hh</htmlbalabala>")
print(ret.group())

# 正確的理解思路:如果在第一對<>中是什么充边,按理說在后面的那對<>中就應(yīng)該是什么

# 通過引用分組中匹配到的數(shù)據(jù)即可庸推,但是要注意是元字符串,即類似 r""這種格式
ret = re.match(r"<([a-zA-Z]*)>\w*</\1>", "<html>hh</html>")
print(ret.group())

# 因?yàn)?對<>中的數(shù)據(jù)不一致浇冰,所以沒有匹配出來
test_label = "<html>hh</htmlbalabala>"
ret = re.match(r"<([a-zA-Z]*)>\w*</\1>", test_label)
if ret:
    print(ret.group())
else:
    print("%s 這是一對不正確的標(biāo)簽" % test_label)

運(yùn)行結(jié)果:

<html>hh</html>
<html>hh</htmlbalabala>
<html>hh</html>
<html>hh</htmlbalabala> 這是一對不正確的標(biāo)簽

示例4:\number

需求:匹配出<html><h1>www.itcast.cn</h1></html>

#coding=utf-8

import re

labels = ["<html><h1>www.itcast.cn</h1></html>", "<html><h1>www.itcast.cn</h2></html>"]

for label in labels:
    ret = re.match(r"<(\w*)><(\w*)>.*</\2></\1>", label)
    if ret:
        print("%s 是符合要求的標(biāo)簽" % ret.group())
    else:
        print("%s 不符合要求" % label)

運(yùn)行結(jié)果:

<html><h1>www.itcast.cn</h1></html> 是符合要求的標(biāo)簽
<html><h1>www.itcast.cn</h2></html> 不符合要求

示例5:(?P<name>) (?P=name)

需求:匹配出<html><h1>www.itcast.cn</h1></html>

#coding=utf-8

import re

ret = re.match(r"<(?P<name1>\w*)><(?P<name2>\w*)>.*</(?P=name2)></(?P=name1)>", "<html><h1>www.itcast.cn</h1></html>")
ret.group()

ret = re.match(r"<(?P<name1>\w*)><(?P<name2>\w*)>.*</(?P=name2)></(?P=name1)>", "<html><h1>www.itcast.cn</h2></html>")
ret.group()

注意:(?P<name>)(?P=name)中的字母p大寫

運(yùn)行結(jié)果:

image.png

re模塊的高級用法

search

需求:匹配出文章閱讀的次數(shù)

#coding=utf-8
import re

ret = re.search(r"\d+", "閱讀次數(shù)為 9999")
ret.group()

運(yùn)行結(jié)果:

'9999'

findall

需求:統(tǒng)計(jì)出python贬媒、c、c++相應(yīng)文章閱讀的次數(shù)

#coding=utf-8
import re

ret = re.findall(r"\d+", "python = 9999, c = 7890, c++ = 12345")
print(ret)

運(yùn)行結(jié)果:

['9999', '7890', '12345']

sub 將匹配到的數(shù)據(jù)進(jìn)行替換

需求:將匹配到的閱讀次數(shù)加1

方法1:

#coding=utf-8
import re

ret = re.sub(r"\d+", '998', "python = 997")
print(ret)

運(yùn)行結(jié)果:

python = 998

方法2:

#coding=utf-8
import re

def add(temp):
    strNum = temp.group()
    num = int(strNum) + 1
    return str(num)

ret = re.sub(r"\d+", add, "python = 997")
print(ret)

ret = re.sub(r"\d+", add, "python = 99")
print(ret)

運(yùn)行結(jié)果:

python = 998
python = 100

練習(xí)

image.png

從下面的字符串中取出文本

<div>
        <p>崗位職責(zé):</p>
<p>完成推薦算法肘习、數(shù)據(jù)統(tǒng)計(jì)际乘、接口、后臺等服務(wù)器端相關(guān)工作</p>
<p><br></p>
<p>必備要求:</p>
<p>良好的自我驅(qū)動(dòng)力和職業(yè)素養(yǎng)井厌,工作積極主動(dòng)蚓庭、結(jié)果導(dǎo)向</p>
<p>&nbsp;<br></p>
<p>技術(shù)要求:</p>
<p>1、一年以上 Python 開發(fā)經(jīng)驗(yàn)仅仆,掌握面向?qū)ο蠓治龊驮O(shè)計(jì)器赞,了解設(shè)計(jì)模式</p>
<p>2、掌握HTTP協(xié)議墓拜,熟悉MVC港柜、MVVM等概念以及相關(guān)WEB開發(fā)框架</p>
<p>3、掌握關(guān)系數(shù)據(jù)庫開發(fā)設(shè)計(jì),掌握 SQL夏醉,熟練使用 MySQL/PostgreSQL 中的一種<br></p>
<p>4爽锥、掌握NoSQL、MQ畔柔,熟練使用對應(yīng)技術(shù)解決方案</p>
<p>5氯夷、熟悉 Javascript/CSS/HTML5,JQuery靶擦、React腮考、Vue.js</p>
<p>&nbsp;<br></p>
<p>加分項(xiàng):</p>
<p>大數(shù)據(jù),數(shù)理統(tǒng)計(jì)玄捕,機(jī)器學(xué)習(xí)踩蔚,sklearn,高性能枚粘,大并發(fā)馅闽。</p>

        </div>

參考答案:

re.sub(r"<[^>]*>|&nbsp;|\n", "", test_str)

split 根據(jù)匹配進(jìn)行切割字符串,并返回一個(gè)列表

需求:切割字符串“info:xiaoZhang 33 shandong”

#coding=utf-8
import re

ret = re.split(r":| ","info:xiaoZhang 33 shandong")
print(ret)

運(yùn)行結(jié)果:

['info', 'xiaoZhang', '33', 'shandong']

python貪婪和非貪婪

Python里數(shù)量詞默認(rèn)是貪婪的(在少數(shù)語言里也可能是默認(rèn)非貪婪)馍迄,總是嘗試匹配盡可能多的字符福也;

非貪婪則相反,總是嘗試匹配盡可能少的字符柬姚。

在"*","?","+","{m,n}"后面加上拟杉?,使貪婪變成非貪婪量承。

>>> s="This is a number 234-235-22-423"
>>> r=re.match(".+(\d+-\d+-\d+-\d+)",s)
>>> r.group(1)
'4-235-22-423'
>>> r=re.match(".+?(\d+-\d+-\d+-\d+)",s)
>>> r.group(1)
'234-235-22-423'
>>>

正則表達(dá)式模式中使用到通配字搬设,那它在從左到右的順序求值時(shí),會盡量“抓取”滿足匹配最長字符串撕捍,在我們上面的例子里面拿穴,“.+”會從字符串的啟始處抓取滿足模式的最長字符,其中包括我們想得到的第一個(gè)整型字段的中的大部分忧风,“\d+”只需一位字符就可以匹配默色,所以它匹配了數(shù)字“4”,而“.+”則匹配了從字符串起始到這個(gè)第一位數(shù)字4之前的所有字符狮腿。

解決方式:非貪婪操作符“腿宰?”,這個(gè)操作符可以用在"*","+","?"的后面缘厢,要求正則匹配的越少越好吃度。

>>> re.match(r"aa(\d+)","aa2343ddd").group(1)
'2343'
>>> re.match(r"aa(\d+?)","aa2343ddd").group(1)
'2'
>>> re.match(r"aa(\d+)ddd","aa2343ddd").group(1) 
'2343'
>>> re.match(r"aa(\d+?)ddd","aa2343ddd").group(1)
'2343'
>>>

練一練

[圖片上傳失敗...(image-53eef0-1600844319562)]

字符串為:

<img data-original="https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg" src="https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg" style="display: inline;">

請?zhí)崛rl地址

參考答案

re.search(r"https://.*?\.jpg", test_str)

r的作用

mm = "c:\a\b\c"
mm
'c:\a\b\c'
print(mm)
c:\a\b\c
re.match("c:\\",mm).group()
'c:\'
ret = re.match("c:\\",mm).group()
print(ret)
c:
ret = re.match("c:\\a",mm).group()
print(ret)
c:\a
ret = re.match(r"c:\a",mm).group()
print(ret)
c:\a
ret = re.match(r"c:\a",mm).group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'

說明

Python中字符串前面加上 r 表示原生字符串,

與大多數(shù)編程語言相同贴硫,正則表達(dá)式里使用""作為轉(zhuǎn)義字符椿每,這就可能造成反斜杠困擾伊者。假如你需要匹配文本中的字符"",那么使用編程語言表示的正則表達(dá)式里將需要4個(gè)反斜杠"\":前兩個(gè)和后兩個(gè)分別用于在編程語言里轉(zhuǎn)義成反斜杠间护,轉(zhuǎn)換成兩個(gè)反斜杠后再在正則表達(dá)式里轉(zhuǎn)義成一個(gè)反斜杠亦渗。

Python里的原生字符串很好地解決了這個(gè)問題,有了原生字符串汁尺,你再也不用擔(dān)心是不是漏寫了反斜杠法精,寫出來的表達(dá)式也更直觀。

ret = re.match(r"c:\a",mm).group()
print(ret)
c:\a

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末均函,一起剝皮案震驚了整個(gè)濱河市亿虽,隨后出現(xiàn)的幾起案子菱涤,更是在濱河造成了極大的恐慌苞也,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件粘秆,死亡現(xiàn)場離奇詭異如迟,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)攻走,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門殷勘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人昔搂,你說我怎么就攤上這事玲销。” “怎么了摘符?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵贤斜,是天一觀的道長。 經(jīng)常有香客問我逛裤,道長瘩绒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任带族,我火速辦了婚禮锁荔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蝙砌。我一直安慰自己阳堕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布择克。 她就那樣靜靜地躺著恬总,像睡著了一般。 火紅的嫁衣襯著肌膚如雪祠饺。 梳的紋絲不亂的頭發(fā)上越驻,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼缀旁。 笑死记劈,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的并巍。 我是一名探鬼主播目木,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼懊渡!你這毒婦竟也來了刽射?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤剃执,失蹤者是張志新(化名)和其女友劉穎誓禁,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肾档,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡摹恰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了怒见。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片俗慈。...
    茶點(diǎn)故事閱讀 40,503評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖遣耍,靈堂內(nèi)的尸體忽然破棺而出闺阱,到底是詐尸還是另有隱情,我是刑警寧澤舵变,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布酣溃,位于F島的核電站,受9級特大地震影響棋傍,放射性物質(zhì)發(fā)生泄漏救拉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一瘫拣、第九天 我趴在偏房一處隱蔽的房頂上張望亿絮。 院中可真熱鬧,春花似錦麸拄、人聲如沸派昧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蒂萎。三九已至,卻和暖如春淮椰,著一層夾襖步出監(jiān)牢的瞬間五慈,已是汗流浹背纳寂。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留泻拦,地道東北人毙芜。 一個(gè)月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像争拐,于是被迫代替她去往敵國和親腋粥。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評論 2 359