網羅天下之~正則表達

 

正則表達

微信閱讀:網羅天下之~正則表達html

在線預覽:http://github.lesschina.com/python/spider/re/1.網羅天下之-正則表達.htmlpython

1.單個字符

字符 含義
. 匹配任意1個字符(除了\n
[] 匹配[ ]中列舉的1個字符(^能夠取反)
\d 匹配數字(0~9
\D 匹配非數字(非數字
\s 匹配空白(空格、Tab鍵、回車
\S 匹配非空白
\w 匹配單詞字符,即a-z、A-Z、0-九、_(包括單箇中文字符)
\W 匹配非單詞字符

注意:git

  1. \s並不匹配""
  2. <re.Match object; span=(0, 1), match='\t'>
    • PS:match=xxx,就是咱們ret.group()的結果
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]:
# [] 驗證

# 不是一、二、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]

# 非二、四、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'>
 

2.多個字符

字符 含義
* 1個字符出現次數:>=0
+ 1個字符出現次數:>=1
? 1個字符出現次數:1 or 0
{m} 1個字符出現m
{m,n} 1個字符出現從[m,n]
\ 轉義特殊字符
^ 匹配字符串開頭
$ 匹配字符串結尾

多個字符,通常都是以^開頭,以$結尾,否則容易出Bug(re.match方法默認以^開頭)github

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_]+@qq.com","mmd@qq.comcom")

# 改進 ~ 如今不匹配了
my_match(r"^[a-zA-z_]\w*$","a_b#w")
 
[匹配結果:a_b]
[匹配結果:mmd@qq.com]
[a_b#w不匹配]
In [15]:
# 轉義字符 \ 引入案例

# 測試Bug,這個也匹配了
my_match(r"[a-zA-z_]+@qq.com","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'>
 

3.其餘字符

字符 含義
| 匹配左右任意一個表達式
\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$","mmd@163.com").group(1)

# HTML的標籤匹配匹配檢查
my_match(r"^<([a-zA-Z1-9]+)>.*</\1>$","<h1>萌萌噠</h1>").group(1)
 
[匹配結果:mmd@163.com]
[匹配結果:<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$","mmd@qq.com")
print(ret.groups())

ret = my_match(r"(^[a-zA-Z0-9_]+)@(qq|163)\.com$","mmd@163.com")
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$","mmd@123.com")
 
[匹配結果:mmd@qq.com]
('mmd', 'qq')
[匹配結果:mmd@163.com]
('mmd', '163')
[@163.com不匹配]
[mmd@123.com不匹配]
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不匹配]
 

4.Python擴展

上面的都是通用系列,下面的才能體現爲啥爬蟲是Python的優點:編程

  1. re.match:和其餘語言用法一致(默認從頭開始匹配)
  2. re.search:匹配第一個並返回(若是加了^$就和match同樣了)
  3. re.findall:返回全部匹配的列表
  4. re.sub:將匹配到的數據進行替換,再返回新的字符串
    • 匹配以後替換成默認值
    • 匹配以後進行函數處理
  5. re.split:正則切割函數(相似於字符串的split)
  6. 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.優秀的溝通能力和文字表達能力,有較強的團隊管理能力'
 

5.貪婪模式

正則表達式默認就是貪婪模式,只要符合表達式就儘量去匹配(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. 爲政企客戶和合做夥伴提供騰訊互聯網+總體解決方案技術層面的售前架構諮詢服務;&nbsp;<br>2. 爲政府、企業提供騰訊大數據等項目的規劃、諮詢服務,協助合做夥伴及產品部門進行大數據等項目的落地;&nbsp;<br>3. 配合BD等團隊發展生態合做夥伴,將騰訊能力與合做夥伴方案進行方案融合,爲合做夥伴提供諮詢、培訓、方案融合服務;&nbsp;<br>4. 針對客戶互聯網+需求,深度定製互聯網+解決方案並制定實施計劃,把握全局項目進度,協調相關資源、協助實施團隊完成方案Demo系統搭建,PoC測試及項目落地工做;&nbsp;<br>5. 負責互聯網+案例、技術方案的更新維護,以及佈道工做。</p>
<p><br>崗位要求:<br>1. 本科以上學歷,5年(碩士3年)以上大數據等售前諮詢相關的工做經驗;&nbsp;<br>2. 熟悉Hadoop、Spark等開源大數據技術體系,熟悉Oracle、PostgreSQL等數據庫。要求至少有3個以上政企大數據項目規劃與落地經驗;&nbsp;<br>3. 具備宏觀思惟,有高層彙報能力。熟悉醫療、公安等行業大數據優先;&nbsp;<br>4. 具有優秀的文檔能力,清晰明瞭地表達架構意圖,可以熟練編寫各種技術文檔;&nbsp;<br>5. 良好的溝通、協調及資源整合能力;&nbsp;<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|&nbsp;|<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的網撒完了,如今準備慢慢收網網絡

這幾個系列相關性挺強,隨便深刻哪個專題都得扯到其餘專題

因此最後網子就有點大了,不過不用慌,慢慢來~

相關係列文章以下: 

聊聊數據庫-概念

聊聊數據庫~開篇

 

萬物互聯之~網絡基礎

網絡編程~UDP專題

網絡編程~TCP專題

萬物互聯之~網絡增強

 

1.併發編程~先導篇(上)

2.併發編程~先導篇(下)

Python3 與 C# 併發編程之~ 上篇(Net專欄)

Python3 與 C# 併發編程之~ 進程篇上

Python3 與 C# 併發編程之~ 進程篇中

Python3 與 C# 併發編程之~ 進程篇下

Python3 與 C# 併發編程之~ 進程實戰篇

 

Python3 與 C# 併發編程之~ 線程入門篇

Python3 與 C# 併發編程之~ 線程篇-鎖專題

線程篇之~鎖專題擴展

線程篇之~線程安全篇

Queue引入篇 [看看就行]

線程篇之~Queue專題

線程篇之~Queue擴展篇

線程篇之~增強篇收尾(Event、Timer、Barrier)

線程深刻篇~引子

線程深刻篇之~GIL專題

線程篇~Actor專題

 

併發編程~協程引入篇

相關文章
相關標籤/搜索