1、数据分类

  1. 数据的分类

    ​ 定义:数据以行为单位,每一个数据表示一个实体的信息。每一行数据的属性都是一样的。

    ​ 常见的结构化数据为关系型数据库存储数据。

  2. 半结构化数据

    ​ 定义:结构化数据的另一种形式,但是并不符合关系型数据的特点,不能用关系型模型来描述,但是 这种数据包含相关标记,有用来分隔语义元素以及字段进行分层的描述。因此也被称为自描述结构。

  3. 非结构化数据

    ​ 定义:没有固定的结构的数据。

    ​ 常见的非结构化数据有:文档,图片,音频,视频等。

    ​ 一般非结构化数据,都是通过整体存储他们二进制格式的数据来进行保存。

2、json数据

2.1、json语言概念

​ js中的语言,用来以【字符串】的形式来保存js中的对象和数组的一种技术。

2.2、js中对象和数组的格式
  • js的数组:var names = ["zs", "ls", "ww"]
  • js对象:varuser = {name: "zs", age: 18, height: 170}
2.3、json数据解析
  • json.loads('json字符串') 将json数据转成python对象(dict, list)
  • json.dumps('python对象') 将python对象转成json字符串
2.4、json数据的优势
  • 数据量很小

  • 传输效率高

3、正则表达式

3.1、正则表达式的定义

​ 正则表达式,又称规则表达式,通常被用来检索、替换那些符合某个模式(规则)的文本。

​ 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组

​ 合,组成一个"规则字符串",这个"规则字符串"用来表达对字符串的一种过滤逻辑。

3.2、正则表达式的作用
  • 给定的字符串是否符合正则表达式的过滤逻辑("匹配");
  • 通过正则表达式,从文本字符串中获取我们想要的特定部分("过滤")。
3.3、正则表达式匹配规则

(1)常用的元字符:

语法 说明 表达式实例 完整匹配的字符串
\d 0-9之间的任意数字 a\dc a2c
\D 除了\d a\Dc abc
\w 数字、字母、下划线中任意一种 a\wc abc
\W 除了\w a\Wc a%c
\n 换行
\s 空白或空格 a\sc a c
. 除了\n任意字符
\. \ 转义让.代表自身
\b 单词的边界
^ 开始 ^abc abc
$ 结束 abc$ abc
[\u4e00-\u9fa5] 中文

(3)量词:

语法 说明 表达式实例 完整匹配的字符串
匹配前一个字符0或1次 abc? ab, abc
+ 匹配前一个字符1或多次 abc+ abc, abccc
* 匹配前一个字符0或多次 abc* ab, abccc
{n} 匹配前一个字符n次 ab{2}c abbc
{n,} 匹配前一个字符n-多次 ab{2,}c abbc, abbbbc
{n,m} 匹配前一个字符n-m次 ab{1,2}c abc, abbc

(3)量词:

语法 说明 表达式实例 完整匹配的字符串
| 或者,由于优先级比较低,经常和小括号一起使用 abc|cd
[0-9] 0-9之间任意一个,相当于\d
[xyz] x或y或z
[\d\s] 数字或空白中的一个
[.] 体表.本身
[+-] +-中的一个
[^xyz] 除了x,y,z任意一个字符
3.4、正则表达式的使用步骤
  • 使用 compile() 函数将正则表达式的字符串形式编译为一个 Pattern 对象
  • 通过 Pattern 对象提供的一系列方法对文本进行匹配查找,获得匹配结果,一个 Match 对象。
  • 最后使用 Match 对象提供的属性和方法获得信息,根据需要进行其他的操作
3.5、compile 函数

compile 函数用于编译正则表达式,生成一个 Pattern 对象,它的一般使用形式如下:

import re

# 将正则表达式编译成 Pattern 对象
pattern = re.compile(r'\d+')

