使用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);
//  

  

  从上面的例子来看,抛开两种语言本身的语法,单看正则表达式的话,有以下几点不同:

      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)
//

    在匹配模式上,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('', _string)
# 输出
#>>> Today is 2017-2017-2017 \d+ \d+ # 使用字符串本身的方法
print _string.replace(regex_str, '')
# 输出
#>>> 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)
// // 定义正则表达式规则 增加全局搜索修饰符
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)
//

  其实这个方法完全可以使用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('')
# 输出
#>>> 9

JS代码示例

// 目标字符串
var _string='Today is 2016-11-17 \d+ \d+'; // 定义正则表达式规则
var regex_str=/\d+/;
var result = _string.search(regex_str)
document.write(result)
// // 匹配字符串
var result = _string.search('2016')
document.write(result)
//

  

  这个里面需要注意的可能就只是参数的类型还有返回值了,要注意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('', 1)
# 输出
#>>> ['Today is ', '-11-17 \\d+ \\d+'] # 完全模拟JS
print _string.split('', 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.[]、~~、!、{}等这些数据类型和操作符如何转化为数字

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

python与JavaScript中正则表达式如何转换的更多相关文章

  1. 详解Javascript中正则表达式的使用

    正则表达式用来处理字符串特别好用,在JavaScript中能用到正则表达式的地方有很多,本文对正则表达式基础知识和Javascript中正则表达式的使用做一个总结. 第一部分简单列举了正则表达式在Ja ...

  2. JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解

    二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 ...

  3. JavaScript中正则表达式判断匹配规则以及常用的方法

    JavaScript中正则表达式判断匹配规则以及常用的方法: 字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在. 正则表达式是一种用来匹配字符串的强有力的武器.它的设计思想 ...

  4. javascript中正则表达式的基础语法

    × 目录 [1]定义 [2]特点 [3]元字符[4]转义字符[5]字符组[6]量词[7]括号[8]选择[9]断言[10]模式[11]优先级[12]局限性 前面的话 正则表达式在人们的印象中可能是一堆无 ...

  5. 【前端】深入浅出Javascript中的数值转换

    由于Javascript是一门弱类型的语言,在我们的代码中无时无刻不在发生着类型转换,所以了解Javascript中的类型转换对于了解我们认识Javascript的运行原理至关重要. 本文主要从数值转 ...

  6. JavaScript中的数值转换

    在JavaScript中,有3个函数可以把非数值转换为数值 1.Number()函数 Number()可以用于任意数据类型. 转换规则如下. 如果是Boolean值,true和false将分别被转换为 ...

  7. python、javascript中的不可变对象

    比如python中str是不变对象,而list是可变对象,javascript中str也是不变对象,而array是可变对象 python的例子: >>> a = 'abc' > ...

  8. C#和Javascript中 正则表达式使用的总结

    说明:本文并非原创,而是从网站上搜集了一些资料整理的!如有雷同,纯属巧合 1.js中正则表达式的使用 在js中定义正则表达式很简单,有两种方式,一种是通过构造函数,一种是通过//,也就是两个斜杠.例如 ...

  9. javascript中正则表达式和ruby中的一点差异

    看到一个例子,不过这个例子中正则表达式的格式貌似是错的: Function.prototype.get_name = function(){ return this.name || this.toSt ...

随机推荐

  1. 将Ctrl+Alt+Delete键进行屏蔽,防止误操作重启服务器

    [root@bgw-t ~]# vi  /etc/init/control-alt-delete.conf #exec /sbin/shutdown -r now "Control-Alt- ...

  2. Haskell语言学习笔记(41)Parsec(1)

    Parsec Parsec是一个词法及语法分析器. 匹配字符与字符串 Prelude Text.Parsec> parseTest anyChar "a" 'a' Prelu ...

  3. ArcGIS案例学习笔记3_1

    ArcGIS案例学习笔记3_1 联系方式:谢老师,135_4855_4328,xiexiaokui#139.com 时间:第三天上午 内容1:ArcGIS 平台介绍 体系结构 Arcgis for d ...

  4. 漫谈四种神经网络序列解码模型【附示例代码】 glimpse attention

    漫谈四种神经网络序列解码模型[附示例代码] http://jacoxu.com/encoder_decoder/ [视觉注意力的循环神经网络模型]http://blog.csdn.net/leo_xu ...

  5. Python递归的经典案例

    目录 : 一.递归的简介 二.递归的经典应用   2.1 递归求阶乘   2.2 递归推斐波那契数列   2.3 二分法找有序列表指定值   2.4 递归解汉诺塔 前言: 当我们碰到诸如需要求阶乘或斐 ...

  6. "\\s+"的使用

    详解 "\\s+" 正则表达式中\s匹配任何空白字符,包括空格.制表符.换页符等等, 等价于[ \f\n\r\t\v] \f -> 匹配一个换页 \n -> 匹配一个换 ...

  7. js中的变量提升(hoisting)

    来看如下代码: function HelloJS(){ var array = [1,2,3,4,5]; for(var i in array){ } alert(i); } HelloJS(); a ...

  8. java并发:volatile关键字

    java并发需要保证原子性,可见性,有序性. http://www.cnblogs.com/expiator/p/9226775.html 一.volatile关键字作用如下: 1.volatile关 ...

  9. Marriage Match II(二分+并查集+最大流,好题)

    Marriage Match II http://acm.hdu.edu.cn/showproblem.php?pid=3081 Time Limit: 2000/1000 MS (Java/Othe ...

  10. python学习——urlparse模块

    urlparse模块: 1.urlparse() 具体程序及结果如下: >>> url = 'http://i.cnblogs.com/EditPosts.aspx?opt=1'&g ...