網羅天下之~正則表達
微信閱讀:OTA3NzUwMQ==&mid=2649748015&idx=1&sn=190773a6d7c93e8b079d1aa620cc1b71&chksm=f0536abdc724e3abcb16da8b947c84be4d7ef1e6bba2f7859c10f888021806f632c1e264bb0e&token=90978429&lang=zh_CN#rd" target="_blank" rel="nofollow,noindex">網羅天下之~正則表達
字元 | 含義 |
---|---|
.
|
匹配任意1個字元(除了\n
) |
[]
|
匹配[ ]
中列舉的1個字元(^
可以取反) |
\d
|
匹配數字(0~9
) |
\D
|
匹配非數字(非數字
) |
\s
|
匹配空白(空格、Tab鍵、回車
) |
\S
|
匹配非空白 |
\w
|
匹配單詞字元,即a-z、A-Z、0-9、_
(包括單箇中文字元) |
\W
|
匹配非單詞字元 |
注意:
-
\s
並不匹配""
-
<re.Match object; span=(0, 1), match='\t'>
-
PS:
match=xxx
,就是我們ret.group()
的結果
-
PS:
In [1]:
# 定義一個通用測試方法 import re def my_match(re_str, input_str): ret = re.match(re_str, input_str) if ret: print(f"[匹配結果:{ret.group()}]") else: print(f"[{input_str}不匹配]") return ret # Python中字串前面加上 r 表示原生字串(不轉義)
In [2]:
# \s 驗證 # 空格匹配驗證 my_match("\s"," ") # Tab鍵匹配驗證 my_match("\s","\t") # 回車匹配驗證 my_match("\s","\n") # 不匹配驗證:(空字串) my_match("\s","")
[匹配結果: ] [匹配結果:] [匹配結果: ] [不匹配]
In [3]:
# \d 驗證 # 匹配單個數字 my_match("\d","1") # 一點要變成字串 # 多個數字則只能匹配一個字元 my_match("\d","11") # 注意 # 解決:以^開頭,以$結尾 my_match("^\d$","11")
[匹配結果:1] [匹配結果:1] [11不匹配]
In [4]:
# [] 驗證 # 不是1、2、3則不匹配 my_match("[1-3]","4") # 匹配1~3,6~9 my_match("[1-36-9]","7") # 不匹配驗證 my_match("[1-36-9]","5") # 只匹配數字和字母(大小寫) my_match("[\da-zA-Z]","7") my_match("[\da-zA-Z]","b") my_match("[\da-zA-Z]","B") # 不匹配驗證 my_match("[\da-zA-Z]","_")
[4不匹配] [匹配結果:7] [5不匹配] [匹配結果:7] [匹配結果:b] [匹配結果:B] [_不匹配]
In [5]:
# [] 取反擴充套件 # \d ==> [0-9] # \D ==> [^0-9] # 非2、4、6 my_match("[^246]","3") my_match("[^246]","@") # 錯誤驗證 my_match("[^246]","4") # 非 1~6 my_match("[^1-6]","7") my_match("[^1-6]","#") # 錯誤驗證 my_match("[^1-6]","5")
[匹配結果:3] [匹配結果:@] [4不匹配] [匹配結果:7] [匹配結果:#] [5不匹配]
In [6]:
# \w在UTF8下會匹配中文的驗證: my_match("\w","滾") # .匹配任意字元,不包括\n的驗證: my_match(".","\n") # 除了\n,可以匹配任意一個字元 my_match(".","\t")
[匹配結果:滾] [ 不匹配] [匹配結果:]
Out[6]:
<re.Match object; span=(0, 1), match='\t'>
In [7]:
# 擴充套件 # 如果想讓.支援\n,再多傳個flag:re.S re.match(".","\n",re.S)
Out[7]:
<re.Match object; span=(0, 1), match='\n'>
字元 | 含義 |
---|---|
*
|
1個字元出現次數:>=0
|
+
|
1個字元出現次數:>=1
|
?
|
1個字元出現次數:1 or 0
|
{m}
|
1個字元出現m
次 |
{m,n}
|
1個字元出現從[m,n]
次 |
\
|
轉義特殊字元 |
^
|
匹配字串開頭 |
$
|
匹配字串結尾 |
多個字元,一般都是以^
開頭,以$
結尾,不然容易出Bug(re.match
方法預設以^
開頭)
PS:vi
命令模式下,輸入^
和$
,游標會跳轉到頭和尾
Python中r""代表不轉義字串:
# r"",如果包含轉義字元\就容易出錯了,這時候r""就上場了 re.match("\\mmd","\mmd") # 原因分析 # \是有特殊含義的,想要沒有特殊含義就再加個\, # 那加上的這個\又有特殊含義,所以就蛋疼了,r""這時候就上場了 # 解決方法 re.match(r"\\mmd","\\mmd") # 下面有案例
In [8]:
# * 、 + 、? # *:0個或者多個 my_match(r"\d*","") my_match(r"\d*","11") # +:1個或者多個 # 不匹配驗證: my_match(r"\d+","") # 匹配驗證: my_match(r"\d+","1") my_match(r"\d+","11") # ?:0個或者1次 # 不匹配驗證: my_match(r"^\d?$","11") # 匹配驗證 my_match(r"^\d?$","") my_match(r"^\d?$","1")
[匹配結果:] [匹配結果:11] [不匹配] [匹配結果:1] [匹配結果:11] [11不匹配] [匹配結果:] [匹配結果:1]
Out[8]:
<re.Match object; span=(0, 1), match='1'>
In [9]:
# 為什麼用^和$包裹,看下面兩個奇葩案例就知道了 my_match("\d","123333") my_match("\d*","a") # ==> "a" ==> """a"
[匹配結果:1] [匹配結果:]
Out[9]:
<re.Match object; span=(0, 0), match=''>
In [10]:
# {}指定位數驗證 # ? ==> {0,1} # 1位數字或者2位數字 my_match(r"^\d{1,2}$","7") # 1位數字或者2位數字 my_match(r"^\d{1,2}$","17") # 錯誤驗證 my_match(r"^\d{1,2}$","777") # 指定位數 eg:10位數字 my_match(r"^\d{10}$","1234567890") # 錯誤驗證 ~ 9位 my_match(r"^\d{10}$","123456789") # 錯誤驗證 ~ 非整數 my_match(r"^\d{10}$","A123456789")
[匹配結果:7] [匹配結果:17] [777不匹配] [匹配結果:1234567890] [123456789不匹配] [A123456789不匹配]
In [11]:
# {} 擴充套件 # * ==> {0,} # + ==> {1,} # \d 至少3個 my_match(r"\d{3,}","123") my_match(r"\d{3,}","1234") # 錯誤驗證 my_match(r"\d{3,}","12")
[匹配結果:123] [匹配結果:1234] [12不匹配]
In [12]:
# ^ $ 案例 # 驗證變數命名 my_match(r"^[a-zA-z_]\w*$","a_bbp") my_match(r"^[a-zA-z_]\w*$","_")
[匹配結果:a_bbp] [匹配結果:_]
Out[12]:
<re.Match object; span=(0, 1), match='_'>
In [13]:
# 測試一個就知道為什麼用\w了 def test蛋(): print("mmd") test蛋() # Python Code
mmd
In [14]:
# 如果沒有加開頭和結尾的Bug測試 # 沒有判斷結尾的Bug案例 my_match(r"[a-zA-z_]\w*","a_b#w") # 測試Bug,這個也匹配了 my_match(r"[a-zA-z_][email protected]","[email protected]") # 改進 ~ 現在不匹配了 my_match(r"^[a-zA-z_]\w*$","a_b#w")
[匹配結果:a_b] [匹配結果:[email protected]] [a_b#w不匹配]
In [15]:
# 轉義字元 \ 引入案例 # 測試Bug,這個也匹配了 my_match(r"[a-zA-z_][email protected]","mmd@qq#comcom") # 改進 ~ 現在不匹配了 (開頭結尾+\轉義) my_match(r"^[a-zA-z_]+@qq\.com$","mmd@qq#comcom")
[匹配結果:mmd@qq#com] [mmd@qq#comcom不匹配]
In [16]:
# r"",如果包含轉義字元\就容易出錯了,這時候r""就上場了 try: my_match("\\mmd","\mmd") except Exception as ex: print(ex) # 原因分析 # \是有特殊含義的,想要沒有特殊含義就再加個\, # 那加上的這個\又有特殊含義,所以就蛋疼了,r""這時候就上場了 # 解決方法 my_match(r"\\mmd", "\\mmd")
bad escape \m at position 0 [匹配結果:\mmd]
Out[16]:
<re.Match object; span=(0, 4), match='\\mmd'>
字元 | 含義 | |
---|---|---|
\ | 匹配左右任意一個表示式 | |
\b
|
匹配一個單詞的邊界(字母與空格間的位置) | |
\B
|
匹配非單詞的邊界 | |
( )
|
將括號中字元作為一個分組 | |
\num
|
引用分組num匹配到的字串 | |
(?P<name>)
|
分組起別名 | |
(?P=name)
|
引用別名為name分組匹配到的字串 |
In [17]:
# 匹配邊界 # \b 匹配以net結尾的單詞 my_match(r"\w+net\b","dotnet") my_match(r"\w+net\b","dotnet crazy") # 不匹配驗證 my_match(r"\w+net\b","dotnetcrazy") # 後面會講 re.findall(r"\w+net\b","dotnet crazy aspnet")
[匹配結果:dotnet] [匹配結果:dotnet] [dotnetcrazy不匹配]
Out[17]:
['dotnet', 'aspnet']
In [18]:
# 不匹配驗證:\b、\B、^、$只是代表邊界,並不表示空格 my_match(r"\w+\bnet\b","dot net crazy") # 正確修改 my_match(r"\w+\s\bnet\b","dot net crazy") # 把上面換成\B,則代表單詞間必須是 非空格的字元 my_match(r"\w+\Bnet\B","dotnetcrazy") my_match(r"\w+\Bnet\B","dotnetAcrazy") my_match(r"\w+\Bnet\B","dotnet1crazy") # 不匹配驗證 my_match(r"\w+\Bnet\B","dotnet#crazy")
[dot net crazy不匹配] [匹配結果:dot net] [匹配結果:dotnet] [匹配結果:dotnet] [匹配結果:dotnet] [dotnet#crazy不匹配]
In [19]:
# | 匹配左右任意一個表示式 # 匹配小明或者小張 my_match(r"^小明|小張$","小明") my_match(r"^小明|小張$","小張") # 不匹配驗證 my_match(r"^小明|小張$","小潘")
[匹配結果:小明] [匹配結果:小張] [小潘不匹配]
In [20]:
# () 將括號中字元作為一個分組 # group(1) 返回第1個括號匹配內容 my_match(r"^[a-zA-Z0-9_]+@(qq|163)\.com$","[email protected]").group(1) # HTML的標籤匹配匹配檢查 my_match(r"^<([a-zA-Z1-9]+)>.*</\1>$","<h1>萌萌噠</h1>").group(1)
[匹配結果:[email protected]] [匹配結果:<h1>萌萌噠</h1>]
Out[20]:
'h1'
In [21]:
# groups返回所有的匹配結果 my_match(r"^<([a-zA-Z1-9]+)><([a-zA-Z1-9]+)>(.*)</\2></\1>$","<p><font>我去</font></p>").groups()
[匹配結果:<p><font>我去</font></p>]
Out[21]:
('p', 'font', '我去')
In [22]:
# 匹配 qq.com 和 163.com (別忘記轉義.) ret = my_match(r"(^[a-zA-Z0-9_]+)@(qq|163)\.com$","[email protected]") print(ret.groups()) ret = my_match(r"(^[a-zA-Z0-9_]+)@(qq|163)\.com$","[email protected]") print(ret.groups()) # 不匹配驗證 my_match(r"^(^[a-zA-Z0-9_]+)@(qq|163)\.com$","@163.com") my_match(r"^(^[a-zA-Z0-9_]+)@(qq|163)\.com$","[email protected]")
[匹配結果:[email protected]] ('mmd', 'qq') [匹配結果:[email protected]] ('mmd', '163') [@163.com不匹配] [[email protected]不匹配]
In [23]:
# 別名案例(不常用) my_match(r"<(?P<mmd>\w*)><(?P<dnt>.*)>.*</(?P=dnt)></(?P=mmd)>","<html><h1>萌萌噠</h1></html>").group(2) # 不匹配驗證 my_match(r"<(?P<mmd>\w*)><(?P<dnt>.*)>.*</(?P=dnt)></(?P=mmd)>","<html><h1>萌萌噠</h2></html>")
[匹配結果:<html><h1>萌萌噠</h1></html>] [<html><h1>萌萌噠</h2></html>不匹配]
In [24]:
# 練練手
In [25]:
# 1~100之間的數字:(1,100) my_match(r"^[1-9]\d?$","0") my_match(r"^[1-9]\d?$","7") # 十位只能是1~9 my_match(r"^[1-9]\d?$","77") # 不匹配驗證 my_match(r"^[1-9]\d?$","07") my_match(r"^[1-9]\d?$","777") # 0~100的數字:[0,100] re_str=r"^([1-9]?\d?|100)$" # ^([1-9]\d?|100|0)$ my_match(re_str,"0") my_match(re_str,"1") my_match(re_str,"70") my_match(re_str,"100") # 不匹配驗證 my_match(re_str,"07") my_match(re_str,"170") my_match(re_str,"700")
[0不匹配] [匹配結果:7] [匹配結果:77] [07不匹配] [777不匹配] [匹配結果:0] [匹配結果:1] [匹配結果:70] [匹配結果:100] [07不匹配] [170不匹配] [700不匹配]
上面的都是通用系列,下面的才能體現為啥爬蟲是Python的優勢:
-
re.match
:和其他語言用法一致(預設從頭開始匹配) -
re.search
:匹配第一個並返回(如果加了^
和$
就和match一樣了) -
re.findall
:返回所有匹配的列表 -
re.sub
:將匹配到的資料進行替換,再返回新的字串- 匹配之後替換成預設值
- 匹配之後進行函式處理
-
re.split
:正則切割函式(類似於字串的split) -
re.compile
:正則字串編譯成正則表示式物件
In [26]:
# 匹配第一個就結束了 ret = re.search(r"\d","我的名字叫小明,今年23,88") print(ret.group()) # 如果加了開頭結尾就和match一樣了 print(re.search(r"^\d$","我的名字叫小明,今年23,88"))
2 None
In [27]:
# 返回所有匹配的列表 re.findall(r"\d","我的名字叫小明,今年23,88")
Out[27]:
['2', '3', '8', '8']
In [28]:
re.split(r",|。","我的名字叫小明,今年23。88")
Out[28]:
['我的名字叫小明', '今年23', '88']
In [29]:
# sub案例:批量替換1 re.sub(r"\d+","***","我上次買的時候98.5塊,現在30就拿到了,差評!")
Out[29]:
'我上次買的時候***.***塊,現在***就拿到了,差評!'
In [30]:
# sub案例:批量替換2 ~ 拿到分組內容並進行處理 re.sub(r"(\d+)",r"400\1","我是小明,客服電話是:6789688")
Out[30]:
'我是小明,客服電話是:4006789688'
In [31]:
# sub案例:函式處理 def shit_test(result): # 返回型別必須是str return str(float(result.group())*2) re.sub(r"\d+",shit_test,"我上次買的時候98.5塊,現在30就拿到了,差評!")
Out[31]:
'我上次買的時候196.0.10.0塊,現在60.0就拿到了,差評!'
In [32]:
# 擴充套件內容 pattern = re.compile(r"A.*Z",re.S) # 表示式複用 print(re.match(pattern,"ABZ").group()) print(re.match(pattern,"ACZ").group())
ABZ ACZ
In [33]:
# 練手小案例
In [34]:
# 提取單詞 input_str = "Python Golang NetCore JavaScript" print(re.split(" ",input_str)) re.findall("[a-zA-Z]+",input_str)
['Python', 'Golang', 'NetCore', 'JavaScript']
Out[34]:
['Python', 'Golang', 'NetCore', 'JavaScript']
In [35]:
# 提取文字 """ 保留字串原始格式 html_str = """ <div> <h3>職位描述</h3> <div> 崗位職責: <br>1. 負責公司資料管理制度、規範、流程的設計,參與資料開發平臺的建設和管理<br>2. 規劃資料倉庫工作方向,持續提升團隊工作目標和工作效率<br>3. 負責全面瞭解公司業務,進行深層次的資料分析,為資料開發專案提供指導性的意見,從資料角度為公司產品開發、業務運營提供決策支援建議<br>4. 掌握業界技術動向,組織研究大資料相關前沿技術,用於指導實際的資料支援專案<br>任職要求:<br>1. 精通資料倉庫實施理論,生命週期管理,具備大型網際網路資料倉庫架構設計、模型設計、ETL設計經驗,以及海量資料處理和優化經驗<br>2. 深入理解Hadoop/Hive/Spark/Storm/Kylin等大資料相關技術和原理<br>3. 有實際使用Hive/MR/Spark等大資料處理技術解決大資料相關問題的專案經驗,具備豐富的效能調優經驗<br>4 熟悉OLAP工具和資料分析技能,對資料敏感,能夠進行資料分析,挖掘資料價值<br>5. 邏輯思維能力強,有較強的學習能力和創新思維,能夠解決複雜的商業問題<br>6. 優秀的溝通能力和文字表達能力,有較強的團隊管理能力 </div> </div> """ # 清除HTML標籤(`/?`:`/`出現0次或者1次) re.sub(r"</?\w+>|\n| ","",html_str).strip()
Out[35]:
'職位描述崗位職責:1.負責公司資料管理制度、規範、流程的設計,參與資料開發平臺的建設和管理2.規劃資料倉庫工作方向,持續提升團隊工作目標和工作效率3.負責全面瞭解公司業務,進行深層次的資料分析,為資料開發專案提供指導性的意見,從資料角度為公司產品開發、業務運營提供決策支援建議4.掌握業界技術動向,組織研究大資料相關前沿技術,用於指導實際的資料支援專案任職要求:1.精通資料倉庫實施理論,生命週期管理,具備大型網際網路資料倉庫架構設計、模型設計、ETL設計經驗,以及海量資料處理和優化經驗2.深入理解Hadoop/Hive/Spark/Storm/Kylin等大資料相關技術和原理3.有實際使用Hive/MR/Spark等大資料處理技術解決大資料相關問題的專案經驗,具備豐富的效能調優經驗4熟悉OLAP工具和資料分析技能,對資料敏感,能夠進行資料分析,挖掘資料價值5.邏輯思維能力強,有較強的學習能力和創新思維,能夠解決複雜的商業問題6.優秀的溝通能力和文字表達能力,有較強的團隊管理能力'
正則表示式預設就是貪婪模式,只要符合表示式就儘可能去匹配(eg:.+
、.*
)
解決方法:後面加個?
(eg:.+?
、.*?
)
In [36]:
# 貪婪演示 # 貪婪模式下會盡可能匹配: input_str = "我叫小明,歡迎撥打客服:4006789678" ret = re.match(r"(.+)(\d+)", input_str) print("[提取的號碼為:]",ret.group(2)) print("[貪婪的字串:]",ret.group(1)) # 解決方法 .+? or .*? ret = re.match(r"(.+?)(\d+)", input_str) print("[提取的號碼為:]",ret.group(2)) print("[貪婪的字串:]",ret.group(1))
[提取的號碼為:] 8 [貪婪的字串:] 我叫小明,歡迎撥打客服:400678967 [提取的號碼為:] 4006789678 [貪婪的字串:] 我叫小明,歡迎撥打客服:
In [37]:
# 練手小案例
In [38]:
# 加強版提取案例 ~ BOSS html_str = """ <div class="detail-content"> <div class="job-sec"> <h3>職位描述</h3> <div class="text"> 崗位職責: <br>1. 負責公司資料管理制度、規範、流程的設計,參與資料開發平臺的建設和管理<br>2. 規劃資料倉庫工作方向,持續提升團隊工作目標和工作效率<br>3. 負責全面瞭解公司業務,進行深層次的資料分析,為資料開發專案提供指導性的意見,從資料角度為公司產品開發、業務運營提供決策支援建議<br>4. 掌握業界技術動向,組織研究大資料相關前沿技術,用於指導實際的資料支援專案<br>任職要求:<br>1. 精通資料倉庫實施理論,生命週期管理,具備大型網際網路資料倉庫架構設計、模型設計、ETL設計經驗,以及海量資料處理和優化經驗<br>2. 深入理解Hadoop/Hive/Spark/Storm/Kylin等大資料相關技術和原理<br>3. 有實際使用Hive/MR/Spark等大資料處理技術解決大資料相關問題的專案經驗,具備豐富的效能調優經驗<br>4 熟悉OLAP工具和資料分析技能,對資料敏感,能夠進行資料分析,挖掘資料價值<br>5. 邏輯思維能力強,有較強的學習能力和創新思維,能夠解決複雜的商業問題<br>6. 優秀的溝通能力和文字表達能力,有較強的團隊管理能力 </div> </div> <div class="job-sec">pass</div> <div class="job-sec">xx</div> <div class="job-sec company-info"pass</div> <div class="job-sec">pass</div> </div> """ # 先找到第一個job-sec(正則思路:直接定位匹配,寫幾個關鍵詞,其他都是偷懶寫法.*?) ret = re.search(r'<div.*?job-sec">.*?text">(.*?)</div>', html_str, re.S) new_str = ret.group(1) print(new_str) # 再處理下多餘的HTML標籤 re.sub(r"<br>|\s","",new_str)
崗位職責: <br>1. 負責公司資料管理制度、規範、流程的設計,參與資料開發平臺的建設和管理<br>2. 規劃資料倉庫工作方向,持續提升團隊工作目標和工作效率<br>3. 負責全面瞭解公司業務,進行深層次的資料分析,為資料開發專案提供指導性的意見,從資料角度為公司產品開發、業務運營提供決策支援建議<br>4. 掌握業界技術動向,組織研究大資料相關前沿技術,用於指導實際的資料支援專案<br>任職要求:<br>1. 精通資料倉庫實施理論,生命週期管理,具備大型網際網路資料倉庫架構設計、模型設計、ETL設計經驗,以及海量資料處理和優化經驗<br>2. 深入理解Hadoop/Hive/Spark/Storm/Kylin等大資料相關技術和原理<br>3. 有實際使用Hive/MR/Spark等大資料處理技術解決大資料相關問題的專案經驗,具備豐富的效能調優經驗<br>4 熟悉OLAP工具和資料分析技能,對資料敏感,能夠進行資料分析,挖掘資料價值<br>5. 邏輯思維能力強,有較強的學習能力和創新思維,能夠解決複雜的商業問題<br>6. 優秀的溝通能力和文字表達能力,有較強的團隊管理能力
Out[38]:
'崗位職責:1.負責公司資料管理制度、規範、流程的設計,參與資料開發平臺的建設和管理2.規劃資料倉庫工作方向,持續提升團隊工作目標和工作效率3.負責全面瞭解公司業務,進行深層次的資料分析,為資料開發專案提供指導性的意見,從資料角度為公司產品開發、業務運營提供決策支援建議4.掌握業界技術動向,組織研究大資料相關前沿技術,用於指導實際的資料支援專案任職要求:1.精通資料倉庫實施理論,生命週期管理,具備大型網際網路資料倉庫架構設計、模型設計、ETL設計經驗,以及海量資料處理和優化經驗2.深入理解Hadoop/Hive/Spark/Storm/Kylin等大資料相關技術和原理3.有實際使用Hive/MR/Spark等大資料處理技術解決大資料相關問題的專案經驗,具備豐富的效能調優經驗4熟悉OLAP工具和資料分析技能,對資料敏感,能夠進行資料分析,挖掘資料價值5.邏輯思維能力強,有較強的學習能力和創新思維,能夠解決複雜的商業問題6.優秀的溝通能力和文字表達能力,有較強的團隊管理能力'
In [39]:
# 再來一例 ~ 拉勾 html_str = """ <dd class="job_bt"> <h3 class="description">職位描述:</h3> <div> <p>崗位職責:<br>1. 為政企客戶和合作夥伴提供騰訊網際網路+整體解決方案技術層面的售前架構諮詢服務; <br>2. 為政府、企業提供騰訊大資料等專案的規劃、諮詢服務,協助合作伙伴及產品部門進行大資料等專案的落地; <br>3. 配合BD等團隊發展生態合作伙伴,將騰訊能力與合作伙伴方案進行方案融合,為合作伙伴提供諮詢、培訓、方案融合服務; <br>4. 針對客戶網際網路+需求,深度定製網際網路+解決方案並制定實施計劃,把握全域性專案進度,協調相關資源、協助實施團隊完成方案Demo系統搭建,PoC測試及專案落地工作; <br>5. 負責網際網路+案例、技術方案的更新維護,以及佈道工作。</p> <p><br>崗位要求:<br>1. 本科以上學歷,5年(碩士3年)以上大資料等售前諮詢相關的工作經驗; <br>2. 熟悉Hadoop、Spark等開源大資料技術體系,熟悉Oracle、PostgreSQL等資料庫。要求至少有3個以上政企大資料專案規劃與落地經驗; <br>3. 具有巨集觀思維,有高層彙報能力。熟悉醫療、公安等行業大資料優先; <br>4. 具備優秀的文件能力,清晰明瞭地表達架構意圖,能夠熟練編寫各類技術文件; <br>5. 良好的溝通、協調及資源整合能力; <br>6. 有針對行業ISV的渠道支援經驗優先。</p> </div> </dd> """ # 匹配需要的內容(正則思路:快速定位,然後.*?偷懶寫法走起) ret = re.search('<h3.*?p>(.*?)</p>.*?p>(.*?)</p>',html_str,re.S) # 再處理下多餘的HTML標籤 for item in (ret.group(1),ret.group(2)): print(re.sub(r"\s| |<br>", "", item))
崗位職責:1.為政企客戶和合作夥伴提供騰訊網際網路+整體解決方案技術層面的售前架構諮詢服務;2.為政府、企業提供騰訊大資料等專案的規劃、諮詢服務,協助合作伙伴及產品部門進行大資料等專案的落地;3.配合BD等團隊發展生態合作伙伴,將騰訊能力與合作伙伴方案進行方案融合,為合作伙伴提供諮詢、培訓、方案融合服務;4.針對客戶網際網路+需求,深度定製網際網路+解決方案並制定實施計劃,把握全域性專案進度,協調相關資源、協助實施團隊完成方案Demo系統搭建,PoC測試及專案落地工作;5.負責網際網路+案例、技術方案的更新維護,以及佈道工作。 崗位要求:1.本科以上學歷,5年(碩士3年)以上大資料等售前諮詢相關的工作經驗;2.熟悉Hadoop、Spark等開源大資料技術體系,熟悉Oracle、PostgreSQL等資料庫。要求至少有3個以上政企大資料專案規劃與落地經驗;3.具有巨集觀思維,有高層彙報能力。熟悉醫療、公安等行業大資料優先;4.具備優秀的文件能力,清晰明瞭地表達架構意圖,能夠熟練編寫各類技術文件;5.良好的溝通、協調及資源整合能力;6.有針對行業ISV的渠道支援經驗優先。
第一階段併發、網路、爬蟲、DB的網撒完了,現在準備慢慢收網
這幾個系列相關性挺強,隨便深入哪一個專題都得扯到其他專題
所以最後網子就有點大了,不過不用慌,慢慢來~