Pattern 对象的一些常用方法主要有:

  • match 方法:从起始位置开始查找,一次匹配
  • search 方法:从任何位置开始查找,一次匹配
  • findall 方法:全部匹配,返回列表
  • finditer 方法:全部匹配,返回迭代器
  • split 方法:分割字符串,返回列表
  • sub 方法:替换
3.6、pattern对象中方法
  • 3.6.1、match方法

    默认从开始位置开始匹配,只匹配一次, 只要找到了一个匹配的结果就返回,而不是查找所有匹配的结果。 它的一般使用形式如下:

    match(string[, start, end])

    其中,string 是待匹配的字符串,start 和 end 是可选参数,指定字符串的起始和终点位置,默认值分别是 0 和 len (字符串长度)。因此,当你不指定 start 和 end 时,match 方法默认匹配字符串的头部。

    当匹配成功时,返回一个 Match 对象,如果没有匹配上,则返回 None。

    >>> import re
    >>> pattern = re.compile(r'\d+') # 用于匹配至少一个数字 >>> m = pattern.match('one12twothree34four') # 从头部开始查找,没有匹配
    >>> print (m)
    None >>> m = pattern.match('one12twothree34four', 2, 10) # 从'e'的位置开始匹配,没有匹配到
    >>> print (m)
    None >>> m = pattern.match('one12twothree34four', 3, 10) # 从'1'的位置开始匹配,正好匹配到
    >>> print (m) # 返回一个 Match 对象
    <_sre.SRE_Match object at 0x10a42aac0> >>> m.group(0) # 可省略 0
    '12'
    >>> m.start(0) # 可省略 0
    3
    >>> m.end(0) # 可省略 0
    5
    >>> m.span(0) # 可省略 0
    (3, 5)

    匹配成功时返回一个match对象,其中:

    • group() 方法用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可直接使用 group() 或 group(0);
    • start( ) 方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为 0;
    • end( ) 方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引+1),参数默认值为 0;
    • span( ) 方法返回 (start(group), end(group))。

    >>> import re
    >>> pattern = re.compile(r'([a-z]+) ([a-z]+)', re.I) # re.I 表示忽略大小写
    >>> m = pattern.match('Hello World Wide Web') >>> print (m) # 匹配成功,返回一个 Match 对象
    <_sre.SRE_Match object at 0x10bea83e8> >>> m.group(0) # 返回匹配成功的整个子串
    'Hello World' >>> m.span(0) # 返回匹配成功的整个子串的索引
    (0, 11) >>> m.group(1) # 返回第一个分组匹配成功的子串
    'Hello' >>> m.span(1) # 返回第一个分组匹配成功的子串的索引
    (0, 5) >>> m.group(2) # 返回第二个分组匹配成功的子串
    'World' >>> m.span(2) # 返回第二个分组匹配成功的子串
    (6, 11) >>> m.groups() # 等价于 (m.group(1), m.group(2), ...)
    ('Hello', 'World') >>> m.group(3) # 不存在第三个分组
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    IndexError: no such group
  • 3.6.2、search方法

    用于查找字符串的任何位置,它也是一次匹配,只要找到了一个匹配的结果就返回,而不是查找所有匹配的结果,它的一般使用形式如下:

    search(string[, start, end])

    其中,string 是待匹配的字符串,start 和 end 是可选参数,指定字符串的起始和终点位置,默认值分别是 0 和 len (字符串长度)。

    当匹配成功时,返回一个 Match 对象,如果没有匹配上,则返回 None。

    >>> import re
    >>> pattern = re.compile('\d+')
    >>> m = pattern.search('one12twothree34four') # 这里如果使用 match 方法则不匹配
    >>> m
    <_sre.SRE_Match object at 0x10cc03ac0>
    >>> m.group()
    '12'
    >>> m = pattern.search('one12twothree34four', 10, 30) # 指定字符串区间
    >>> m
    <_sre.SRE_Match object at 0x10cc03b28>
    >>> m.group()
    '34'
    >>> m.span()
    (13, 15)

    再来看一个例子:

    import re
    # 将正则表达式编译成 Pattern 对象
    pattern = re.compile(r'\d+')
    # 使用 search() 查找匹配的子串,不存在匹配的子串时将返回 None
    # 这里使用 match() 无法成功匹配
    m = pattern.search('hello 123456 789')
    if m:
    # 使用 Match 获得分组信息
    print ('matching string:',m.group())
    # 起始位置和结束位置
    print ('position:',m.span())

    执行结果:

    matching string: 123456
    position: (6, 12)
  • 3.6.3、findall方法

    默认从头开始匹配,搜索整个字符串,获取所有匹配的结果。它的一般使用形式如下:

    findall(string[, start, end])

    其中,string 是待匹配的字符串,start 和 end 是可选参数,指定字符串的起始和终点位置,默认值分别是 0 和 len (字符串长度)。

    findall 以列表形式返回全部能匹配的子串,如果没有匹配,则返回一个空列表。

    看看例子:

    import re
    pattern = re.compile(r'\d+') # 查找数字 result1 = pattern.findall('hello 123456 789')
    result2 = pattern.findall('one1two2three3four4', 0, 10) print (result1)
    print (result2)

    执行结果:

    ['123456', '789']
    ['1', '2']

    再先看一个例子:

    import re
    
    pattern = re.compile(r'\d+\.\d*')
    
    #通过partten.findall()方法就能够全部匹配到我们得到的字符串
    result = pattern.findall("123.141593, 'bigcat', 232312, 3.15") #findall 以 列表形式 返回全部能匹配的子串给result
    for item in result:
    print (item)

    运行结果:

    123.141593
    3.15
  • 3.6.4、finditer方法

    finditer 方法的行为跟 findall 的行为类似,也是搜索整个字符串,获得所有匹配的结果。但它返回一个 顺序访问每一个匹配结果(Match 对象)的迭代器。

    看看例子:

    import re
    
    pattern = re.compile(r'\d+')
    
    ret1_iter = pattern.finditer('hello 123456 789')
    ret2_iter = pattern.finditer('one1two2three3four4', 0, 10) print(type(ret1_iter))
    print(type(ret1_iter)) print('----ret1----')
    for m1 in ret1_iter:
    # print(m1) # m1是一个对象
    print('matching string:{},position:{}'.format(m1.group(), m1.span())) print('----ret2----')
    for m2 in ret2_iter:
    # print(m2) # m2是一个对象
    print('matching string:{},position:{}'.format(m2.group(), m2.span()))

    执行结果:

    <class 'callable_iterator'>
    <class 'callable_iterator'>
    ----ret1----
    matching string:123456,position:(6, 12)
    matching string:789,position:(13, 16)
    ----ret2----
    matching string:1,position:(3, 4)
    matching string:2,position:(7, 8)
  • 3.6.5、split方法

    split 方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:

    split(string[, count])

    其中,count 用于指定最大分割次数,不指定将全部分割。

    看看例子

    import re
    
    pattern = re.compile(r'[\s\,\;]+')
    ret = pattern.split('a,b;;c d')
    print(ret)

    执行结果:

    ['a', 'b', 'c', 'd']
  • 3.6.6、sub方法

    sub 方法用于替换。它的使用形式如下:

    sub(repl, string[, count])

    其中,repl 可以是字符串也可以是一个函数:

    • 如果 repl 是字符串,则会使用 repl 去替换字符串每一个匹配的子串,并返回替换后的字符串,另外,repl 还可以使用 id 的形式来引用分组,但不能使用编号 0;
    • 如果 repl 是函数,这个方法应当只接受一个参数(Match 对象),并返回一个字符串用于替换(返回的字符串中不能再引用分组)。
    • count 用于指定最多替换次数,不指定时全部替换。

    看看例子:

    import re
    
    pattern = re.compile(r'(\w+) (\w+)')
    s = 'hello 123, hello 456'
    print(pattern.sub('hello world', s)) # 使用 'hello world' 替换 'hello 123' 和 'hello 456'
    print(pattern.sub(r'\1 \2', s)) # 引用分组 print('-' * 50)
    def fun(m):
    print(m) # 传递参数必须为一个Match对象
    return 'hi' + ' ' + m.group(2) # group(0)表示本身,group(1)表示hello,group(2)表示后面的数字 print(pattern.sub(fun, s)) # 每次sub的结果传递给fun
    print(pattern.sub(fun, s, 1)) # 只替换一次

    执行结果:

    hello world, hello world
    hello 123, hello 456
    ------------------------------------------------------------
    <_sre.SRE_Match object; span=(0, 9), match='hello 123'>
    <_sre.SRE_Match object; span=(11, 20), match='hello 456'>
    hi 123, hi 456
    <_sre.SRE_Match object; span=(0, 9), match='hello 123'>
    hi 123, hello 456
