zoukankan      html  css  js  c++  java
  • 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.[]、~~、!、{}等这些数据类型和操作符如何转化为数字

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

  • 相关阅读:
    在linux下使用sqlcmd
    sqlserver 索引的结构及其存储,索引内容
    据库被标记为RESTORING的处理方式,正在还原中,正在恢复
    sql语句的优化分析
    SQL Server表分区-水平分区
    JavaScript Structure
    JS----Issue
    JavaScript Book Plan
    LINQ
    About JavaScript
  • 原文地址:https://www.cnblogs.com/dyfblog/p/6077122.html
Copyright © 2011-2022 走看看