精华内容
下载资源
问答
  • IT服务圈儿有温度、有态度IT自媒体平台来源:Python编程时光(ID:Cool-Python)作者:写代码明哥从一段指定字符串中,取得期望数据,正常人都会想到正则表达式吧?写过正则表达式的人都知道,正则表达式入门...
    84c78b99137f2de106f64a3a29a01f7f.png

    IT服务圈儿

    有温度、有态度的IT自媒体平台

    来源:Python编程时光(ID:Cool-Python)作者:写代码的明哥9d2206de27b4d16d15f41543c1ffc0b8.png

    从一段指定的字符串中,取得期望的数据,正常人都会想到正则表达式吧?

    写过正则表达式的人都知道,正则表达式入门不难,写起来也容易。

    但是正则表达式几乎没有可读性可言,维护起来,真的会让人抓狂,别以为这段正则是你写的就可以驾驭它,过个一个月你可能就不认识它了。

    完全可以说,天下苦正则久矣。

    今天给你介绍一个好东西,可以让你摆脱正则的噩梦,那就是 Python 中一个非常冷门的库 --  parse

    1. 真实案例

    拿一个最近使用 parse 的真实案例来举例说明。

    下面是 ovs 一个条流表,现在我需要收集提取一个虚拟机(网口)里有多少流量、多少包流经了这条流表。也就是每个 in_port 对应的 n_bytes、n_packets 的值 。

    cookie=0x9816da8e872d717d, duration=298506.364s, table=0, n_packets=480, n_bytes=20160, priority=10,ip,in_port="tapbbdf080b-c2" actions=NORMAL

    如果是你,你会怎么做呢?

    先以逗号分隔开来,再以等号分隔取出值来?

    你不防可以尝试一下,写出来的代码应该和我想象的一样,没有一丝美感而言。

    我来给你展示一下,我是怎么做的?

    fa7093b5f4fe495b89bba40cfd6aa5b3.png

    可以看到,我使用了一个叫做 parse 的第三方包,是需要自行安装的

    $ python -m pip install parse

    从上面这个案例中,你应该能感受到 parse 对于解析规范的字符串,是非常强大的。

    2. parse 的结果

    parse 的结果只有两种结果:

    1. 没有匹配上,parse 的值为None
    >>> parse("halo""hello"is None
    True
    >>>
    1. 如果匹配上,parse 的值则 为 Result 实例
    >>> parse("hello""hello world")
    >>> parse("hello""hello")
    >>> 

    如果你编写的解析规则,没有为字段定义字段名,也就是匿名字段, Result 将是一个 类似 list 的实例,演示如下:

    >>> profile = parse("I am {}, {} years old, {}""I am Jack, 27 years old, male")
    >>> profile
    'Jack', '27''male') {}>>>> profile[0]'Jack'>>> profile[1]'27'>>> profile[2]'male'

    而如果你编写的解析规则,为字段定义了字段名, Result 将是一个 类似 字典 的实例,演示如下:

    >>> profile = parse("I am {name}, {age} years old, {gender}""I am Jack, 27 years old, male")
    >>> profile
    'gender': 'male''age''27''name''Jack'}>>>> profile['name']'Jack'>>> profile['age']'27'>>> profile['gender']'male'

    3. 重复利用 pattern

    和使用 re 一样,parse 同样支持 pattern 复用。

    >>> from parse import compile
    >>> 
    >>> pattern = compile("I am {}, {} years old, {}")
    >>> pattern.parse("I am Jack, 27 years old, male")
    'Jack', '27''male') {}>>>> >>> pattern.parse("I am Tom, 26 years old, male")'Tom', '26''male') {}>

    4. 类型转化

    从上面的例子中,你应该能注意到,parse 在获取年龄的时候,变成了一个"27" ,这是一个字符串,有没有一种办法,可以在提取的时候就按照我们的类型进行转换呢?

    你可以这样写。

    >>> from parse import parse
    >>> profile = parse("I am {name}, {age:d} years old, {gender}""I am Jack, 27 years old, male")
    >>> profile
    'gender': 'male''age'27'name''Jack'}>>>> type(profile["age"])'int'>

    除了将其转为 整型,还有其他格式吗?

    内置的格式还有很多,比如

    匹配时间

    >>> parse('Meet at {:tg}''Meet at 1/2/2011 11:00 PM')
    2011, 21230),) {}>

    更多类型请参考官方文档:

    TypeCharacters MatchedOutput
    lLetters (ASCII)str
    wLetters, numbers and underscorestr
    WNot letters, numbers and underscorestr
    sWhitespacestr
    SNon-whitespacestr
    dDigits (effectively integer numbers)int
    DNon-digitstr
    nNumbers with thousands separators (, or .)int
    %Percentage (converted to value/100.0)float
    fFixed-point numbersfloat
    FDecimal numbersDecimal
    eFloating-point numbers with exponent e.g. 1.1e-10, NAN (all case insensitive)float
    gGeneral number format (either d, f or e)float
    bBinary numbersint
    oOctal numbersint
    xHexadecimal numbers (lower and upper case)int
    tiISO 8601 format date/time e.g. 1972-01-20T10:21:36Z (“T” and “Z” optional)datetime
    teRFC2822 e-mail format date/time e.g. Mon, 20 Jan 1972 10:21:36 +1000datetime
    tgGlobal (day/month) format date/time e.g. 20/1/1972 10:21:36 AM +1:00datetime
    taUS (month/day) format date/time e.g. 1/20/1972 10:21:36 PM +10:30datetime
    tcctime() format date/time e.g. Sun Sep 16 01:03:52 1973datetime
    thHTTP log format date/time e.g. 21/Nov/2011:00:07:11 +0000datetime
    tsLinux system log format date/time e.g. Nov 9 03:37:44datetime
    ttTime e.g. 10:21:36 PM -5:30time

    5. 提取时去除空格

    去除两边空格

    >>> parse('hello {} , hello python''hello     world    , hello python')
    '    world   ',) {}>>>> >>> >>> parse('hello {:^} , hello python''hello     world    , hello python')'world',) {}>

    去除左边空格

    >>> parse('hello {:>} , hello python''hello     world    , hello python')
    'world   ',) {}>

    去除右边空格

    >>> parse('hello {:, 'hello     world    , hello python')'    world',) {}>

    6. 大小写敏感开关

    Parse 默认是大小写不敏感的,你写 hello 和 HELLO 是一样的。

    如果你需要区分大小写,那可以加个参数,演示如下:

    >>> parse('SPAM''spam')
    >>> parse('SPAM''spam'is NoneFalse>>> parse('SPAM''spam', case_sensitive=Trueis NoneTrue

    7. 匹配字符数

    精确匹配:指定最大字符数

    >>> parse('{:.2}{:.2}''hello')  # 字符数不符
    >>> 
    >>> parse('{:.2}{:.2}''hell')   # 字符数相符
    'he', 'll') {}>

    模糊匹配:指定最小字符数

    >>> parse('{:.2}{:2}''hello'
    'h', 'ello') {}>>>> >>> parse('{:2}{:2}''hello') 'he', 'llo') {}>

    若要在精准/模糊匹配的模式下,再进行格式转换,可以这样写

    >>> parse('{:2}{:2}''1024'
    '10', '24') {}>>>> >>> >>> parse('{:2d}{:2d}''1024') 10, 24) {}>

    8. 三个重要属性

    Parse 里有三个非常重要的属性

    • fixed:利用位置提取的匿名字段的元组
    • named:存放有命名的字段的字典
    • spans:存放匹配到字段的位置

    下面这段代码,带你了解他们之间有什么不同

    >>> profile = parse("I am {name}, {age:d} years old, {}""I am Jack, 27 years old, male")
    >>> profile.fixed
    ('male',)
    >>> profile.named
    {'age'27'name''Jack'}
    >>> profile.spans
    {0: (2529), 'age': (1113), 'name': (59)}
    >>> 

    9. 自定义类型的转换

    匹配到的字符串,会做为参数传入对应的函数

    比如我们之前讲过的,将字符串转整型

    >>> parse("I am {:d}""I am 27")
    27,) {}>>>> type(_[0])'int'>>>> 

    其等价于

    >>> def myint(string):
    ...     return int(string)
    ... 
    >>> 
    >>> 
    >>> parse("I am {:myint}""I am 27", dict(myint=myint))
    27,) {}>>>> type(_[0])'int'>
    >>>

    利用它,我们可以定制很多的功能,比如我想把匹配的字符串弄成全大写

    >>> def shouty(string):
    ...    return string.upper()
    ...
    >>> parse('{:shouty} world''hello world', dict(shouty=shouty))
    'HELLO',) {}>
    >>>

    10 总结一下

    parse 库在字符串解析处理场景中提供的便利,肉眼可见,上手简单。

    在一些简单的场景中,使用 parse 可比使用 re 去写正则开发效率不知道高几个 level,用它写出来的代码富有美感,可读性高,后期维护起代码来一点压力也没有,推荐你使用。

    11d8b2b7d906bc30598d73ca340d59e1.png

    cc3a6a4934fde226f37216593be0153e.png

    ba741991015f5dd646d01d558cf055a8.gif

    • 以 B 站为例,聊聊站内消息系统的设计

    • 国内开发者开源爬虫工具箱爆红GitHub

    • 图解 | 看完这篇还不懂高并发中的线程与线程池,你来打我!

    • 24张图 | 带你彻底理解Java中的21种锁

    *版权声明:转载文章和图片均来自公开网络,版权归作者本人所有,推送文章除非无法确认,我们都会注明作者和来源。如果出处有误或侵犯到原作者权益,请与我们联系删除或授权事宜。

    dbac96d3e562c1bb46b40da62482400d.png

    展开全文
  • “Python猫” ,一个值得加星标的公众号剧照| 《大话西游之大圣娶亲》从一段指定字符串中,取得期望数据,正常人都会想到正则表达式吧?写过正则表达式的人都知道,正则表达式入门不难,写起来也容易。但是正则...

    Python猫” ,一个值得加星标的公众号

    91baf73bacf8511ba1501f9c83631550.png

    剧照 | 《大话西游之大圣娶亲》

    从一段指定的字符串中,取得期望的数据,正常人都会想到正则表达式吧?

    写过正则表达式的人都知道,正则表达式入门不难,写起来也容易。

    但是正则表达式几乎没有可读性可言,维护起来,真的会让人抓狂,别以为这段正则是你写的就可以驾驭它,过个一个月你可能就不认识它了。

    完全可以说,天下苦正则久矣。

    今天给你介绍一个好东西,可以让你摆脱正则的噩梦,那就是 Python 中一个非常冷门的库 --  parse

    1. 真实案例

    拿一个最近使用 parse 的真实案例来举例说明。

    下面是 ovs 一个条流表,现在我需要收集提取一个虚拟机(网口)里有多少流量、多少包流经了这条流表。也就是每个 in_port 对应的 n_bytes、n_packets 的值 。

    cookie=0x9816da8e872d717d, duration=298506.364s, table=0, n_packets=480, n_bytes=20160, priority=10,ip,in_port="tapbbdf080b-c2" actions=NORMAL

    如果是你,你会怎么做呢?

    先以逗号分隔开来,再以等号分隔取出值来?

    你不防可以尝试一下,写出来的代码应该和我想象的一样,没有一丝美感而言。

    我来给你展示一下,我是怎么做的?

    55937005d7da3887a88ca4f3cb8f1cac.png

    可以看到,我使用了一个叫做 parse 的第三方包,是需要自行安装的

    $ python -m pip install parse

    从上面这个案例中,你应该能感受到 parse 对于解析规范的字符串,是非常强大的。

    2. parse 的结果

    parse 的结果只有两种结果:

    1. 没有匹配上,parse 的值为None
    >>> parse("halo""hello"is None
    True
    >>>
    1. 如果匹配上,parse 的值则 为 Result 实例
    >>> parse("hello""hello world")
    >>> parse("hello""hello")
    >>> 

    如果你编写的解析规则,没有为字段定义字段名,也就是匿名字段, Result 将是一个 类似 list 的实例,演示如下:

    >>> profile = parse("I am {}, {} years old, {}""I am Jack, 27 years old, male")
    >>> profile
    'Jack', '27''male') {}>>>> profile[0]'Jack'>>> profile[1]'27'>>> profile[2]'male'

    而如果你编写的解析规则,为字段定义了字段名, Result 将是一个 类似 字典 的实例,演示如下:

    >>> profile = parse("I am {name}, {age} years old, {gender}""I am Jack, 27 years old, male")
    >>> profile
    'gender': 'male''age''27''name''Jack'}>>>> profile['name']'Jack'>>> profile['age']'27'>>> profile['gender']'male'

    3. 重复利用 pattern

    和使用 re 一样,parse 同样支持 pattern 复用。

    >>> from parse import compile
    >>> 
    >>> pattern = compile("I am {}, {} years old, {}")
    >>> pattern.parse("I am Jack, 27 years old, male")
    'Jack', '27''male') {}>>>> >>> pattern.parse("I am Tom, 26 years old, male")'Tom', '26''male') {}>

    4. 类型转化

    从上面的例子中,你应该能注意到,parse 在获取年龄的时候,变成了一个"27" ,这是一个字符串,有没有一种办法,可以在提取的时候就按照我们的类型进行转换呢?

    你可以这样写。

    >>> from parse import parse
    >>> profile = parse("I am {name}, {age:d} years old, {gender}""I am Jack, 27 years old, male")
    >>> profile
    'gender': 'male''age'27'name''Jack'}>>>> type(profile["age"])'int'>

    除了将其转为 整型,还有其他格式吗?

    内置的格式还有很多,比如

    匹配时间

    >>> parse('Meet at {:tg}''Meet at 1/2/2011 11:00 PM')
    2011, 21230),) {}>

    更多类型请参考官方文档:

    TypeCharacters MatchedOutput
    lLetters (ASCII)str
    wLetters, numbers and underscorestr
    WNot letters, numbers and underscorestr
    sWhitespacestr
    SNon-whitespacestr
    dDigits (effectively integer numbers)int
    DNon-digitstr
    nNumbers with thousands separators (, or .)int
    %Percentage (converted to value/100.0)float
    fFixed-point numbersfloat
    FDecimal numbersDecimal
    eFloating-point numbers with exponent e.g. 1.1e-10, NAN (all case insensitive)float
    gGeneral number format (either d, f or e)float
    bBinary numbersint
    oOctal numbersint
    xHexadecimal numbers (lower and upper case)int
    tiISO 8601 format date/time e.g. 1972-01-20T10:21:36Z (“T” and “Z” optional)datetime
    teRFC2822 e-mail format date/time e.g. Mon, 20 Jan 1972 10:21:36 +1000datetime
    tgGlobal (day/month) format date/time e.g. 20/1/1972 10:21:36 AM +1:00datetime
    taUS (month/day) format date/time e.g. 1/20/1972 10:21:36 PM +10:30datetime
    tcctime() format date/time e.g. Sun Sep 16 01:03:52 1973datetime
    thHTTP log format date/time e.g. 21/Nov/2011:00:07:11 +0000datetime
    tsLinux system log format date/time e.g. Nov 9 03:37:44datetime
    ttTime e.g. 10:21:36 PM -5:30time

    5. 提取时去除空格

    去除两边空格

    >>> parse('hello {} , hello python''hello     world    , hello python')
    '    world   ',) {}>>>> >>> >>> parse('hello {:^} , hello python''hello     world    , hello python')'world',) {}>

    去除左边空格

    >>> parse('hello {:>} , hello python''hello     world    , hello python')
    'world   ',) {}>

    去除右边空格

    >>> parse('hello {:, 'hello     world    , hello python')'    world',) {}>

    6. 大小写敏感开关

    Parse 默认是大小写不敏感的,你写 hello 和 HELLO 是一样的。

    如果你需要区分大小写,那可以加个参数,演示如下:

    >>> parse('SPAM''spam')
    >>> parse('SPAM''spam'is NoneFalse>>> parse('SPAM''spam', case_sensitive=Trueis NoneTrue

    7. 匹配字符数

    精确匹配:指定最大字符数

    >>> parse('{:.2}{:.2}''hello')  # 字符数不符
    >>> 
    >>> parse('{:.2}{:.2}''hell')   # 字符数相符
    'he', 'll') {}>

    模糊匹配:指定最小字符数

    >>> parse('{:.2}{:2}''hello'
    'h', 'ello') {}>>>> >>> parse('{:2}{:2}''hello') 'he', 'llo') {}>

    若要在精准/模糊匹配的模式下,再进行格式转换,可以这样写

    >>> parse('{:2}{:2}''1024'
    '10', '24') {}>>>> >>> >>> parse('{:2d}{:2d}''1024') 10, 24) {}>

    8. 三个重要属性

    Parse 里有三个非常重要的属性

    • fixed:利用位置提取的匿名字段的元组
    • named:存放有命名的字段的字典
    • spans:存放匹配到字段的位置

    下面这段代码,带你了解他们之间有什么不同

    >>> profile = parse("I am {name}, {age:d} years old, {}""I am Jack, 27 years old, male")
    >>> profile.fixed
    ('male',)
    >>> profile.named
    {'age'27'name''Jack'}
    >>> profile.spans
    {0: (2529), 'age': (1113), 'name': (59)}
    >>> 

    9. 自定义类型的转换

    匹配到的字符串,会做为参数传入对应的函数

    比如我们之前讲过的,将字符串转整型

    >>> parse("I am {:d}""I am 27")
    27,) {}>>>> type(_[0])'int'>>>> 

    其等价于

    >>> def myint(string):
    ...     return int(string)
    ... 
    >>> 
    >>> 
    >>> parse("I am {:myint}""I am 27", dict(myint=myint))
    27,) {}>>>> type(_[0])'int'>
    >>>

    利用它,我们可以定制很多的功能,比如我想把匹配的字符串弄成全大写

    >>> def shouty(string):
    ...    return string.upper()
    ...
    >>> parse('{:shouty} world''hello world', dict(shouty=shouty))
    'HELLO',) {}>
    >>>

    10 总结一下

    parse 库在字符串解析处理场景中提供的便利,肉眼可见,上手简单。

    在一些简单的场景中,使用 parse 可比使用 re 去写正则开发效率不知道高几个 level,用它写出来的代码富有美感,可读性高,后期维护起代码来一点压力也没有,推荐你使用。

    c0d5cf2be6a761a566253bb09568cc22.gif

    优质文章,推荐阅读:

    我是Redis,MySQL大哥被我害惨了!

    Python 函数为什么会默认返回 None?

    编程语言中花括号 { } 的简明历史

    由浅入深:Python 中如何实现自动导入缺失的库?

    cdecb4949541baf5e35ffc3e3f1a8b0f.png

    感谢创作者的好文30fc7600506b136c458941b81396cfbc.png
    展开全文
  • CDA数据分析师 出品在前两篇连载文章中,我们学习了re模块match()、search()、findall()方法,以及学习了使用正则表达式中常用元字符、限定符、选择字符、中括号来搭配这些方法来灵活处理常见数据匹配问题。...

    e3b4a74ab149f9216aaf1cdad3dceabf.png
    CDA数据分析师 出品

    在前两篇连载文章中,我们学习了re模块的match()、search()、findall()方法,以及学习了使用正则表达式中常用的元字符、限定符、选择字符、中括号来搭配这些方法来灵活处理常见的数据匹配问题。这本篇文章分钟,我们将会进一步学习正则表达式中其他符合,包括令初学者非常头疼的分组问题。

    排除字符

    首先我们回顾一下上一篇连载文章中最后使用的例子:

    pattern='[aA-zZ]+'

    message='企业名称:CDA数据科学研究院n邮箱:1918560461@qq.comn地址:北京市海淀区厂洼街3号2号楼2层n网址:http://www.cda.cnn企业名称:广州就学在线科技有限公司n邮箱:981856661@qq.comn地址:广州市黄埔区护林路1198号516房n网址:http://www.cda.cnn'

    findall = re.findall(pattern, message)

    print(findall)

    out:'CDA', 'qq', 'com', 'www', 'cda', 'cn', 'qq', 'com', 'www', 'cda', 'cn']

    通过模式字符串中的中括号,我们可以匹配到字符串中所有的英文字符串,但是如果反过来说,要提取所有非英文的字符串,如何提取?

    这时,可以使用排除字符"^",放在方括号中,表示排除的意思,只需要将其放在模式字符串的中括号以内的第一个字符位置即可:

    pattern='[^aA-zZ]+'

    message='企业名称:CDA数据科学研究院n邮箱:1918560461@qq.comn地址:北京市海淀区厂洼街3号2号楼2层n网址:http://www.cda.cnn企业名称:广州就学在线科技有限公司n邮箱:981856661@qq.comn地址:广州市黄埔区护林路1198号516房n网址:http://www.cda.cnn'

    findall = re.findall(pattern, message)

    print(findall)

    out:['企业名称:', '数据科学研究院n邮箱:1918560461@', '.', 'n地址:北京市海淀区厂洼街3号2号楼2层n网址:', '.', '.', 'n企业名称:广州就学在线科技有限公司n邮箱:981856661@', '.', 'n地址:广州市黄埔区护林路1198号516房n网址:', '.', '.', 'n']

    这是我们会发现,使用排除字符字符,就连换行符以及逗号等常见的分界符都被提取出来了。

    可以看到,排除字符"^"的实质是把要排除的字符当做分隔符,一一提取要排除的字符。

    令人头疼的分组

    上面讲解了排除字符在正则表达式的中括号所起到的作用,与中括号相比,则表达式里面的小括号,对于很多初学的同学来说简直是噩梦般的存在:无处不在但是其所起到的作用往往让人摸不着头。

    这一方面是由于没有关于这方面的太多的浅显易懂的学习资料,一方面是小括号这符号在正则表达式里面可以表现出两种不同的作用方式。 首先我们看小括号第一种起作用的方式:分组。

    正则表达式里面所说的分组,跟很多编程语言中的groupby操作有着天壤之别。本着由浅入深的精神,我们先举一个简单的例子如下:

    pattern='(six)th'

    message='sixthfourth'

    search=re.search(pattern,message)

    search

    search.group(0)

    search.group(1)

    out:<re.Match object; span=(0, 5), match='sixth'>

    'sixth'

    'six'

    我们发现,使用模式字符串'(six)th'可以匹配出字符串'sixthfourth'中的'sixth'。

    如果调用返回的re.match对象中的.group(n)方法,我们会惊奇第发现search.group(0)返回来的就是第一个匹配出来的对象sixth'。

    search.group(1)返回来的是另外一个匹配对象"six"!。也就是说,带有括号的模式字符串会匹配两次!

    · 第一次是忽略小括号,直接使用模式字符串'sixth'来匹配出'sixth'。

    · 第二次是把模式字符串中的小括号中的字符串'six',当做是子模式字符串进行第二次匹配,得到匹配结果'six'。

    我们可以把括号以内的字符串当做是模式字符串的"子表达式"。

    我们再举个例子,比如我们想要匹配字符串'sixthseventh'中的'six'、'sixth'、'seven'、'seventh'这四个字符串,我们使用re.findall()方法看看效果:

    pattern='(six|seven)th'

    message='sixthseventh'

    findall=re.findall(pattern,message)

    findall

    out:['six', 'seven']

    0c38c86d821766eab33682742a4bb6f6.png

    我们会发现,我们使用了小括号,小括号内部也使用了选择字符"|",小括号右边还有"th",但是依然没有把sixth和seventh匹配出来。

    这其实是一个初学正则表达式的时候很多同学经常踩到的一个"坑",那就是小括号在re.search()起作用的方式和在re.findall()起作用的方式不同。

    re.findall()在识别模式字符串的时候,一旦碰到小括号,就会匹配小括号里面的模式字符串,而小括号以外的模式字符串会被忽略掉。

    在上面的例子当中,模式字符串中的"th"在小括号以外的地方,这就是为什么前面例子当中re.findall()没有把sixth和seventh匹配出来的原因。

    那么这种情况该怎么办?既然re.findall()方法只匹配小括号以内的模式字符串,那么我们可以在前面的模式字符串最外层再嵌套一层小括号就可以了,看效果:

    pattern='((six|seven)th)'

    message='sixthseventh'

    findall=re.findall(pattern,message)

    findall

    out:[('sixth', 'six'), ('seventh', 'seven')]

    我们会发现,'six'、'sixth'、'seven'、'seventh'这四个字符串都匹配上了,而且'sixth', 'six'用一个元组来"打包"在一起。

    运算符优先级问题

    上面的例子其实也可以反映出小括号可以限制选择字符"|"其中用范围,除此以外小括号还可以限定元字符的范围。这其实反映出在正则表达式式里面,小括号的运算符优先级是高于选择字符的,那么,正则表达式的所有运算符的优先级顺序是怎么样的呢?

    我们可以看下表:

    656ef0d407bdd6e8340eaf1ef4988b99.png

    那么,既然正则表达式的小括号的优先级更高,那么又有什么作用?

    我们可以使用它来搭配限定符去匹配一些连续多次重复出现的字符串,且每个字符串自身内部也有相同的规律,比如每次都是连续出现的日期。

    首先举一个简单的例子,比如说我们要匹配特定格式的日期,找到日期字符串规律之后,我们把模式字符串定义为以下形式:

    pattern=r'[0-9]{4}年[0-9]{1,2}月[1-9]{1,2}日'

    message='今天是2020年03月1日,在2019年7月17日发生的一件事,让我记忆犹新'

    findall=re.findall(pattern,message)

    findall

    out:['2020年03月1日', '2019年7月17日']

    可以看到,由于上面出现的日期,其内部都是有规律的,因此我们把日期的这些内部规律写成模式字符串后才把所有日期都匹配出来。但是如果上面例子中的message中的日期有部分出现异常,每次日期都会重复两次出现,比如:

    message='今天是2020年03月1日2020年03月1日,在2019年7月17日2019年7月17日发生的一件事,让我记忆犹新'

    这种就是前面所说的,内部有规律,连续出现的次数也有规律的情况。

    这个时候我们可以把前面的例子中的pattern内部使用小括号"打包在一块",这小括号内的模式字符串其实就相当于用来匹配内部规律,变成这样:

    pattern=r'([0-9]{4}年[0-9]{1,2}月[1-9]{1,2}日)'

    然后在小括号外面的右边添加限定符,比如说异常日期都是连续出现两次,这连续两次也是一种规律,添加限定符{2},变成这样:

    pattern=r'([0-9]{4}年[0-9]{1,2}月[1-9]{1,2}日){2}'

    还没完!连续出现两次这种外部规律还需要用小括号"打包"起来,正如前面一小节给大家提醒,外部连续出现的规律的通过"外部小括号"来匹配,最终pattern变成这样:

    pattern=r'(([0-9]{4}年[0-9]{1,2}月[1-9]{1,2}日){2})'

    我们看一下效果:

    pattern=r'(([0-9]{4}年[0-9]{1,2}月[1-9]{1,2}日){2})'

    message='今天是2020年03月1日2020年03月1日,在2019年7月17日2019年7月17日发生的一件事,让我记忆犹新'

    findall=re.findall(pattern,message)

    findall

    out:[('2020年03月1日2020年03月1日', '2020年03月1日'),

    ('2019年7月17日2019年7月17日', '2019年7月17日')]

    这样子就可以将内部有规律,外部也有连续规律的字符串都匹配出来。

    更多行业干货持续不断分享给大家,可以一直关注我们哟!

    (1)获取更多优质内容,可前往:疫情当下,脚步放慢了,也是提升自己的好时机,为未来蓄能——蓄势待发!

    70402bfc5bbcae622edde2461371ec53.png

    (2)搜索CDA小程序,手机端随时随地浏览最新资讯和优质课程:

    673422760e55f5b00e2ceaf1a252fb37.png
    展开全文
  • 参数如下:参数1:正则表达式参数2:字符串参数3: limit参数一般指定分割多少个数,但是返回数组最后一个[子串]元素将包含所有剩余没有分割部分参数4: 一些默认常量配置、并且可以位或运算 | 进行组合使用。...
    f3e0a1f5f4e07265545e529e8e05bbdc.png

    PHP正则分割函数

    preg_split()函数

    preg_split()  通过一个正则表达式分隔字符串, 返回数组! 参数如下

    参数1:正则表达式

    参数2:字符串

    参数3: limit参数一般指定分割多少个数,但是返回数组的最后一个[子串]元素将包含所有剩余没有分割的部分

    参数4: 一些默认常量的配置、并且可以以位或运算 | 进行组合使用。

    如: PREG_SPLIT_NO_EMPTY如果这个标记被设置, preg_split() 将进返回分隔后的非空部分!

    返回值: 返回通过正则边界分隔字符串后得到的数组!

    特别注意

    被匹配到的分隔字符串不会被返回!

    案例

    0961a78c709ac5be59451e8a77c8ea06.gif

    使用逗号或空格(包含" ", \r, \t, \n, \f)分隔短语,代码如下:

    $pattern='/[\s,]+/';
    $subject='hypertext language, programmimg';
    $result=preg_split($pattern, $subject,3,PREG_SPLIT_NO_EMPTY);
    show($result);

    案例

    0961a78c709ac5be59451e8a77c8ea06.gif

     使用#号字符来分割一个字符串 。比如我们有时候会得到一个路径的字符串 按照一定规则进行连接,我们需要把他们拆分开,得到我们想要的连接数据。代码如下:

    $pattern='/#/';
    $subject='upload/1.jpg#upload/2.jpg#upload/3.jpg#upload/4.jpg#upload/5.jpg#upload/6.jpg';
    $result=preg_split($pattern, $subject,-1,PREG_SPLIT_NO_EMPTY+PREG_SPLIT_OFFSET_CAPTURE);
    show($result);

    案例

    0961a78c709ac5be59451e8a77c8ea06.gif

    匹配div标签,取出div中的内容,代码如下:

    $subject='
    百度 测试数据1
    新浪 测试数据2
    ';
    $pattern='/(
    )|(\s*)/is';
    $result=preg_split($pattern, $subject,-1,PREG_SPLIT_NO_EMPTY);
    show($result);4ca480b2228d9b410fd9e331a959cd01.gif

    "点赞""评论""收藏"

    大家的支持就是我坚持下去的动力!

    如果以上内容有任何错误或者不准确的地方,

    欢迎在下面 留个言指出、或者你有更好的想法,

    欢迎一起交流学习

    关注: 极客小俊 公众号   不定期分享技术干货

    712afceb4ac36c0e7492aee98a7917d6.png

    微信技术交流群   关注群主邀请进群 

    7b1f4c140ef666e88d5aa8b9952e9014.png
    展开全文
  • 参数如下:参数1:正则表达式参数2:字符串参数3: limit参数一般指定分割多少个数,但是返回数组最后一个[子串]元素将包含所有剩余没有分割部分参数4: 一些默认常量配置、并且可以位或运算 | 进行组合使用。...
  • 我需要创建一个正则表达式验证逗号分隔的数值。...的值必须是一个数字,如:1点之前或...我有以下的代码,但它仅检查数字和逗号没有特定的顺序:如何更改下面的正则表达式符合上面的描述?谢谢!// get posted valuei...
  • 我只是想尝试做一个代码,可以做到这一点老式方式。它发现“,并根据它是否是他们之间或他们外面或不替换。$str = '1,"4052","B00K6ED81S",,"Bottle, white - 6,5 l, WENKO","Good design!","Bottle, white 6,5 ...
  • 要搜索以逗号分隔的列表,请使用MySQL find_in_set()。这里不需要为此使用正则表达式。语法如下-select*fromyourTableNamewherefind_in_set(anyValue,yourColumnName);让我们创建一个表-mysql>createtabledemo17...
  • 其实际含义基于一个场景:比如在oracle的某张表中,有两个字段A1 B11 A,B,C,D,2 E,F假如现在的需求,是要统计A1中,每条记录拥有多少个数目的B1,比如A1=1的时候,其B1的字段中有4个以逗号分隔的,所以数目为4,A1=2...
  • 其实际含义基于一个场景:比如在oracle的某张表中,有两个字段A1 B11 A,B,C,D,2 E,F假如现在的需求,是要统计A1中,每条记录拥有多少个数目的B1,比如A1=1的时候,其B1的字段中有4个以逗号分隔的,所以数目为4,A1=2...
  • 现数据库表中某个字段保存值为“01,07,08”,需要sql去查询下表中到相应名称:1、使用find_in_set()...查询字段中包含01,07,08记录:...这SQL,肿么给它拆分开呢,难道再循环一下....2、正则表达式,完美...
  • oracle中通过正则表达式函数处理逗号分隔的字段这个题目的确不大好写,其实际含义基于一个场景:www.2cto.com比如在oracle的某张表中...比如A1=1的时候,其B1的字段中有4个以逗号分隔的,所以数目为4,A1=2的,有E,F...
  • 英文货币数字采用是千位...1)根据千位把相应位置替换成“,”,最后一个逗号为例。解决方法:(?=d{3}$)。var result = "12345678".replace(/(?=d{3}$)/g, ','); console.log(result); //“12345,678”其中...
  • 其实际含义基于一个场景:比如在oracle的某张表中,有两个字段A1 B11 A,B,C,D,2 E,F假如现在的需求,是要统计A1中,每条记录拥有多少个数目的B1,比如A1=1的时候,其B1的字段中有4个以逗号分隔的,所以数目为4,A1=2...
  • (/d+)(,/d+)* 说明: 用于匹配多个数字之间用逗号分隔,且第一个和最后一个字符必须是数字。 例如: ,123 123, 123,123 123,123, k,123 匹配成功为: 123,123 using S...
  • 这个题目的确不大好写,其实际含义基于一个场景: 比如在oracle的某张表中,有两个字段 ...A1=1的时候,其B1的字段中有4个以逗号分隔的,所以数目为4,A1=2的,有 E,F共2个,所有数目为2 ...
  • oracle中通过正则表达式函数处理逗号分隔的字段这个题目的确不大好写,其实际含义基于一个场景:www.2cto.com比如在oracle的某张表中...比如A1=1的时候,其B1的字段中有4个以逗号分隔的,所以数目为4,A1=2的,有E,F...
  • 字符串操作Python有简单易用的字符串和文本处理功能,大...字符串对象方法以逗号分隔的字符串可以用split拆分成数段In [4]: val='a,bc,c, gudio'In [5]: val.split(',')Out[5]: ['a', 'bc', 'c', ' gudio']In [6]...
  • 精通正则表达式(中英)

    热门讨论 2011-09-08 13:18:58
    作为编程语言的正则表达式 4 文件名做类比 4 语言做类比 5 正则表达式的知识框架 6 对于有部分经验的读者 6 检索文本文件:egrep 6 egrep元字符 8 行的起始和结束 8 字符组 9 用点号匹配任意字符 11 多选结构 13...
  • 字符串a和b a="111,222,333,444,555,66,777,8,99,121" b="111,222,333,444,555,66,777,8,99,121...请教各位高人有没有正则可以用,没有话用什么方法效率最高?因为这2个字符串里面字符可能非常非常多 谢谢各位
  • 正则表达式实现千分位分隔

    千次阅读 2018-02-18 22:04:23
    正则实现数字每3位加逗号的表示,如12345678 输出为12,345,678。输入为整数时代码为:num.toString().replace(/(\d)(?=(\d{3})+$)/g,'$1,')将数字num转化为字符串后,全局(/g)正向匹配,看是否符合断言(\d)(?=...
  • 精通正则表达式~~~

    2009-05-07 12:36:48
    作为编程语言的正则表达式... 4 文件名做类比... 4 语言做类比... 5 正则表达式的知识框架... 6 对于有部分经验的读者... 6 检索文本文件:Egrep. 6 Egrep元字符... 8 行的起始和结束... 8 字符组... 9...
  • 除了作为入门教程之外,本文还试图成为可以在日常工作中使用的正则表达式语法参考手册。就作者本人的经历来说,这个目标还是完成得不错的——你看,我自己也没能把所有的东西记下来,不是吗? 恢复格式 文本格式约定...
  • 端口号:以逗号分隔或范围(80,433,53 1-65535)^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])(,([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3...
  • 正则表达式和java解析csv文件 作者:弹着钢琴设计 来源:博客园 发布时间:2009-06-15 ...csv(Comma Separate Values)文件即逗号分隔符文件,它是一种文本文件,可以直接以文本打开,以逗号分隔。windows默认用e

空空如也

空空如也

1 2 3 4 5
收藏数 98
精华内容 39
关键字:

以逗号分隔的正则表达式