3.7、匹配中文

中文的 unicode 编码范围 主要在 [u4e00-u9fa5] , 这里说主要是因为这个范围并不完整,比如没有包括全角(中文)标点,不过,在大部分情况下,应该是够用的。

假设现在想把字符串 title = u'你好,hello,世界' 中的中文提取出来,可以这么做:

import re

title = '你好,hello,世界'
pattern = re.compile(r'[\u4e00-\u9fa5]+')
result = pattern.findall(title) print (result)

正则表达式前面加上了两个前缀 ur,其中 r 表示使用原始字符串,u 表示是 unicode 字符串。

3.8、贪婪模式与非贪婪模式
  • 婪模式:在整个表达式匹配成功的前提下,尽可能多的匹配 ( * );

  • 非贪婪模式:在整个表达式匹配成功的前提下,尽可能少的匹配 ( ? );

  • Python里数量词默认是贪婪的。

例子一:源字符串:abbbc

  • 使用贪婪的数量词的正则表达式 ab* ,匹配结果: abbb。

* 决定了尽可能多匹配 b,所以a后面所有的 b 都出现了。

  • 使用非贪婪的数量词的正则表达式ab*?,匹配结果: a。

即使前面有 *,但是 ? 决定了尽可能少匹配 b,所以没有 b。

