正则表达式 python 实现

正则表达式

1.原子

2.元字符

3.模式修正

4.贪婪模式

5.懒惰模式

1.原子

原子是正则表达式中最基本的组成单位,每个正则表达式中至少要包含一个原子,
常见的原子有一下几类:

  1. 普通字符作为原子

  2. 非打印字符作为原子

  3. 通用字符作为原子

  4. 原子表

  5. 普通字符作为原子
    一些普通字符,例如:字母,数字,下划线都可以作为原子.

     import re
     pattern = "test" # 普通字符作为原子
     string = "asdfatestsdfasd"
     result1 = re.search(pattern, string)
     print(result1)

     <_sre.SRE_Match object; span=(5, 9), match='test'>
  1. 非打印字符作为原子
    非打印字符就像换行符之类的符号.
     import re
     pattern = '\n'
     string = '''http://baidu.com
test'''
     result1 = re.search(pattern, string)
     print(result1) 

     <_sre.SRE_Match object; span=(16, 17), match='\n'>
     #!/usr/bin/env python3
     import re
     pattern = '\n'
     string = '''http://baidu.com
     test
     test'''
     result1 = re.search(pattern, string)
     print(result1)
     
     <_sre.SRE_Match object; span=(16, 17), match='\n'>
 但是即使有多个换行符也只能匹配到一个.
  1. 通用字符作为原子
    通用字符可以匹配一类字符,经常用到.
符号 含义
\w 匹配任意一个字母,数字或下划线
\W 匹配除字母,数字或下划线以外的任意一个字符
\d 匹配任意一个十进制数
\D 匹配除十进制数外的任意一个 其他字符
\s 匹配任意一个空白字符
\S 匹配除空白字符以外的任意一个字符
#!/usr/bin/env python3
import re

string1 = 'asdfas234234234python234234_py'
string2 = 'asdfas234234234\npython234234_py'

pattern1 = '\w\dpython'
pattern2 = '\Wpython'
pattern3 = '\dpython'
pattern4 = '\Dpython'
pattern5 = '\s'
pattern6 = '\S'

result1 = re.search(pattern1, string1)
result2 = re.search(pattern2, string2)
result3 = re.search(pattern3, string1)
result4 = re.search(pattern4, string1)
result5 = re.search(pattern5, string2)
result6 = re.search(pattern6, string2)

print(result1)
print(result2)
print(result3)
print(result4)
print(result5)
print(result6)

    <_sre.SRE_Match object; span=(13, 21), match='34python'>
<_sre.SRE_Match object; span=(15, 22), match='\npython'>
<_sre.SRE_Match object; span=(14, 21), match='4python'>
None
<_sre.SRE_Match object; span=(15, 16), match='\n'>
<_sre.SRE_Match object; span=(0, 1), match='a'>
  1. 原子表
    使用原子表,可以定义一组地位平等的原子,然后匹配时会去该原子表中的任意一个原子
    进行匹配,在python中,原子表由[]表示,例如[xyz]就是一个原子表,在这个原子表中定义
    了3个原子,这3个原子的地位平等,如
#!/usr/bin/env python3
import re

string1 = 'asdfas234234234python234234_py'

pattern1 = '[1234]python'
pattern2 = '[opq]ython'

result1 = re.search(pattern1, string1)
result2 = re.search(pattern2, string1)

print(result1)
print(result2)
 类似的,[^]代表的是除了中括号里面的原子均可以匹配,比如
#!/usr/bin/env python3
import re

string1 = 'asdfas234234234pythony234234_py'

pattern1 = '\w\dpython[xyz]\w'
pattern2 = '\w\dpython[^xz]\w'
pattern3 = '\w\dpython[xyz]\W'

result1 = re.search(pattern1, string1)
result2 = re.search(pattern2, string1)
result3 = re.search(pattern3, string1)

print(result1)
print(result2)
print(result3)

<_sre.SRE_Match object; span=(13, 23), match='34pythony2'>
<_sre.SRE_Match object; span=(13, 23), match='34pythony2'>
None

2.元字符
元字符就是正则表达式中含有一些特殊意义的字符,比如重复N次前面的字符
元字符可以分成五类:

  1. 任意匹配元字符 如:"."
  2. 边界限制元字符 如:"^"和"$"
  3. 限定符 如:"*","?","+","{n}","{n,}","{n,m}"
  4. 模式选择符 如:"|"
  5. 模式单元符 如:"()"
    常见的元字符及含义
符号 含义
. 匹配除换行符以外的任意字符
^ 匹配字符串的开始位置
$ 匹配字符串的结束位置
* 匹配0次,1次或多次前面的原子
? 匹配0次或1次前面的原子
+ 匹配1次或多次前面的原子
{n} 前面的原子恰好出现n次
{n,} 前面的原子至少出现n次
{n,m} 前面的原子至少出现n次,最多出现m次
| 模式选择符,匹配时可以任意选择一个模式匹配
() 模式单元符,将一些原组合成一个大原子使用

一些使用例子:

  #!/usr/bin/env python3
  import re
  pattern = '.python...'
  string = 'bacdefphp345python_py'
  result = re.search(pattern, string)
  print(result)

  <_sre.SRE_Match object; span=(11, 21), match='5python_py'>
 ------------------------------------------------------------- 
  #!/usr/bin/env python3
  import re
  pattern1 = '^abd'   # 从字符串的开始去找abd
  pattern2 = '^abc'   # 从字符串的开始去找abc
  pattern3 = 'py$'    # 从字符串的结尾去找py
  pattern4 = 'ay$'    # 从字符串的尾部去找ay
  string = 'abcdfphp345python_py'
  result1 = re.search(pattern1, string)
  result2 = re.search(pattern2, string)
  result3 = re.search(pattern3, string)
  result4 = re.search(pattern4, string)
  print(result1)
  print(result2)
  print(result3)
  print(result4)
 
  None
  <_sre.SRE_Match object; span=(0, 3), match='abc'>
  <_sre.SRE_Match object; span=(18, 20), match='py'>
  None
 -------------------------------------------------------------  
  #!/usr/bin/env python3
  import re
  pattern1 = 'py.*n'   
  pattern2 = 'cd{2}'
  pattern3 = 'cd{3}'
  pattern4 = 'cd{2,}'
  string = 'abcdddfphp345pythony_py'
  result1 = re.search(pattern1, string)
  result2 = re.search(pattern2, string)
  result3 = re.search(pattern3, string)
  result4 = re.search(pattern4, string)
  print(result1)
  print(result2)
  print(result3)
  print(result4)

  <_sre.SRE_Match object; span=(13, 19), match='python'>
  <_sre.SRE_Match object; span=(2, 5), match='cdd'>
  <_sre.SRE_Match object; span=(2, 6), match='cddd'>
  <_sre.SRE_Match object; span=(2, 6), match='cddd'>
 -------------------------------------------------------------
  #!/usr/bin/env python3
  import re
  pattern1 = 'python|php'   
  string = 'abcdddfphp345pythony_py'
  result1 = re.search(pattern1, string)
  print(result1)

  <_sre.SRE_Match object; span=(7, 10), match='php'>
 -------------------------------------------------------------
  #!/usr/bin/env python3
  import re
  pattern1 = '(cd){1,}'   
  pattern2 = 'cd{1,}'
  string = 'abcdcdcddfphp345pythony_py'
  result1 = re.search(pattern1, string)
  result2 = re.search(pattern2, string)
  print(result1)
  print(result2)

  <_sre.SRE_Match object; span=(2, 8), match='cdcdcd'>
  <_sre.SRE_Match object; span=(2, 4), match='cd'>
 -------------------------------------------------------------
符号 含义
I 匹配时忽略大小写
M 多行匹配
L 做本地化识别匹配
U 根据Unicode字符及解析字符
S 让.匹配包含换行符,即用修正模式,"."可以匹配任意字符

3.模式修正
模式修正符:可以在不改变正则表达式的情况下,通过模式修正符改变正则表达式的含义,
从而实现一些匹配结果的调整等功能.
常见模式修正符

符号 含义
I 匹配时忽略大小写
M 多行匹配
L 做本地化识别匹配
U 根据Unicode字符及解析字符
S 让.匹配包含换行符,即用修正模式,"."可以匹配任意字符
  #!/usr/bin/env python3
  import re
  pattern1 = 'python'   
  pattern2 = 'python'
  pattern3 = 'Pythony.'
  string = 'abcdfphp345Pythony_py'
  result1 = re.search(pattern1, string)
  result2 = re.search(pattern2, string, re.I)
  result3 = re.search(pattern3, string, re.S)
  print(result1)
  print(result2)
  print(result3)

  None
  <_sre.SRE_Match object; span=(11, 17), match='Python'>
  <_sre.SRE_Match object; span=(11, 19), match='Pythony_'>

4.贪婪模式与懒惰模式
贪婪模式就是尽可能多的匹配
懒惰模式就是尽可能少的匹配

  #!/usr/bin/env python3
  import re
  pattern1 = 'p.*y'   
  pattern2 = 'p.*?y'
  string = 'abcdfphp345Pythony_py'
  result1 = re.search(pattern1, string)
  result2 = re.search(pattern2, string)
  print(result1)
  print(result2)
  
  <_sre.SRE_Match object; span=(5, 21), match='php345Pythony_py'>
  <_sre.SRE_Match object; span=(5, 13), match='php345Py'>

正则表达式常见函数:re.match(), re.search(), 全局匹配函数, re.sub()

  1. re.match()
    从源字符串的起始位置匹配一个模式,我们可以使用re.match()
    re.match(pattern, string, flag)
    pattern:对应的表达式
    string: 源字符串
    flag: 可选,对应的标志位,可放模式修正符
   import re
   string = 'apythonhellomypythonhispythonourpythonend'
   pattern = '.python'
   result = re.match(pattern, string)
   result2 = re.match(pattern, string).span()
   print(result)
   print(result2) 
   
   <_sre.SRE_Match object; span=(0, 7), match='apython'>
   (0, 7)
  1. re.search()
    使用该函数进行匹配,会扫描整个字符串进行对应的匹配. re.match()从源字符串的
    开头进行匹配,而re.search()会在全文进行检索并匹配.
   import re
   string = 'hellomypythonhispythonourpythonend'
   pattern = '.python.'
   result = re.match(pattern, string)
   result2 = re.search(pattern, string)
   print(result)
   print(result2)

   None
   <_sre.SRE_Match object; span=(6, 14), match='ypythonh'>

re.mathc()从头开始匹配,而开头不符合正则表达式,所以返回None

  1. 全局匹配函数
    前面两个函数即使源字符串中多个结果符合模式,也只会返回一个结果.
    怎么把所有的内容全部匹配出来?
    思路如下:
    1. 使用re.compile()对正则表达式进行编译
    2. 编译后,使用findall()根据正则表达式从源字符串中将匹配结果全部找出
   import re
   string = 'hellomypythonhispythonourpythonend'
   pattern = re.compile('.python.') # 预编译
   result = pattern.findall(string) # 找出符合模式的所有结果
   print(result) 
   
   ['ypythonh', 'spythono', 'rpythone']

也可以将两步合并到一步

   import re
   string = 'hellomypythonhispythonourpythonend'
   result = re.compile('.python.').findall(string) # 找出符合模式的所有结果
   print(result)

   ['ypythonh', 'spythono', 'rpythone']
  1. re.sub()
    用来实现字符串替换功能
    re.sub(pattern, rep, string, max)
    pattern: 正则表达式
    rep: 为要替换成的字符串
    string: 源字符串
    max: 为可选项,代表最多替换的次数,如果忽略不写,则会将符合模式的结果全部替换
   import re
   string = 'hellomypythonhispythonourpythonend'
   pattern = 'python.'
   result = re.sub(pattern, 'php', string)  # 全部替换
   result2 = re.sub(pattern, 'php', string, 2)      # 最多替换2次
   print(result)
   print(result2)

   hellomyphpisphpurphpnd
   hellomyphpisphpurpythonend
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355

推荐阅读更多精彩内容