精华内容
下载资源
问答
  • 以下的三个程序才是正确的,环球网校小编建议大家可以试着理解这些内容,也许对您的python学习有帮助,毕竟实践出真知,所以你要知道python解析URL的方法是什么?以下的三个程序才是正确的。在Python中的urlparse模块...

    【摘要】网络爬虫是爬虫的应用之一,那么python解析URL的方法是什么?以下的三个程序才是正确的,环球网校小编建议大家可以试着理解这些内容,也许对您的python学习有帮助,毕竟实践出真知,所以你要知道python解析URL的方法是什么?以下的三个程序才是正确的。

    在Python中的urlparse模块主要是用于解析url中的参数 对url按照一定格式进行 拆分或拼接

    1、python解析URL的方法是什么——urlparse.urlparse

    将url分为6个部分,返回一个包含6个字符串项目的元组:协议、位置、路径、参数、查询、片段。

    import urlparse

    url_change = urlparse.urlparse('https://i.cnblogs.com/EditPosts.aspx?opt=1')

    print url_change

    输出结果为:

    1ParseResult(scheme='https', netloc='i.cnblogs.com', path='/EditPosts.aspx', params='', query='opt=1', fragment='')

    其中 scheme 是协议 netloc 是域名服务器 path 相对路径 params是参数,query是查询的条件

    1urlparse.parse_qs(urlparse.urlparse(url).query)

    这个是获取urlparse分割后元祖中的某一项 urlparse.urlparse(url).query 获取查询条件

    parse_qs 有几种实现

    urlparse.parse_qs 返回字典

    urlparse.parse_qsl 返回列表

    2、python解析URL的方法是什么——urlparse.urlsplit

    和urlparse差不多,将url分为5部分,返回一个包含5个字符串项目的元组:协议、位置、路径、查询、片段。

    import urlparse

    url_change = urlparse.urlsplit('https://i.cnblogs.com/EditPosts.aspx?opt=1')

    print url_change

    SplitResult(scheme='https', netloc='i.cnblogs.com', path='/EditPosts.aspx', query='opt=1', fragment='')

    其中 scheme 是协议 netloc 是域名服务器 path 相对路径 query是查询的条件

    3、python解析URL的方法是什么——urlparse.urljoin

    将相对的地址组合成一个url,对于输入没有限制,开头必须是http://,否则将不组合前面。

    import urlparse

    new_url = urlparse.urljoin('https://baidu.com/ssss/','88888')

    print new_url

    输出 https://baidu.com/ssss/88888

    如果输入错误信息 如 new_url = urlparse.urljoin('122','88888') 并不会将两者合并 输出‘88888’

    以上就是《python解析URL的方法是什么?以下的三个程序才是正确的》的全部内容,这些解析网站URL的方法学会了,你的python一定会突飞猛进,环球网校的小编也祝大家python学习之路顺利。如果你想知道更多的python编程知识,可以点击下方资料下载链接。

    展开全文
  • 广义的理解其实就是数据请求的两种方式,区别的也基本人尽可之 1.GET在浏览器回退时无害的,而POST会再次提交请求。 2.GET产生的URL地址可以被Bookmark,而POST不可以。 3.GET请求会被浏览器主动cache,而POST不会...

    什么是GET和POST

    广义的理解其实就是数据请求的两种方式,区别的也基本人尽可之
    1.GET在浏览器回退时是无害的,而POST会再次提交请求。
    2.GET产生的URL地址可以被Bookmark,而POST不可以。
    3.GET请求会被浏览器主动cache,而POST不会,除非手动设置。
    4.GET请求只能进行url编码,而POST支持多种编码方式。
    5.GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
    6.GET请求在URL中传送的参数是有长度限制的,而POST么有。
    7.对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
    8.GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
    9.GET参数通过URL传递,POST放在Request body中
    在这里插入图片描述
    这样回答也没错,但你这样的回答其实只能说明你没有get到面试官真正的意图
    我们抛开两者的不同来看,其实从出发点上来说他们本质相同的一种东西
    依附的都是http

    而HTTP的底层是TCP/IP。所以GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接。GET和POST能做的事情是一样一样的。你要给GET加上request body,给POST带上url参数,技术上是完全行的通的。
    

    GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。

    GETPOST 其实还有一个隐式的最大区别 :GET产生一个TCP数据包;POST产生两个TCP数据包。
    这才是核心的区别所在!!!
    造成这一现象的原因呢,其实就是浏览器接受响应的处理方式造成的

    对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据)

    对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)
    

    使用技巧的区别

    1. GET与POST都有自己的语义,不能随便混用。

    2. 在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。

    3. 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。

    展开全文
  • 原文地址:[url]http://www.buildapp.net/post/corona_lua_table.htm[/url] ...如果你有其他语言开发经验,你应该知道2种数据类型,那就是数组和集合,在lua中,table就是数组和集合混合物(这也什么tabl...
    原文地址:[url]http://www.buildapp.net/post/corona_lua_table.htm[/url]

    在corona sdk里,是用lua去做所有事情的。因此,了解lua的特性和API非常重要。

    什么是Table?

    如果你有其他语言的开发经验,你应该知道2种数据类型,那就是数组和集合,在lua中,table就是数组和集合的混合物(这也是为什么table如此强大的原因)。

    如果corona sdk是你第一次开始接触编程,你可能认为table就是一个表,或者梳妆台,哈哈。

    梳妆台的抽屉就类似于“key”,你放在里面的东西就是“value”。然后,lua table和真正的梳妆台不同的是,梳妆台抽屉里面还可以放置梳妆台。

    在我们继续之前,我认为你已经了解了如下内容:

    1)table里保存数据,数据可以是任何类型,包括function。

    2)table里也可以保存table

    3)key代表数据存储的位置(如抽屉)

    4)value就是用特定的key存储的数据

    这可能就是lua table的基本解释了,下面我讲说一说在lua中如何定义table,如何对table进行存储和检索,以及如何使用“for”来循环表里table。

    定义table

    当然,定义,我的意思是创建一个表,所以你可以任何时候用它。现在,我将重点放在创建一个没有数据的空白表。这将是我们的品牌新的梳妆台:

    local myTable = {}

    在lua中定义table和定义其他变量一样,就是一个等号,左边是变量名,右边是存储的数据。table是用“{”“}”来定义存储的数据。这种表达方式在你使用一些函数的时候经常看到。现在你有一个空白表(mytable),接下来,我将通过不同的方式存储数据到一个表中,以及如何检索数据。

    table数组

    下面3种方法来定义table都是合法的,实际上他们都在做同样的事情。3和4的其实是一样的,只是告诉你在这里换行是没有必要的,尤其把table作为函数参数时经常用到。

    方法1:
    local colorTable = {}

    colorTable[1] = "blue"
    colorTable[2] = "red"
    colorTable[3] = "yellow"
    colorTable[4] = "green"
    colorTable[5] = "purple"

    print( colorTable[3] ) -- output: "yellow"

    方法2:
    local colorTable = {
    [1] = "blue",
    [2] = "red",
    [3] = "yellow",
    [4] = "green",
    [5] = "purple"
    }

    print( colorTable[3] ) -- output: "yellow"

    方法3:
    local colorTable = {
    "blue",
    "red",
    "yellow",
    "green",
    "purple"
    }

    print( colorTable[3] ) -- output: "yellow"

    方法4:
    local colorTable = { "blue", "red", "yellow", "green", "purple" }

    print( colorTable[3] ) -- output: "yellow"

    上面的例子都在做同样一件事情。作为corona的开发者,你必须熟悉每一种表示方法,因为你可以完全根据个人喜好来使用table。当table仅仅是做为一个数值数组时,key都是数值(和其他语言不同的是,是从1开始而不是0)。例如在每个print语句(段)告诉您如何使用放在方括号(“[]”)之间的索引号来访问表中的数据。

    要获得使用数字key的table的元素总数,你可以这样做在表的名称前面使用'#'标志,就像这样:
    print( #colorTable ) -- output: 5

    table集合
    Lua中的table,也可以像其他编程语言的dictionary集合(也称为“关联数组”)。
    下面是一个像dictionary一样行为的表的例子:
    local colorTable = {
    sky = "blue",
    grass = "green",
    water = "blue",
    lava = "red"
    }
    colorTable.dirt = "brown"
    -- Accessing the data:
    print( colorTable.grass ) -- output: green
    print( colorTable["dirt"] ) -- output: brown

    在上面的例子,你可以看到没有定义数字键,这就是主要区别。有时候,使用这种方法可以使得数据便于识别和访问。使用key而不是数字索引,是为了更准确(当作为集合使用时,数据的实际存储位置和你定义时的位置可能不一致)。你可以使用下面两种方法来访问数据:

    colorTable["sky"]
    -- and...
    colorTable.sky

    上面的2种方法显示了2种不同的方法来访问同一个数据。和使用数字key一样,你也可以添加key,就像定义之后再添加“dirt”一样。

    lua中的table可以同时表示数组和集合,你可以混合使用数字key和字符串key,但是这会非常混乱,我们建议你同时只用来表达一个类型的数据。

    数据类型

    如上所述,table可以用key来存储任何数据类型。这意味着你可以存储额外的表,函数和引用函数的表,以及更常见的数字和字符串。

    这里有一个如何在表中存储一个表的例子(以及如何访问数据):

    local people = {
    { name="Bob", age=32, gender="male" },
    { name="Jane", age=29, gender="female" }
    }

    print( people[1].name )
    -- output: Bob

    print( people[2]["gender"] )
    -- output: female

    table中可以存储任意个table,没有限制。

    下面,另一个稍微复杂的数据table,你会看到在一个表中利用一个key来存储function的引用。示例:

    local function helloWorld()
    print( "Hello World!" )
    end

    local myTable = {
    name = "Bob",
    func = helloWorld
    }

    myTable.func() -- output: Hello World!

    ----------

    local function helloWorld()
    print( "Hello World!" )
    end

    local myTable = { 100, 100, helloWorld, true }
    myTable[3]() -- output: Hello World!

    下面将展示如何在一个table里存储function的实际功能。

    local myTable = { 100, 100, function() print( "Hello World!" ); end, true }
    myTable[3]() -- output: Hello World!

    你现在可能已经明白了,lua table里面的key和lua的其他变量没有任何区别,可以存储任何类型数据。这样是最好理解的方法了。

    当table越来越大越来越混乱时,我建议里可以用逗号为间隔来看待。可能会比较清晰。

    table和循环

    如何迭代表数据是使用table最常见的功能了,下面展示如何遍历一个使用数字key的table:

    local myTable = { "blue", "red", "yellow", "green", "white", "purple" }

    for i=1,#myTable do
    print( myTable[i] )
    end

    -- OUTPUT:
    blue
    red
    yellow
    green
    white
    purple

    上面的代码,我想已经很清楚的说明了一切。遍历数字key的表的内容是相当平滑的。

    但是,如果你的表的键名,而不是数字?

    为此,我们将使用pairs()函数(它返回两个变量):

    local colorTable = {
    sky = "blue",
    grass = "green",
    water = "blue",
    lava = "red",
    dirt = "brown"
    }

    for key,value in pairs(colorTable) do
    print( key, value )
    end

    -- OUTPUT:
    sky blueg
    rass green
    water blue
    lava red
    dirt brown

    如果一个table使用字符串来表示key,那么你就不能简单的使用索引来访问(上面说过当用字符串key来存储时,数据的实际存储顺序和你定义它时的可能不一致,所以不能直接用数字索引)。相反,你使用了pairs()来遍历没有使用数字key的table(就像上面的例子中看到)。

    为了获得更完整,全面了解Lua中的表,请访问以下两个网页(两者都是我学习的时候我非常有用):

    http://www.lua.org/pil/2.5.html
    http://lua.gts-stolberg.de/en/Tables.php
    展开全文
  • 本文转载自霍格沃兹测试学院优秀学员ling_tianxia学习笔记,原文链接: ...url=...    提起正则表达式,不知道大家第一印象是什么,可能是强大好用也可能是晦涩难懂。正则表达式在文本处理中.

    本文转载自霍格沃兹测试学院优秀学员ling_tianxia的学习笔记,原文链接:
    http://qrcode.testing-studio.com/f?from=csdn2&url=https://ceshiren.com/tag/%E7%B2%BE%E5%8D%8E%E5%B8%96 转载请注明出处

    正则表达式学习心得

    前言

    一个学习笔记居然会有前言?没错,这个是额外增加的,显得专业一点。
        提起正则表达式,不知道大家第一印象是什么,可能是强大好用也可能是晦涩难懂。正则表达式在文本处理中相当重要,各大编程语言中均有支持,但可能使用起来有细微的差别,该学习笔记中元字符介绍一节不特定于某一个编程语言,旨在简要描述正则本身的基本用法。
        前言中先阐述一下正则表达式到底是个什么东西,清楚这个概念的可以直接跳过。正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。(该概念摘自百度百科,不要问我为啥不用Google)
        看完上面的解释,我的第一反应是有点似懂非懂。
        个人理解如下:某个大佬为了从字符串中匹配或找出符合特定规律(如手机号、身份证号)的子字符串,先定义了一些通用符号来表示字符串中各个类型的元素(如数字用 \d 表示),再将它们组合起来得到了一个模板(如:\d\d模板就是指代两个数字),拿这个模板去字符串中比对,找出符合该模板的子字符串。

    简单的例子

    了解了什么是正则表达式后,在由几个例子去进一步理解。
        现在有一个字符串为:

    I am a tester, and My job is to test some software.

    1. test是一个正则表达式,它的匹配情况:I am a tester, and My job is to test some software. 它既可以匹配tester中的test,又可以匹配第二个test。正则表达式中的test就代表test这个单词本身。
    2. \btest\b是一个正则表达式,它的匹配情况:I am a tester, and My job is to test some software. 它只能匹配第二个test。因为\b具有特殊意义,指代的是单词的开头或结尾。故tester中的test就不符合该模式。
    3. test\w*是一个正则表达式,它的匹配情况:I am a tester, and My job is to test some software. 它匹配出了tester,也匹配出了第二个test。其中\w的意思是匹配字母数字下划线,*表示的是数量,指有0个或多个\w。所以这个正则表达是的意思就是匹配开头为test,后续跟着0个及以上字母数字下划线的子字符串
    4. test\w+是一个正则表达式,它的匹配情况:I am a tester, and My job is to test some software. 它只匹配了tester。因为+与*不同,+的意思是1个或多个,所以该正则表达式匹配的是开头为test,后续跟着1个及以上字母数字下划线的字符串。
          通过上述几个例子,应该可以看出正则表达式的工作方式,正则表达式由一般字符和元字符组成,一般字符就是例子中的‘test’,其指代的意思就是字符本身,t匹配的就是字母t;元字符就是例子中有特殊含义的字符,如\w, \b, *, +等。后续介绍一些基础的元字符。

    元字符介绍

    元字符有很多,不同元字符有不同的作用,大致可以分为如下几类。

    用于表示意义

    有些元字符专门用来指代字符串中的元素类型,常用的如下:

    ![](https://s4.51cto.com/images/blog/202012/18/954aa89bf71ae61c0fccb9b357a79c08.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
    

    通过上述表格中的数据可以发现,\w,\d,\s都有一个与之相反的元字符(将对应字母大写后就是了)。\w匹配所有字母数字下划线,那么\W就是匹配所有不是字母数字下划线的字符。只要记住其中3个,另外3个就很好记了。
        乍一看这几个元字符挺简单的,但是经常不用的话保不准会忘记,此处分享一下我的记忆方法。我把这几个元字符都当作是某一个单词的缩写(虽然可能就是某个单词的缩写,但是没有找到准确的资料去印证),\s是space(空间)的缩写、\d是digit(数字)的缩写、\w是word(可以理解成不是传统意义上的单词而是代码中的变量名,变量名可包含的元素就是字母数字下划线)的缩写。好了,看到此处你应该已经熟记了6个元字符了。接下来,\n和\t平时会经常用到,这个肯定比较熟了,最后一个元字符‘.’可以理解它匹配一行中的所有元素,因为遇到换行符后就不再进行匹配了(万事万物源于一点)。

    用于表示数量

    有些元字符用于表示某种元素的数量,如\d表示一个数字,当你想表示6位数字怎么办?当然可以\d\d\d\d\d\d ,但确实太麻烦了,为了简便就需要一些表示数量的元字符,上述可以写成\d{6},元字符详情如下:

    这几个元字符还算比较好记。*表示0个或多个,+表示1个或多个,这个可能会混淆,或许你可以这么记,表示10=0或多个,+表示1+0=1或多个。?表示0或1个,可以理解成某个人在问你这个类型的元素有还是没有呀?你回答可能有(1)也可能没有(0)。
        剩下的三个只要记住大括号是用来表示数量,后续我们还会看到除了{}外,还有[]和()。它们各有各的作用。

    用于表示位置

    有些元字符没有具体的的匹配项,它只是一个抽象的位置概念,它用来表示字符串中的各个位置。一个字符串的位置可以分成:字符串的开头或结尾、单词的开头或结尾。如字符串‘I am a tester_.’,I前面是字符串的开头位置,英文句号后面为字符串的结尾位置,每一个word(注意此处指的不是传统意义上的单词)前后的位置即为单词的开头或结尾,对于‘tester_’来说t前面是单词开头,下划线是单词结尾。
        在这里插入图片描述

    其中\b在前面的例子中有说过,此处可以以这种方式记忆:\b是block(块)的缩写,即一个单词是一块内容,\b是这一块的边界。至于另外两个元字符,暂时没找到很好的记忆方法(^一个尖角,小荷才露尖尖角?),但应该也不难记。
        此处有个地方要提及一下,所有表示位置的不会实际占用字符。为了理解可以继续看最上面的第二个例子,\btest\b最终匹配出来了子字符串“test”,而不是“ test ”。
        大家依据目前了解的元字符概念,可以思考一下这个正则表达式^\d{6,10}$,和\d{6,10}的区别。针对字符串‘12345678‘,第一个和第二个都可以匹配出’12345678‘。但是针对字符串’W12345678‘,只有第二个可以正确匹配出’12345678‘,原因在于第一个正则表达式的意思匹配一个字符串只有6-10个数字组成,而第二个正则表达式意思是匹配字符串中的6-10个连续数字。
        除了这三个元字符表示位置外,还有零宽断言、负向零宽断言也表示位置,后续会详细介绍。

    用于字符转义

    字符转义的概念大家肯定不陌生,对于*, +等有特殊意义的元字符,假如你想匹配5个号应该怎么写,{5}吗?肯定不是,这样写是语法错误,应该使用\将其转义:*{5}。这样一来*的特殊意义就被\给取消了,想要匹配\的话,也是一样,再用一个\把特殊意义取消掉就好了。

    字符集

    前面列出了部分用于表示意义的元字符,但是可能这几个元字符覆盖的都太广泛了,想要具体的匹配某一类字符。比如就是想匹配abcd这四个字符中的某一个,正则表达式当然也是支持的。
        这时候就需要用到第二种括号,中括号[]。匹配abcd中的某一个可以写成[abcd]或者[a-d],意思是匹配一个a-d中的任意字符。相反若匹配非abcd的任意字符,可以写成[^abcd],意思是匹配一个不是abcd的字符。
        括号内也可以写入不同类型的元素,如[a-d1-7@],表示的是匹配一个a-d或1-7或@中的任意字符,[^a-d1-7@]则与之相反

    分组

    讲完中括号后我们可以看一下小括号(),小括号的意思是分组,即小括号内部的所有元字符是一个整体。
        之前有学过表示数量的元字符,但是那个表示的数量都是针对于一个元字符来说的,比如ab+表示的是匹配一个a后面跟着1个或多个b的子字符串。
        倘若我们想要匹配的是1个或多个ab(如:abababab),此时分组就派上作用了,可以这么写:(ab)+。此时ab被绑定为一个整体,后面的数量元字符对这个整体起作用。

    分枝条件

    元字符中有一个或运算符,它与大多数编程语言类似都是用 | 来表示。它的作用为:Ab|aB表示的是匹配Ab或者aB。通过这个例子可以很直观的理解该元字符的作用。当然它也经常和分组一起使用:(Ab|aB)+c,该正则匹配开始为1-N个Ab或aB之后是c的子字符串,如:AbaBc, AbAbAbaBc。

    后向引用

    后向引用的使用是依附于分组的,分组的概念之前讲过了。
        首先,我们先看一下正则表达式中组号的分配方式,此时先看一个用到分组的正则表达式:(ab)?(c|C)d。这个正则的意思大家现在肯定都清楚了。这个正则表达式里面用到了两个分组分别是(ab)和(c|C)。正则内部会对所有分组进行组号分配,从左向右,第一个分组(ab)的组号是1,第二个分组(c|C)的组号是2。而组号0代表的是整个正则表达式。尝试过python正则的此处应该有印象,匹配对象的group方法传参为0或不传则返回整个正则所匹配的结果,传参为1为第一个分组匹配的结果。
        了解了组号分配方式后,可以开始解释后向引用了。后向引用就是将前面某个分组已经匹配的数据拿过来用,第一个分组匹配的数据用\1代替,第二个分组匹配的数据用\2代替,依次类推。
        似乎不是特别好理解,直接看例子吧,(ab)?(c|C)d\2D该正则中\2表示的是第二个分组匹配到的数据,若第二个分组匹配到了c那么\2就是c,反之亦然。所以它能匹配到:abcdcD, abCdCD。不能匹配:abcdCD, abCdcD。通过这个例子可以理解它的作用了吧。
        当然分组除了有自己的组号外,还可以给它自定义组名。不同编程语言中的方式不同,Python中自定义组名的格式为:(?Pexp),Name为你自定义的组名,exp代表任意元字符的组合。后面引用的方法为(?P=name)。所以上面例子可以修改成:(ab)?(?Pc|C)d(?P=CWord)D。

    组号分配介绍

    上一节简单的讲了一下正则表达式是如何分配组号的,但其实还有几个需要注意的地方。
    虽然组号是从左向右进行分配,但是扫描两遍,第一遍先分配给未命名的分组,第二遍再分配给命名的分组。所以命名后的分组组号会更大
    使用(?:exp)可以使一个分组不分配组号,如(?:ab)?(c|C)d\2D中(ab)就没有分配到组号,而(c|C)组号为1

    贪婪与懒惰

    人性是贪婪的,正则表达式与人一样也是贪婪的。一个正则表达式会尽量多的去匹配字符串,如:ab.+c去匹配’abccccc’是会将该字符串全部匹配出来。但有时候我们只想要其匹配’abcc’,此时怎么办呢?需要给正则表达式中表示数量的元字符加一个?变成ab.+?c。此时该正则表达式就变懒了,不会再去匹配那么多,匹配到‘abcc’就完事了。

    零宽断言及负向零宽断言

    这两个个概念有些不太好理解。正如前面所说这两个也是表示位置的元字符。从字面意思上理解,零宽代表其没有宽度,即如之前介绍表示位置的元字符中提到的一样,不会实际占用字符。断言是什么?是assert,是用来判断条件是True还是False。理解完这两个词语的意思后,零宽断言的概念应该也就能理解了。那么负向无非就是它的反义词。

    上面的表格主要看第一列它是什么格式就好,反正后面的名称和说明也很难看懂。接下来我来用自己的理解通俗的解释一下这些概念。
       首先字符串中可以有四种方式确认某个子字符串的位置,如字符串‘BACAB’中有两个A,A前面是B、A前面不是B、A后面是C、A后面不是C。上述四种条件都能够匹配出唯一一个子字符串A。这个例子大概理解的话就可以往后看了。

    • (?=exp)中exp指代的是任意元字符的组合,结合具体的例子来理解该元字符的用法,一个正则表达式为A(?=C),它代表的情况就是A后面是C的情况。所以匹配出了第一个A,由于该元字符是零宽所以它只能匹配出A而不是AC。
    • (?<=exp)与上面用法相反,一个正则表达式为(?<=B)A,它代表的情况就是A前面是B的情况。所以匹配出了第一个A。如果改成(?<=C)A,则能匹配出第二个A。
    • (?!exp)的例子为:A(?!C),它代表的情况为A后面不是C,所以匹配出第二个A。
    • (?<!exp)的例子为:(?<!B)A,它代表的情况为A前面不是B,所以匹配出第二个A。
          通过上面四个例子的介绍,应该对于这两个概念、四个元字符有了了解。理解是重点,记下来也是重点。本人是这样记下来的,四个元字符的基本格式都是(?),只不过问号后面的不一样。分下面两种情况:
    • XXX前/后是XXX的话就写一个=,XXX前/后不是XXX的话就写一个!。这个和日常用的=和!=差不多。
    • 如果表示的意思是前的话,这个元字符就需要出现在前面且要加一个类似于向前指的箭头<。如果表示的意思是后的话,就什么都不需要加。
          通过上面两个情况的归纳,是不是这四个元字符就都记下来了,上述记忆方法为个人拙见,仅供参考。

    总结

    到目前为止,正则表达式的基本内容都介绍完了。但是文中用的例子都比较简单,只能帮助你理解概念。如果感兴趣或者工作中能用到的话,还需要后续勤加练习。
        你以为文章到总结就结束了?So naive, 当我们知道正则表达式大概是个什么东西,大概怎么去用了之后。我再来列举一个日常工作中的案例,将理论应用到实践。正则表达式在日常使用中一定是基于某一种编程语言的,后面的案例编程语言选择python(因为我目前只会这个)。
        设想这么一个场景,在测试过程中需要获取某个时间段内某个程序的运行情况,从而分析出该程序的稳定性或使用频率等指标,该程序的日志记录完备,日志格式固定且已知。这时候最佳的办法就是从该程序日志中进行相关信息的获取。假如该日志内容格式大概如下(注:该日志样例不是实际项目中的日志文件,为个人举例):

    2020-02-17 11:04:34 [INFO] 接收到来自IP: 182.168.3.111的访问,访问的认证方式为邮箱:110232123@qq.com,获取数据状态码1,获取数据12931KB
    2020-02-17 11:05:34 [INFO] 接收到来:自IP:182.168.3.111的访问,访问的认证方式为手机号:008617626045747,获取数据状态码2,获取数据0KB
    2020-02-17 12:04:34 [WARN] IP:182.168.3.111访问失败
    2020-02-17 11:04:34 [ERROR] 连接XXX服务失败,正在重连。。。。

    从这个日志中可以看到访问成功的IP及其认证账号、访问失败的IP、程序的错误信息。那么我们怎么把这些数据给抓取出来呢?抓取的方法肯定有很多,如果此时你第一时间想到了正则表达式,那么恭喜你,通过阅读前面的文章,正则已经在你心中留下了痕迹,或者它本来就留有痕迹。
        我们先来分析一下第一条日志,其余的与此类似,有用的信息可以分成如下几个片段:

    • 时间字符串:2020-02-17 11:04:34
    • 日志级别:INFO
    • IP:182.168.3.111
    • 认证邮箱:110232123@qq.com
    • 状态码:1
    • 客户端获取到的数据大小:12931KB
          上面几个片段对应的正则为:
    • 时间字符串:\d{4}-\d{2}-\d{2}\s*\d{2}:\d{2}:\d{2}
    • 日志级别:[INFO]
    • IP:(\d{1,3}.){3}\d{1,3}
    • 认证邮箱:\w+@\w+.\w+
    • 状态码:\d+
    • 客户端获取到的数据大小:\d+KB
          上述中某几个正则其实并不严谨,比如IP对应的正则还可以匹配出999.999.999.999。严谨的正则表达式是((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)。由于该正则太长,加之此处重点在于如何应用,故暂用其宽松版的正则表达式。
          知道了各个字段的正则后,我们可以将它们各自写成一个分组,分组之间填充上其余元字符,把匹配整行日志的正则表达式写出来,如下:
    (\d{4}-\d{2}-\d{2}\s*\d{2}:\d{2}:\d{2})\s*\[(INFO)\]\s*.*:((\d{1,3}\.){3}\d{1,3}).*:(\w+@\w+\.\w+)\D*(\d+)\D*(\d+)KB
    

    现在我们通过这个正则表达式可以抓取出日志文件中这种格式的日志字符串,再根据组号就可以拿出来对应的数据了。不过根据组号取数据可能会有些含糊不清,或许我们可以给每个分组进行命名(使用python支持的方式),形成如下正则表达式:

    (?P<Time>\d{4}-\d{2}-\d{2}\s*\d{2}:\d{2}:\d{2})\s*\[(?P<LogLevel>INFO)\]\s*.*:(?P<IP>(\d{1,3}\.){3}\d{1,3}).*:(?P<Email>\w+@\w+\.\w+)\D*(?P<status>\d+)\D*(?P<data_size>\d+)KB
    

    好了现在我们可以很清楚的看到,表示时间的分组命名为Time,依次类推。接下来,我们可以使用上述正则表达式去抓取一行日志,再通过分组的名称拿到对于的字符串数据了。具体的代码可以参考下面的样例:

    import re
    
    def reg_deal(pattern_list, text, func_dict=None):
        if func_dict is None:
            func_dict = {}
        for pattern in pattern_list:
            match_obj = re.match(pattern, text)
            if match_obj:
                return {k: func_dict.get(k, lambda x: x)(v) for k, v in match_obj.groupdict().items()}
    
    if __name__ == '__main__':
        email_pattern = r"(?P<Time>\d{4}-\d{2}-\d{2}\s*\d{2}:\d{2}:\d{2})\s*\[(?P<LogLevel>INFO)\]\s*.*:(?P<IP>(\d{1," \
                        r"3}\.){3}\d{1,3}).*:(?P<Email>\w+@\w+\.\w+)\D*(?P<status>\d+)\D*(?P<data_size>\d+)KB"
        phone_pattern = r"(?P<Time>\d{4}-\d{2}-\d{2}\s*\d{2}:\d{2}:\d{2})\s*\[(?P<LogLevel>INFO)\]\s*.*:(?P<IP>(\d{1," \
                        r"3}\.){3}\d{1,3}).*:(?P<Phonenum>((\+|00)86)?1[3-9]\d{9})\D*(?P<status>\d+)\D*(?P<data_size>\d+)KB"
        warn_pattern = r"(?P<Time>\d{4}-\d{2}-\d{2}\s*\d{2}:\d{2}:\d{2})\s*\[(?P<LogLevel>WARN)\]\s*.*:(?P<IP>(\d{1," \
                       r"3}\.){3}\d{1,3}).*"
        error_pattern = r"(?P<Time>\d{4}-\d{2}-\d{2}\s*\d{2}:\d{2}:\d{2})\s*\[(?P<LogLevel>ERROR)\]\s*(?P<ERROR_Message>.*)"
        pattern_list = [email_pattern, phone_pattern, warn_pattern, error_pattern]
        status_dict={
            '1': 'Sucess',
            '2': 'Fail'
        }
        func_dict = {
            'status': lambda x: status_dict[x],
            'data_size': lambda x: int(x)/1024
        }
        result_list = []
        with open('logcontent.log', 'r', encoding='utf-8') as f:
            for data in f:
                result_dict = reg_deal(pattern_list, data, func_dict)
                result_list.append(result_dict)
        print(result_list)
    

    代码中实现了一个函数reg_deal,后面代码都是对于这个函数的实际应用,该函数入参为:正则表达式组成的列表、待匹配的字符串、特殊函数组成的字典。其先循环将字符串与列表中各个正则表达式进行匹配,匹配成功后得到一个匹配对象,调用该匹配对象的groupdict函数可以返回一个结果字典,该结果字典的键为分组的名称,值为分组匹配到的值。针对这一结果字典再进行一步特殊函数处理,如上述中的status字段日志中是码值,但输出结果需要是具体的汉字。故对其进行了一步码值转换操作,对与数据大小将KB转化成了MB。
        若使用该函数,需自己将正则表达式写出来并对正则表达式中的分组进行命名,若有些分组数据需要特殊处理,则维护一个特殊函数字典,键为分组名,值为函数(匿名函数或者是函数名称)。将参数传入后即可获得结果字典或者None。得到结果字典后具体怎么处理就看你接下来的发挥啦。

    本文转载自霍格沃兹测试学院优秀学员ling_tianxia的学习笔记,原文链接:
    http://qrcode.testing-studio.com/f?from=csdn2&url=https://ceshiren.com/tag/%E7%B2%BE%E5%8D%8E%E5%B8%96 转载请注明出处

    展开全文
  • 下面个人学习过程中总结,供个人复习使用,如有理解正确或不足地方希望大家指出。 先上一张脑图: 浏览器中输入url后发生了什么 我将该过程分为了以下六步: 步骤 1. DNS域名解析 在浏览器DNS缓存中搜索...
  • 下面个人学习过程中总结,供个人复习使用,如有理解正确或不足地方希望大家指出。 先上一张脑图: 浏览器中输入url后发生了什么 我将该过程分为了以下六步: 1. DNS域名解析 在浏览器DNS缓存中...
  • 下面个人学习过程中总结,如有理解正确或不足地方希望大家指出。先上一张脑图: 还有个问题:www.baidu.com 键入后,域名怎么知道的是这个IP! 补充个问题:谁和谁建立连接呢? 建立TCP连接,http ...
  • 通俗的理解网址就是常说的URL很多个它一起组成了数量庞大形形色色的网站网址(Uniform Resource Locator)统一资源定位器,计算机Web网络相关的术语,就是网页地址的意思。我们的互联网世界就是由很多的网址组成...
  • 浏览器中输入url后发生了什么

    千次阅读 2017-09-21 10:17:37
    下面个人学习过程中总结,供个人复习使用,如有理解正确或不足地方希望大家指出。 先上一张脑图: 浏览器中输入url后发生了什么 我将该过程分为了以下六步: 1. DNS域名解析 在浏览器DNS缓存中...
  • "兄弟,确实编码问题、当我为ANSI编码,GBK,GB2312等都完全正确、唯独UTF-8时候日期能显示、天气不能显示、天气恰好中文、建议你和sina编码保持一致即可、ps:你能判断到编码问题上,为何不写个编码下测试...
  • 下面个人学习过程中总结,供个人复习使用,如有理解正确或不足地方希望大家指出。 先上一张脑图: 浏览器中输入url后发生了什么 我将该过程分为了以下六步: 1. DNS域名解析 在浏览器DNS缓存中搜索 ...
  • 一直以来在基于springMVC做restful风格的开发。 最近要跟外面做接口,没有restful风格的接口,只有webservice方式。 于是上网恶补webservice的知识,看完之后还是有很多不确定的地方...不知道我上面的理解是否正确
  • 关于REST一点理解

    2020-05-25 11:36:38
    REST 实际上只是一种设计风格,它并不是标准 看Url就知道要什么 看http method就知道干什么 ...1、REST 面向资源的,这个概念非常重要,而资源通过...比如:左边错误的设计,而右边是正确的 GET /rest/api/getDogs -
  • 下面个人学习过程中总结,供个人复习使用,如有理解正确或不足地方希望大家指出。先上一张脑图: 我将该过程分为了以下六步: 1. DNS域名解析 在浏览器DNS缓存中搜索 在操作系统DNS缓存中搜索 ...
  • 随着接触web开发时间增长,自己也对http请求有了自己见解,但都自己理解,不一定十分正确,在此记录下来,方便以后更加深入学习后,用来对比与现在理解差异。 我们都知道,在服务器中需要定义url与视图...
  • Volatile的正确使用

    2008-07-06 21:54:37
    以前就看到过Volatile关键字, 只知道跟多线程同步有关, 但一直没去过问具体含义。 今天想了起来, 查找了一下Volatile相关资料。 就理解而言,看这篇文章就足够了: [url]...一、什么是Vo...
  • 在海康官方在线接口文档中(原文链接:...刚好之前有个朋友问到我,我这里就特意说明一下这句话的正确含义是什么。 误解:视频只能播放5分钟。 正解:取流URL设有有效时间,有效时间为5.
  • 我可以告诉我同事“请查看 yoursite.com/products/Widgets,”,她可能无需再次问我 URL 是什么即可打开该页面。(尝试一下,您只需说出“Amazon.com 页面”即可!)此 URL 还将显示出来,并且应该是“可删节”...
  • <div><h2>开始 从浏览器输入一个 url 开始,到页面完成渲染,...如何确保数据的正确稳定传输呢,“三次握手”中还有别的信息。 <h4>TCP 报文段 先查看一下 TCP 头部的信息,如下图: ...
  • 一、首先得知道服务器配置是什么,有什么用 其实这里配置是用于接收用户在公众号中操作产生事件,比如用户取关了,或者用户关注了,微信服务器会向我们配置的url发送请求,告诉我们当前用户操作,对于这些...
  • ResultFul推荐每个URL能操作具体资源,而且能准确描述服务器对资源处理动作,通常服务器对资源支持get/post/put/delete/等,用来实现资源增删改查,但是通常用浏览器访问资源都GET,增加都POST,而修改和...
  • 什么是数据源? 数据源类似URL,比如 https://gitee.com/mini-bag/picture-bed/blob/master/img/cs.jpeg就可以理解为一张图片源,源并不代表数据本身,而是一个地址。通过数据源可以建立Connection,从而访问...
  • 通过单击上方或以下URL的蓝色徽标来访问此活页夹: 注意:将Internet Explorer用作Web浏览器可能会导致严重的延迟。 关于这些教程的注意事项 这些教程旨在指导您完成执行各种机器学习技术所需的代码。概述了每个步骤...
  • 的理解是它满足了网络共享和数据交互,使用DTD最大的好处在于DTD文件的共享。(就是上文DTD说明语句中的PUBLIC属性)。比如,两个相同行业不同地区的人使用同一个DTD文件来作为文档创建规范,那么他们的数据就很容易...
  • 接口测试一些总结

    2020-10-10 17:46:05
    简单的理解为一个接口就是一个url,可以有参数也可以没有参数,参数可以在url后面也可以在请求体里面,其实你只要理解http协议,就知道接口测试是什么了。 接口功能测试 1.查看接口文档,有哪些入参和出参,没有...
  • 首先根据我的理解,webservice一个跨平台,跨语言的技术,简单来说就是接口和语言没有太大的关系,而且不管你用什么方式发布服务器端接口,客户端只要掌握正确的信息(URL,wsdl等)就可以连接并调用接口。...
  • 问题一:from标签里id属性是什么意思,有name了还要id干什么? 问题二:action里提交地址格式该怎么写?是否是这样子: TomCat中servlet.xml中配置path上下文路径 / web.xml里配置的url-pattern路径 ...
  • 比如说 判断用户输入的是否一个正确的身份证号、判断是否一个有效的URl连接等 总之 他的功能非常的强大 只有想不到 没有配不到 先说一下那道题中我怎么匹配的 先说百家姓 匹配百家姓非常的简单 在txt中 ...
  • 最近一直纠结CSS里面no-repeat后面两个数字的意思,百度上查了好多,发现每个人的理解不一样的,而且在不知道什么意思的情况下,看到不同人的解读,最后依然找不到正确的答案; 研究了很久,在此归纳: 以此为...

空空如也

空空如也

1 2 3 4 5 6
收藏数 102
精华内容 40
关键字:

url的正确的理解是什么