例子二:源字符串:aa<div>test1</div>bb<div>test2</div>cc

  • 使用贪婪的数量词的正则表达式: <div>.*</div>
  • 匹配结果: <div>test1</div>bb<div>test2</div>

这里采用的是贪婪模式。在匹配到第一个</div>时已经可以使整个表达式匹配成功,但是由于采用的是贪婪模式,所以仍然要向右尝试匹配,查看是否还有更长的可以成功匹配的子串。匹配到第二个</div>后,向右再没有可以成功匹配的子串,匹配结束,匹配结果为 <div>test1</div>bb<div>test2</div>


  • 使用非贪婪的数量词的正则表达式 : <div>.*?</div>
  • 匹配结果:<div>test1</div>

正则表达式二采用的是非贪婪模式,在匹配到第一个</div>时使整个表达式匹配成功,由于采用的是非贪婪模式,所以结束匹配,不再向右尝试,匹配结果为<div>test1</div>

day03_正则表达式的更多相关文章

  1. JS正则表达式常用总结

    正则表达式的创建 JS正则表达式的创建有两种方式: new RegExp() 和 直接字面量. //使用RegExp对象创建 var regObj = new RegExp("(^\\s+) ...

  2. Python高手之路【五】python基础之正则表达式

    下图列出了Python支持的正则表达式元字符和语法: 字符点:匹配任意一个字符 import re st = 'python' result = re.findall('p.t',st) print( ...

  3. C# 正则表达式大全

    文章导读 正则表达式的本质是使用一系列特殊字符模式,来表示某一类字符串.正则表达式无疑是处理文本最有力的工具,而.NET提供的Regex类实现了验证正则表达式的方法.Regex 类表示不可变(只读)的 ...

  4. C#基础篇 - 正则表达式入门

    1.基本概念 正则表达式(Regular Expression)就是用事先定义好的一些特定字符(元字符)或普通字符.及这些字符的组合,组成一个“规则字符串”,这个“规则字符串”用来判断我们给定的字符串 ...

  5. JavaScript正则表达式,你真的知道?

    一.前言 粗浅的编写正则表达式,是造成性能瓶颈的主要原因.如下: var reg1 = /(A+A+)+B/; var reg2 = /AA+B/; 上述两个正则表达式,匹配效果是一样的,但是,效率就 ...

  6. Python 正则表达式入门(中级篇)

    Python 正则表达式入门(中级篇) 初级篇链接:http://www.cnblogs.com/chuxiuhong/p/5885073.html 上一篇我们说在这一篇里,我们会介绍子表达式,向前向 ...

  7. 【JS基础】正则表达式

    正则表达式的() [] {}有不同的意思. () 是为了提取匹配的字符串.表达式中有几个()就有几个相应的匹配字符串. (\s*)表示连续空格的字符串. []是定义匹配的字符范围.比如 [a-zA-Z ...

  8. JavaScript 正则表达式语法

    定义 JavaScript定义正则表达式有两种方法. 1.RegExp构造函数 var pattern = new RegExp("[bc]at","i"); ...

  9. [jquery]jquery正则表达式验证(手机号、身份证号、中文名称)

    数字判断方法:isNaN()函数 test()方法 判断字符串中是否匹配到正则表达式内容,返回的是boolean值 ( true / false ) // 验证中文名称 function isChin ...

随机推荐

  1. Linux之Centos7开机之后连不上网

    问题:ns33mtu 1500 qdisc noop state DOWN group default qlen 1000 解决方法: root@topcheer ~]# systemctl stop ...

  2. 在移动硬盘中安装win10和macos双系统

    本文通过在SSD移动硬盘中安装win10和macos双系统,实现操作系统随身携带 小慢哥的原创文章,欢迎转载 目录 ▪ 目标 ▪ 准备工作 ▪ Step1. 清空分区,转换为GPT ▪ Step2. ...

  3. Logstash 安装及简单实用(同步MySql数据到Elasticsearch)(Linux)

    1.下载logstash wget https://artifacts.elastic.co/downloads/logstash/logstash-6.6.0.tar.gz 2. 解压logstas ...

  4. API 网关知识看这篇就足够了!

    本文已经收录自 JavaGuide (60k+ Star[Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识.) 本文授权转载自:https://github.com/java ...

  5. js垃圾回收

    内存生命周期 分配你所需要的内存 使用分配到的内存(读.写) 不需要时将其释放\归还 所有语言第二部分都是明确的.第一和第三部分在底层语言中是明确的,但在像 JavaScript 这些高级语言中,嵌入 ...

  6. 《Effective Java》 读书笔记(九)使用try-with-resources 语句替代try-finally

    这一点其实深有感触.话不多说,先上代码: static String firstLineOfFile(String path) { BufferedReader bufferedReader = nu ...

  7. python之装饰器的两种写法

    上一篇文章介绍了 装饰器的概念.现在讲一下在程序中怎么来写装饰器.上代码: def X(fun): def Y(b): print(b) fun() return Y def test(): prin ...

  8. printf的实现原理

    printf的声明    int _cdecl printf(const char* format, …);    _cdecl是C和C++程序的缺省调用方式 _CDEDL调用约定:    1.参数从 ...

  9. Elasticsearch系列---Elasticsearch的基本概念及工作原理

    基本概念 Elasticsearch有几个核心的概念,花几分钟时间了解一下,有助于后面章节的学习. NRT Near Realtime,近实时,有两个层面的含义,一是从写入一条数据到这条数据可以被搜索 ...

  10. ASP.NET Core 1.0: Deploy to IIS

    尽管ASP.NET最新的官方文档记录了如何Deploy to IIS,但是实际操作起来依旧磕磕绊绊.官方文档地址:https://docs.asp.net/en/latest/publishing/i ...