Python正規表現操作--reモジュール

PHP中文网
リリース: 2017-06-20 16:54:09
オリジナル
1528 人が閲覧しました

re模块

序言:

re模块用于对python的正则表达式的操作

'.'     默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
'^'     匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
'$'     匹配字符结尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以
'*'     匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac")  结果为['abb', 'ab', 'a']
'+'     匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']
'?'     匹配前一个字符1次或0次
'{m}'   匹配前一个字符m次
'{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb']
'|'     匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'
'(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c
'[a-z]' 匹配a到z任意一个字符
'[^()]' 匹配除()以外的任意一个字符
 
r' '    转义引号里的字符 针对\字符  详情查看⑦
'\A'    只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的
'\Z'    匹配字符结尾,同$
'\d'    匹配数字0-9
'\D'    匹配非数字
'\w'    匹配[A-Za-z0-9]
'\W'    匹配非[A-Za-z0-9]
'\s'    匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t'
   
&#39;(?P<name>...)&#39; 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city")
结果{&#39;province&#39;: &#39;3714&#39;, &#39;city&#39;: &#39;81&#39;, &#39;birthday&#39;: &#39;1993&#39;}
re.IGNORECASE  忽略大小写 re.search(&#39;(\A|\s)red(\s+|$)&#39;,i,re.IGNORECASE)
ログイン後にコピー

标志位即模式修正符,不改变正则表达式的情况下,通过模式修正符改变正则表达式的含义,从而实现一些匹配结果的调整等功能: 

# flags
I = IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE # ignore case  匹配时忽略大小写
L = LOCALE = sre_compile.SRE_FLAG_LOCALE # assume current 8-bit locale   做本地化识别匹配
U = UNICODE = sre_compile.SRE_FLAG_UNICODE # assume unicode locale       根据Unicode字符及解析字符
M = MULTILINE = sre_compile.SRE_FLAG_MULTILINE # make anchors look for newline   多行匹配
S = DOTALL = sre_compile.SRE_FLAG_DOTALL # make dot match newline      让.匹配包括换行符,即用了该模式修正后,"."匹配就可以匹配任意的字符了
X = VERBOSE = sre_compile.SRE_FLAG_VERBOSE # ignore whitespace and comments
ログイン後にコピー

贪婪模式、懒惰模式:

import re

result1 =  re.search("p.*y","abcdfphp435pythony_py")   # 贪婪模式
print(result1)
# <_sre.SRE_Match object; span=(5, 21), match=&#39;php435pythony_py&#39;>

result2 =  re.search("p.*?y","abcdfphp435pythony_py")   # 懒惰模式
print(result2)
# <_sre.SRE_Match object; span=(5, 13), match=&#39;php435py&#39;>
ログイン後にコピー

  

match:

从起始位置开始根据模型去字符串中匹配指定内容:

#match
import re                               

obj = re.match(&#39;\d+&#39;, &#39;123uua123sf&#39;)       #从第一个字符开始匹配一个到多个数字
print(obj)                                
#<_sre.SRE_Match object; span=(0, 3), match=&#39;123&#39;>

if obj:                                   #如果有匹配到字符则执行,为空不执行
    print(obj.group())                    #打印匹配到的内容
#123
ログイン後にコピー

匹配ip地址:

import re

ip = &#39;255.255.255.253&#39;
result=re.match(r&#39;^([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.&#39;
                r&#39;([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])$&#39;,ip)
print(result)
# <_sre.SRE_Match object; span=(0, 15), match=&#39;255.255.255.253&#39;>
ログイン後にコピー

search:

根据模型去字符串中匹配指定内容(不一定是最开始位置),匹配最前

#search
import  re
obj = re.search(&#39;\d+&#39;, &#39;a123uu234asf&#39;)     #从数字开始匹配一个到多个数字
print(obj)
#<_sre.SRE_Match object; span=(1, 4), match=&#39;123&#39;>

if obj:                                   #如果有匹配到字符则执行,为空不执行
    print(obj.group())                    #打印匹配到的内容
#123


import  re
obj = re.search(&#39;\([^()]+\)&#39;, &#39;sdds(a1fwewe2(3uusfdsf2)34as)f&#39;)     #匹配最里面()的内容
print(obj)
#<_sre.SRE_Match object; span=(13, 24), match=&#39;(3uusfdsf2)&#39;>

if obj:                                   #如果有匹配到字符则执行,为空不执行
    print(obj.group())                    #打印匹配到的内容
#(3uusfdsf2)
ログイン後にコピー

group与groups的区别:

#group与groups的区别
import  re
a = "123abc456"
b = re.search("([0-9]*)([a-z]*)([0-9]*)", a)
print(b)
#<_sre.SRE_Match object; span=(0, 9), match=&#39;123abc456&#39;>
print(b.group())
#123abc456
print(b.group(0))
#123abc456
print(b.group(1))
#123
print(b.group(2))
#abc
print(b.group(3))
#456
print(b.groups())
#(&#39;123&#39;, &#39;abc&#39;, &#39;456&#39;)
ログイン後にコピー

findall:

上述两中方式均用于匹配单值,即:只能匹配字符串中的一个,如果想要匹配到字符串中所有符合条件的元素,则需要使用 findall;findall没有group用法

#findall
import  re
obj = re.findall(&#39;\d+&#39;, &#39;a123uu234asf&#39;)     #匹配多个

if obj:                                   #如果有匹配到字符则执行,为空不执行
    print(obj)                             #生成的内容为列表
#[&#39;123&#39;, &#39;234&#39;]
ログイン後にコピー

sub:

用于替换匹配的字符串(pattern, repl, string, count=0, flags=0)

#sub
import  re

content = "123abc456"
new_content = re.sub(&#39;\d+&#39;, &#39;ABC&#39;, content)
print(new_content)
#ABCabcABC
ログイン後にコピー

split:

根据指定匹配进行分组(pattern, string, maxsplit=0, flags=0)

#split
import  re

content = "1 - 2 * ((60-30+1*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2) )"
new_content = re.split(&#39;\*&#39;, content)       #用*进行分割,分割为列表
print(new_content)
#[&#39;1 - 2 &#39;, &#39; ((60-30+1&#39;, &#39;(9-2&#39;, &#39;5/3+7/3&#39;, &#39;99/4&#39;, &#39;2998+10&#39;, &#39;568/14))-(-4&#39;, &#39;3)/(16-3&#39;, &#39;2) )&#39;]

content = "&#39;1 - 2 * ((60-30+1*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2) )&#39;"
new_content = re.split(&#39;[\+\-\*\/]+&#39;, content)
# new_content = re.split(&#39;\*&#39;, content, 1)
print(new_content)
#["&#39;1 ", &#39; 2 &#39;, &#39; ((60&#39;, &#39;30&#39;, &#39;1&#39;, &#39;(9&#39;, &#39;2&#39;, &#39;5&#39;, &#39;3&#39;, &#39;7&#39;, &#39;3&#39;, &#39;99&#39;, &#39;4&#39;, &#39;2998&#39;, &#39;10&#39;, &#39;568&#39;, &#39;14))&#39;,
#  &#39;(&#39;, &#39;4&#39;, &#39;3)&#39;, &#39;(16&#39;, &#39;3&#39;, "2) )&#39;"]

inpp = &#39;1-2*((60-30 +(-40-5)*(9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2))&#39;
inpp = re.sub(&#39;\s*&#39;,&#39;&#39;,inpp)                #把空白字符去掉
print(inpp)
new_content = re.split(&#39;\(([\+\-\*\/]?\d+[\+\-\*\/]?\d+){1}\)&#39;, inpp, 1)
print(new_content)
#[&#39;1-2*((60-30+&#39;, &#39;-40-5&#39;, &#39;*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))&#39;]
ログイン後にコピー

补充r' ' 转义:

fdfdsfds\fds
sfdsfds& @$
ログイン後にコピー
lzl.py

首先要清楚,程序读取文件里的\字符时,添加到列表里面的是\\

import re,sys
li = []
with open(&#39;lzl.txt&#39;,&#39;r&#39;,encoding="utf-8") as file:
    for line in file:
        li.append(line)
print(li)                   # 注意:文件中的单斜杠,读出来后会变成双斜杠
# [&#39;fdfdsfds\\fds\n&#39;, &#39;sfdsfds& @$&#39;]
print(li[0])                # print打印的时候还是单斜杠
# fdfdsfds\fds
ログイン後にコピー

r字符的意义,对字符\进行转义\只做为字符出现:

import re,sys
li = []
with open(&#39;lzl.txt&#39;,&#39;r&#39;,encoding="utf-8") as file:
    for line in file:
        print(re.findall(r&#39;s\\f&#39;, line))  #第一种方式匹配
        # print(re.findall(&#39;\\\\&#39;, line))  #第二种方式匹配
        li.append(line)
print(li)                   # 注意:文件中的单斜杠,读出来后会变成双斜杠
# [&#39;s\\f&#39;]
# []
# [&#39;fdfdsfds\\fds\n&#39;, &#39;sfdsfds& @$&#39;]
ログイン後にコピー

补充:看完下面的代码你可能更懵了

import re
re.findall(r&#39;\\&#39;, line)  # 正则中只能这样写 不能写成 r&#39;\&#39; 这样
print(r&#39;\\&#39;)            # 只能这样写 不能写成r&#39;\&#39; \只能是双数
# \\        结果
# 如果想值打印单个\ 写成如下
print(&#39;\\&#39;)             # 只能是双数
# \         结果
ログイン後にコピー

总结:文件中的单斜杠\,读出到程序中时是双斜杠\\,print打印出来是单斜杠\;正则匹配文件但斜杠\时,用r'\\'双斜杠去匹配,或者不用r直接用'\\\\'四个斜杠去匹配

compile函数:

说明:

Python通过re模块提供对正则表达式的支持。使用re的一般步骤是先使用re.compile()函数,将正则表达式的字符串形式编译为Pattern实例,
然后使用Pattern实例处理文本并获得匹配结果(一个Match实例),最后使用Match实例获得信息,进行其他的操作
ログイン後にコピー

举一个简单的例子,在寻找一个字符串中所有的英文字符:

import re
pattern = re.compile(&#39;[a-zA-Z]&#39;)
result = pattern.findall(&#39;as3SiOPdj#@23awe&#39;)
print(result)
# [&#39;a&#39;, &#39;s&#39;, &#39;S&#39;, &#39;i&#39;, &#39;O&#39;, &#39;P&#39;, &#39;d&#39;, &#39;j&#39;, &#39;a&#39;, &#39;w&#39;, &#39;e&#39;]
ログイン後にコピー

匹配IP地址(255.255.255.255):  

import re

pattern = re.compile(r&#39;^(([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])$&#39;)
result = pattern.match(&#39;255.255.255.255&#39;)
print(result)
# <_sre.SRE_Match object; span=(0, 15), match=&#39;255.255.255.255&#39;>
ログイン後にコピー

 

以上がPython正規表現操作--reモジュールの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート