python與JavaScript中正則表達式如何轉換


  使用python爬取網站數據的時候,總會遇到各種各樣的反爬蟲策略,有很大一部分都和JavaScript(以下簡稱為JS)

有關。在破解這些JS代碼的過程中,經常會遇到模擬JS正則表達式的情況,因此,今天總結一下如何使用python來模擬JS

中的正則。

  關於JS中正則表達式的詳細教程,可以看一下W3School的教程 JavaScript RegExp 對象

  簡單來說,無論是那種語言的正則表達式,其基本的元字符含義都是一樣的,區別之處只在於語法、函數、語言特色、

內部實現方式等,下面我們就來看一下 JS 和 python 的正則表達式有什么不一樣吧。

 

  一、正則表達式的書寫語法

  python代碼示例 

#coding:utf8
import re # 目標字符串
_string = 'Today is 2016-11-17'

# 定義正則表達式規則
regex_str = '\d+'

# 編譯為Pattern對像
pattern = re.compile(regex_str) # 開始匹配
print pattern.search(_string).group() # 輸出 #>>> 2016

 

JS代碼示例

// 目標字符串
var _string='Today is 2016-11-17'; // 定義正則表達式規則
var regex_str=/\d+/; // 編譯為Pattern對像
pattern = new RegExp(regex_str); // 開始匹配
var result = pattern.exec(_string); document.write(result); // 2016  

  

  從上面的例子來看,拋開兩種語言本身的語法,單看正則表達式的話,有以下幾點不同:

      1.python中的正則表達式本質上是一個字符串,JS中則必須以斜杠符號 / 包圍,並且不能書寫為 '/\d+/', 只

    能寫成 /\d+/ 。

      2.如果你看了W3School中JS教程的話,就會發現,JS的 RegExp 對象僅支持 compile、exec、test 這三個

    方法,而search、match、replace、split 這些更常用的方法放到了 String 類型中。但在python中的Pattern

    對象卻可以支持所有常用正則表達式操作。

 

  二、匹配模式或者說修飾符

python代碼示例

#coding:utf8
import re # 目標字符串
_string = 'Today is 2016-11-17'

# 定義正則表達式規則
regex_str = '\d+'

# 編譯為Pattern對像 # 指定使用各種模式
pattern = re.compile(regex_str, re.I | re.L | re.M | re.S | re.X | re.U) # 開始匹配 
print pattern.search(_string).group() # 輸出 #>>> 2016

 

JS 代碼示例

// 目標字符串
var _string='Today is 2016-11-17'; // 定義正則表達式規則
var regex_str=/\d+/; // 編譯為Pattern對像
pattern = new RegExp(regex_str, 'g') // pattern = new RegExp(regex_str, 'i') // pattern = new RegExp(regex_str, 'm')

// 開始匹配
var result = pattern.exec(_string) document.write(result) // 2016

    在匹配模式上,python支持的模式比較多,而JS僅支持 g 全局搜索、i 忽略大小寫、m 多行匹配這三種模式,並且

  這三種模式也不是任何時候都可以使用的,具體請往下面看。

 

  三、JS 的 String 類型支持的正則表達式操作 replace

  python的字符串處理能力很強,而JS中關於字符串的各種操作也是比較復雜、令人頭疼,一般情況下反爬蟲的JS代碼

都是通過一系列的字符串操作達到混淆視聽的目的,或者將字符串加密解密,而其中最特殊的就是replace方法。python

中的字符串類型也有replace方法,這個是基於字符串本身的,和正則表達式沒有任何關系,想要實現基於正則表達式的替

換需要使用re模塊中的sub函數。而JS中的replace函數則直接支持兩種替換方式,其根據傳入的參數類型來決定。

python示例代碼

#coding:utf8
import re # 目標字符串
_string = 'Today is 2016-11-17 \d+ \d+'

# 定義正則表達式規則
regex_str = '\d+'

# 編譯為Pattern對像
pattern = re.compile(regex_str) # 開始匹配 
print pattern.sub('2017', _string) # 輸出  #>>> Today is 2017-2017-2017 \d+ \d+

# 使用字符串本身的方法
print _string.replace(regex_str, '2017') # 輸出 #>>> Today is 2016-11-17 2017 2017

 

    JS 示例代碼

// 目標字符串
var _string='Today is 2016-11-17 \d+ \d+'; // 定義正則表達式規則
var regex_str=/\d+/;
var result = _string.replace(regex_str, '2017') document.write(result) // Today is 2017-11-17 \d+ \d+

// 不使用正則表達式
var result = _string.replace('\d+', '2017') document.write(result) // Today is 2016-11-17 2017 \d+

// 定義正則表達式規則 增加全局匹配模式 g
var regex_str=/\d+/g;
var result = _string.replace(regex_str, '2017') document.write(result) // Today is 2017-2017-2017 \d+ \d+

 

  在這個例子里面可以發現,python 的每個模塊分工很明確,而JS則混用比較嚴重,但這樣也增加了易用性。然后總結

一下幾個區別:

  1.JS 以 / 來標識正則表達式,以引號來標示字符串,根據參數類型決定進行何種替換。

  2.JS的replace無論使用正則表達式還是字符串本身,默認情況下僅替換第一個匹配項,但正則表達式可以通過使用增

加修飾符 g 實現全局替換,而字符串卻不可以。

 

四、JS 的 String 類型支持的正則表達式操作 match

  python中的re模塊有一個match函數,從字符串的開始處匹配正則表達式,但JS中的match卻不一樣,更類似於

python的re模塊的findall函數。

python示例代碼

#coding:utf8
import re # 目標字符串
_string = 'Today is 2016-11-17 \d+ \d+'

# 定義正則表達式規則
regex_str = '\d+'

# 編譯為Pattern對像
pattern = re.compile(regex_str) # match 匹配
print pattern.match(_string) # 輸出  #>>> None 

# findall 匹配
print pattern.findall(_string) # 輸出  #>>> ['2016', '11', '17']

 

      JS示例代碼

// 目標字符串
var _string='Today is 2016-11-17 \d+  \d+'; // 定義正則表達式規則
var regex_str=/\d+/;
var result = _string.match(regex_str) document.write(result) // 2016

// 定義正則表達式規則 增加全局搜索修飾符
var regex_str=/\d+/g;
var result = _string.match(regex_str) document.write(result) // 2016,11,17

// 匹配字符串
var result = _string.match('2016') document.write(result) // 2016

 

  其實這個方法完全可以使用python的findall來代替,只需要注意:

1. JS中match接受的參數是字符串還是正則表達式,字符串的話最好使用python的字符串操作方法,正則表達式的話

轉換一下寫法就可以了。

2. JS中是否使用了修飾符 g, 使用了的話和使用python的findall得到的結果是一樣的,否則就只是findall返回

值中的前一個元素。

四、JS 的 String 類型支持的正則表達式操作 search

  search方法用於檢索字符串中指定的子字符串,或檢索與正則表達式相匹配的子字符串。它的返回值是尋找到的子字符

串的起始位置的索引,這個方法在python里面對應了字符串的find方法和正則表達式re模塊中的search方法。

python示例代碼

#coding:utf8
import re # 目標字符串
_string = 'Today is 2016-11-17 \d+ \d+'

# 定義正則表達式規則
regex_str = '\d+'

# 編譯為Pattern對像
pattern = re.compile(regex_str) # search 方法尋找第一個數字出現的位置
print pattern.search(_string).start() # 輸出  #>>> 9

# find
print _string.find('2016') # 輸出  #>>> 9

 

JS代碼示例

// 目標字符串
var _string='Today is 2016-11-17 \d+  \d+'; // 定義正則表達式規則
var regex_str=/\d+/;
var result = _string.search(regex_str) document.write(result) // 9

// 匹配字符串
var result = _string.search('2016') document.write(result) // 9

  

  這個里面需要注意的可能就只是參數的類型還有返回值了,要注意JS只是返回了一個索引,而不是一個字符串

 

五、JS 的 String 類型支持的正則表達式操作 split

  split方法用於把一個字符串分割成字符串數組,可以指定返回的數組長度,JS中可接受正則表達式和字符串兩種參數,

而python與之對應的是字符串的split方法與正則表達式re模塊中的split方法

python代碼示例

#coding:utf8
import re


# 目標字符串
_string = 'Today is 2016-11-17 \d+ \d+'

# 定義正則表達式規則
regex_str = '\d+'

# 編譯為Pattern對像
pattern = re.compile(regex_str)

# split 根據正則切分
print pattern.split(_string, 2)
# 輸出                      
#>>> ['Today is ', '-', '-', ' \\d+ \\d+'] 

# 完全模擬JS
print pattern.split(_string, 2)[:2]
# 輸出                      
#>>> ['Today is ', '-'] 

# split 根據字符串切分
print _string.split('2016', 1)
# 輸出       
#>>> ['Today is ', '-11-17 \\d+ \\d+'] 

# 完全模擬JS
print _string.split('2016', 1)[:1]
# 輸出       
#>>> ['Today is '] 

 

JS 代碼示例

// 目標字符串
var _string='Today is 2016-11-17 \d+  \d+';

// 定義正則表達式規則
var regex_str=/\d+/;
var result = _string.split(regex_str, 2)
document.write(result)
// Today is ,-

// 匹配字符串
var result = _string.split('2016', 1)
document.write(result)
// Today is

      

這個在轉換的時候需要注意的就是JS返回的數組的長度了,默認情況下完全返回和完全分割,python和JS的結果是一樣

的。

  關於python和JS的正則表達式轉換,就介紹到這里了。其實真正模擬JS代碼的時候正則並不是最麻煩的,最麻煩的是以下幾個:

    1.各種位移操作

    2.JS特有的數字和字符類型相加規則

    3.[]、~~、!、{}等這些數據類型和操作符如何轉化為數字

  還有啥暫時想不起來了,這些東西會在后續的文章中逐一介紹,歡迎交流!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM