python与JavaScript中正则表达式如何转换

  使用python爬取网站数据的时候,总会遇到各类各样的反爬虫策略,有很大一部分都和JavaScript(如下简称为JS)python

有关。在破解这些JS代码的过程当中,常常会遇到模拟JS正则表达式的状况,所以,今天总结一下如何使用python来模拟JS正则表达式

中的正则。数组

  关于JS中正则表达式的详细教程,能够看一下W3School的教程 JavaScript RegExp 对象函数

  简单来讲,不管是那种语言的正则表达式,其基本的元字符含义都是同样的,区别之处只在于语法、函数、语言特点、网站

内部实现方式等,下面咱们就来看一下 JS 和 python 的正则表达式有什么不同吧。加密

 

  1、正则表达式的书写语法spa

  python代码示例 code

#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代码示例regexp

// 目标字符串
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

    对象却能够支持全部经常使用正则表达式操做。

 

  2、匹配模式或者说修饰符

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 多行匹配这三种模式,而且

  这三种模式也不是任什么时候候均可以使用的,具体请往下面看。

 

  3、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 实现全局替换,而字符串却不能够。

 

4、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返回

值中的前一个元素。

4、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只是返回了一个索引,而不是一个字符串

 

5、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.[]、~~、!、{}等这些数据类型和操做符如何转化为数字

  还有啥暂时想不起来了,这些东西会在后续的文章中逐一介绍,欢迎交流!!!

相关文章
相关标签/搜索