1. 一个列表中所有的数字都是重复2次,但是有一个数字只重复了一次。
请找出重复一次的数字,不可以使用内置函数。
[2,2,1,1,0,4,3,4,3]
方法1:通过字典计数,找到value等于1的key
s = [2,2,1,1,0,4,3,4,3]
m = {}
for i in s:
if i in m:
m[i]+=1
else:
m[i] = 1
print(m)
for k,v in m.items():
if v ==1:
print (k)
#运行结果:
#{2: 2, 1: 2, 0: 1, 4: 2, 3: 2}
#0
方法2:使用排序,判断在头、中、尾三种情况
s = [2,2,1,1,0,4,3,4,3]
s = sorted(s)
for i in range(len(s)):
if i == 0 and s[1] !=s[0]:
print(s[0])
break
elif i == lens(s)-1 and s[i] s=s[i-1]:
print(s[i])
else:
if i!=len(s)-1 and i!=0 and s[i]!=s[i+1] and s[i]!=s[i-1]:
print(s[i])
break
#运行结果:
#0
方法3:使用内置函数append和remove
s = [2,2,1,1,0,4,3,4,3,0,-1]
relist = []
for i in s:
if i in relist:
relist.remove(i)
else:
relist.append(i)
print(relist[0])
#运行结果:
#-1
方法4:使用字典,优点:哈希查找,速度快
s = [2,2,1,1,0,4,3,4,3,0,-1]
redict = {}
for i in s:
try:
redict[i] +=1
del redict[i]
except:
redict[i] = 1
print(redict.keys())
#运行结果:
#dict_keys([-1])
print(list(redict.keys()))
#运行结果:
#[-1]
print(list(redict.keys())[0])
#运行结果:
#-1
输出结果时,换个方法:
print(redict) #查看redict中的内容
#{-1: 1}
print(dir(redict)) #查看字典可用的方法
#['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
print(redict.popitem()) #使用pop.item方法,将字典转换为tuple,且在源字典中删除该组
#(-1, 1)
print(redict) #再次查看redict,已经变成空,因为redict中只有一个key和value
{}
print(redict.popitem()[0])#所以,要将所有代码写在一起,防止pop后在取值取不到报错
-1
d = {1:2,3:4} #有两组key和value的字典
print(d.popitem())
#(3, 4) #popitem出来的是第二组的key和value
print(d)
#{1: 2} #再次查看原字典,只留下未pop的数据
print(d.popitem())
#(1, 2)
2. 写个程序可以处理下面的情况
Example 1:
Input: s = "leetcode", wordDict = ["leet", "code"]
Output: true
Explanation: Return true because "leetcode" can be segmented as "leet code".
Example 2:
Input: s = "applepenapple", wordDict = ["apple", "pen"]
0utput: true
Explanation: Return true because " applepenapple" can be segmented as "apple pen apple".
Note that you are allowed to reuse a dictionary word.
Example 3:
Input: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
Output: false
方法1:
import re
s = "leetcode"
word_dict = ["leet","code"]
pattern = re.compile("("+"|".join(word_dict)+")")
print(pattern)
#re.compile('(leet|code)')
result = pattern.findall(s)
print(result)
#['leet', 'code']
print(len("".join(result))==len(s))
#True
import re
s = "leetcodex"
word_dict = ["leet","code"]
pattern = re.compile("("+"|".join(word_dict)+")")
print(pattern)
#re.compile('(leet|code)')
result = pattern.findall(s)
print(result)
#['leet', 'code']
print(len("".join(result))==len(s))
#False
方法2:
import re
s = "leetcode"
word_dict = ["leet","code"]
result = s
for i in word_dict:
result = "".join(re.split(i,result))
print(result == "")
#True
import re
s = "leetcodex"
word_dict = ["leet","code"]
result = s
for i in word_dict:
result = "".join(re.split(i,result))
print(result == "")
#False
一、正则表达式
1、正则表达式 – 后向引用
正则表达式中,放在圆括号”()”中的表示是一个分组。然后我们就可以对整个组使用一些正则操作,例如重复操作符。
要注意的是,只有”()”才能形成分组,””用于定义字符串,而“{}”用于定义重复操作。当用”()”定义了一个正则表达式分组后,正则引擎就会把匹配的组按照顺序进行编号,然后存入缓存中。这样我们就可以在后面对已经匹配过的内容进行引用,这就叫后向引用。
1. 通过索引引用
数字
1表示引用第一个分组,2引用第二个分组,以此类推,而 则表示引用整个被匹配的正则表达式本身。
2. 通过命名分组名进行引用(如果有的话)
(?P=name)
字符P必须是大写的P,name表示命名分组的分组名。
注意:
这些引用都必须是在正则表达式中才有效,用于匹配一些重复的字符串。
1) 通过默认分组编号进行后向引用
import re
s = "22 22 aa"
print(re.search(r"(d{2}) 1",s).group()) #1的意思是必须匹配和第一个分组匹配一样的内容
#22 22 #后向引用,引用了分组1
s = "22 aa 22"
print(re.search(r"(d{2}) 1",s).group())
#AttributeError: 'NoneType' object has no attribute 'group'
s = "22 21 22"
print(re.search(r"(d{2}) 1",s).group()) #虽然21满足d{2},但是21和22的内容不一样,即
1匹配到的内容和d{2}匹配到的内容不一样,所以未匹配成功
#AttributeError: 'NoneType' object has no attribute 'group'
1表示第一个分组匹配到的内容
2) 通过命名分组进行后向引用
import re
res = re.search(r'(?P<name>go)s+(?P=name)s+(?P=name)', 'go go go')
print(res.group())
#go go go
3) 交换字符串的位置
import re
s = "abc.xyz"
res = re.sub(r"(.*).(.*)",r"2.1",s)
print(res)
#xyz.abc
2、正则表达式 – 前向肯定断言与后向肯定断言
前向肯定断言的语法:
(?<=pattern)
前向肯定断言表示你希望匹配的字符串前面是pattern匹配的内容时,才匹配
后向肯定断言的语法是:
(?=pattern)
后向肯定断言表示你希望匹配的字符串是后面是pattern匹配的内容时,才匹配
import re
print(re.search(r"(?<=abc)d+","abc123").group())#匹配前面是abc的多个数字
#123
print(re.search(r"(?<=abc)d+","a1c123").group())
#AttributeError: 'NoneType' object has no attribute 'group'
print(re.search(r"d+(?=abc)","123abc").group()) #匹配后面是abc的多个数字
#123
print(re.search(r"d+(?=abc)","123a1c").group())
#AttributeError: 'NoneType' object has no attribute 'group'
前向肯定断言括号中的正则表达式必须是能确定长度的正则表达式,比如W{3},而不能写成w*或者w+或者w?等这种不能确定个数的正则模式符。
import re
s = "aaa111aaa,bbb222,333ccc"
print(re.findall(r"(?<=[a-z]{3})d+(?=[a-z]+)",s)) #指定前后肯定断言
#['111']
print(re.findall(r"(?<=[a-z]{3})d+",s)) #指定前向肯定断言
#['111', '222']
print(re.findall(r"d+(?=[a-z]+)",s)) #指定后向肯定断言
#['111', '333']
print(re.findall(r"[a-z]+d+[a-z]+",s)) #普通匹配方法
#['aaa111aaa']
try:
matchResult = re.findall(r"(?<=[a-]+)d+(?=[a-z+])",s)#前向肯定未固定宽度
except Exception as e:
print(e)
else:
print(matchResult)
#look-behind requires fixed-width pattern #前向匹配需要固定宽度的匹配模式
3、正则表达式 – 前向否定断言与后向否定断言
前向否定断言的语法:
(?<!pattern)
前向否定断言表示你希望匹配的字符串的前面不是pattern匹配的内容时,才匹配。
后向否定断言的语法:
后向否定断言表示你希望匹配的字符串的后面不是pattern匹配的内容时,才匹配。
和前向肯定断言一样,前向否定断言括号中的正则表达式必须是能确定长度的正则表达式,比如W{3},而不能写成w*或者w+或者w?等这种不能确定个数的正则模式符。
import re
s = "aaa111aaa,bbb222,333ccc"
print(re.findall(r"(?<![a-z]{3})d+(?![a-z]+)",s)) #指定前后否定断言
#['1', '22', '33']
print(re.findall(r"(?<![a-z]{3})d+",s)) #指定前向否定断言
#[['11', '22', '333']
print(re.findall(r"d+(?![a-z]+)",s)) #指定后向否定断言
#['11', '222', '33']
print(re.findall(r"[a-z]+d+[a-z]+",s)) #普通匹配方法
#['aaa111aaa']
try:
matchResult = re.findall(r"(?<![a-]+)d+(?![a-z+])",s)#前向否定断言未确定长度
except Exception as e:
print(e)
else:
print(matchResult)
#look-behind requires fixed-width pattern
===============================================================
二、JSON
1、使用Python语言来编码和解码JSON对象
Python的json模块序列化和反序列化分别是dumps和loads
json.dumps():将一个Python对象编码成JSON字符串
json.loads():将JSON格式字符串解码成Python对象
对简单的数据类型可以直接处理。如:string,Unicode,int,float,list,tuple,dict
2、JSON简介
JSON:JavaScript Object Notation(JavaScript对象表示法)
JSON:是存储和交换文本信息的语法。类似XML(存储数据的格式,有格式的存储数据)
JSON比XML更小、更快,更易解析。
3、JSON语法与语法规则
1) JSON语法:
JSON语法是JavaScript语法的子集。
2) JSON语法规则:
JSON语法是JavaScript对象表示法语法的子集。
1. 数据在名称/值对中
2. 数据由逗号分隔
3. 花括号保存对象
4. 方括号保存数组
4、JSON名称/值对
Json数据的书写格式是:
名称/值对
名称/值对包括字段名称,后面写一个冒号,然后是值,比如:
“firstName”:”John”
等价于下面这条JavaScript语句:
firstName = “John”
JSON值可以是:
数字(整数或浮点数)
字符串(在双引号中)
逻辑值(true 或false),区别于Python的True和False
数组(在方括号中)
对象(在花括号中)
null
5、JSON对象
JSON对象是在花括号中书写的。对象可以包含多个名称/值对。比如:
{“firstName”:”John”,”lastName”:”Doe”}
这等价于JavaScript语句:
firstName = “John”
lastName = “Doe”
6、JSON数组
JSON数组是在方括号中书写的。数组可以包含多个对象。比如:
a = {
"employees":[
{"firstName":"John","lastName":"Doe"},
{"firstName":"Anna","lastName":"Smith"},
{"firstName":"Peter","lastName":"Jones"}
]
}
print(a)
在上面的例子中,对象”employees”是包含三个对象的数组。每个对象代表一条关于某人(有姓和名)的记录。
7、JSON解码:
1)将json格式字符串解码成Python对象,我们使用的是json.loads()函数,可以将
简单数据类型解码成Python对象。
json.loads #将json串转换为dict类型
>>> s = '{"name":"hehe","age":"18"}' #s定义了一个json串
>>> print(s)
{"name":"hehe","age":"18"}
>>> print(type(s)) #json串的数据类型是str
<class 'str'>
>>> import json #引入json包
>>> json.loads(s) #json.loads(s)将json串转换为dict类型
{'name': 'hehe', 'age': '18'}
>>> print(type(json.loads(s))) #查看json.loads后的数据类型,是dict
<class 'dict'>
>>> s #查看经过json.loads后的s是否有变化
'{"name":"liuyujing","age":"18"}' #s没有变化
>>> s1 = json.loads(s)
>>> print(type(s1))
<class 'dict'>
>>> print(s) #s是str类型,但是print(s)是没有””的
{"name":"liuyujing","age":"18"}
>>> print(type(s))
<class 'str'>
>>> s #交互模式下,直接s会显示’’
'{"name":"liuyujing","age":"18"}'
>>> data = [{'a':"Aasdf",'b':(2,4),'c':3.0}] #原始数据中有tuple(2,4)
>>> json.dumps(data)
'[{"a": "Aasdf", "b": [2, 4], "c": 3.0}]' #经过json编码后,变成了JSON的数组
>>> json.loads(json.dumps(data)) #经过json解码后,原tuple类型转化成list类型
[{'a': 'Aasdf', 'b': [2, 4], 'c': 3.0}]
#编码过程中,Python中的list和tuple都被转化成json的数组,而解码后,json的数组最终转化为Python的list,无论原来是list还是tuple。
2)从json到Python的类型转化
JSON字符串类型 |
Python类型 |
object |
dict |
array |
list |
string |
unicode |
number(int) |
int |
uumber(real) |
float |
true |
True |
false |
False |
null |
None |
>>> a = [{1:12, 'a':12.3}, [1,2,3], (1,2), 'asd', 'ad', 12, 13, 3.3,True,False,None]
>>> json.dumps(a)
'[{"1": 12, "a": 12.3}, [1, 2, 3], [1, 2], "asd", "ad", 12, 13, 3.3, true, false, null]'
>>> json.loads(json.dumps(a))
[{'1': 12, 'a': 12.3}, [1, 2, 3], [1, 2], 'asd', 'ad', 12, 13, 3.3, True, False, None]
注意:
json格式的字符串解码成Python对象以后,String类型都变成了Unicode类型,数组变成了list,不会回到原来的元祖类型,字典key的字符类型也被转成Unicode类型。
8、JSON编码
1). 使用json.dumps()方法来将一个Python数据类型列表编码成json格式的字符串。
json.dumps() #将dict类型,转换为json串
>>> print(json.dumps(s1)) #在上面已说明,s1是字典类型
{"name": "liuyujing", "age": "18"}
>>> type(s1)
<class 'dict'>
>>> s2 = json.dumps(s1) #json.dumps()将字典类型转换为json串
>>> print(s2)
{"name": "liuyujing", "age": "18"}
>>> print(type(s2))
<class 'str'>
>>> s2
'{"name": "liuyujing", "age": "18"}'
2)从Python到JSON字符串类型转化
>>> import json
>>> data = [{'a':"A",'b':(2,4),'c':3.0}]
>>> res = repr(data) #有什么用?
>>> print("data :", res)
data : [{'a': 'A', 'b': (2, 4), 'c': 3.0}]
>>> data_json = json.dumps(data)
>>> print(data_json)
[{"a": "A", "b": [2, 4], "c": 3.0}]
#观察两次打印的结果,会发现Python对象被转成JSON字符串以后,跟原始的repr()输出的结果会有些特殊的变化,原字典中的元祖被改成了json类型的数组。
在json编码的过程中,会存在从Python原始类型转化json类型的过程,但这两种语言的类型存在一些差异,对照表如下:
Python类型 |
JSON字符串类型 |
dict |
object |
list,tuple |
array |
str,Unicode |
string |
int,long,float |
number |
True |
true |
False |
flase |
None |
null |
json.dumps支持将以上Python类型转换为JSON字符串类型
>>> json.dumps({1:2}) #会自动将dict的key值加上””
'{"1": 2}'
>>> json.loads(json.dumps({1:2})) #loads后,原dict中的key值的””依然存在
{'1': 2}
>>> json.dumps([1,2]) #将list转换为数组(array)
'[1, 2]'
>>> json.dumps((1,2)) #将tuple转化为数组(array)
'[1, 2]'
>>> json.dumps(["hehe"])
'["hehe"]'
>>> json.dumps(["1",2,{1:2},("asx")])
'["1", 2, {"1": 2}, "asx"]' #依次将list中的每个元素转换为对应的JSON字符串类型
>>> json.dumps(["1",2,{1:2},("asx","jing")])
'["1", 2, {"1": 2}, ["asx", "jing"]]'
>>> type(("asx"))
<class 'str'>
>>> json.dumps(True)
'true'
>>> json.loads(json.dumps(True))
True
>>> json.dumps(False)
'false'
>>> json.loads(json.dumps(False))
False
>>> json.dumps(None)
'null'
>>> json.loads(json.dumps(None))#无返回值
>>>
>>> print(json.loads(json.dumps(None)))
None
3) Json.dumps()
函数原型
9、eval #将json串转换为dict
>>> s #s是个json串
'{"name":"liuyujing","age":"18"}'
>>> eval(s) #eval()可以将json串转换为dict
{'name': 'liuyujing', 'age': '18'}
>>> s #经过eval后的s没有什么变化
'{"name":"liuyujing","age":"18"}'
>>> print(type(eval(s))) #eval()可以将json串转换为dict
<class 'dict'>
10、json编码
函数原型:
dumps(obj, skipkeys = False, ensure_ascii= True, check_circular=True, allow_nan = True, cls = None, indent = None, separators = None, encoding = “utf- 8”, default = None,sort_keys = False, **kw)
该方法返回编码后的一个json字符串,是一个str对象encodejson.
dumps函数的参数很多,但是不是所有的都必须弄清楚,下面只说明几个比较常用的参数。
1) sort_keys:
是否按字典排序(a到z)输出。因为默认编码成json格式字符串后,是紧凑输出,并且也没有顺序的,不利于可读。
>>> data = [{"a":"A","x":(2,4),"c":3.0,"b":"4"},]
>>> json.dumps(data)
'[{"a": "A", "x": [2, 4], "c": 3.0, "b": "4"}]' #key值无顺序
>>> json.dumps(data,sort_keys = True) #按照key值排序输出,且也转化为Json字符
'[{"a": "A", "b": "4", "c": 3.0, "x": [2, 4]}]' #串类型
>>> data = {1:2,53:4,5:6}
>>> json.dumps(data,sort_keys = True)
'{"1": 2, "5": 6, "53": 4}' #依然会按照key值排序
>>> data = {1:2,53:4,"a":6} #key值存在两种类型
>>> json.dumps(data,sort_keys = True)
TypeError: '<' not supported between instances of 'str' and 'int'
#报错,在int与str之间无法比较<
>>> data = {"1":"2","53":4,"a":6} #key值都是str,有数字也有字母
>>> json.dumps(data,sort_keys = True)
'{"1": "2", "53": 4, "a": 6}' #能够排序
>>> ord("53")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: ord() expected a character, but string of length 2 found
TypeError: ord()期望得到一个字符,但是找到了长度为2的字符串
2) indent:
设置参数缩进显示的空格数。缩进显示使读起来更加清晰。
>>> data = {"1":"2","53":4,"a":6}
>>> json.dumps(data,sort_keys = True,indent = 3) #无print.换行输出
'{ "1": "2", "53": 4, "a": 6 }'
>>> print(json.dumps(data,sort_keys = True,indent = 3))
{
"1": "2",
"53": 4,
"a": 6
} #有print,每层缩进3格
>>> data = {"1":"2","53":[1,2,3,4,5,6],"a":6} #”53”key的值是一个数组
>>> print(json.dumps(data,sort_keys = True,indent = 3)) #设置输出每层缩进3
{
"1": "2", #”1”,”a”,”53”是一层,
"53": [ #[1,2,3,4,5,6]是第二层
1, #遇到{}和[]和,会换行
2,
3,
4,
5,
6
],
"a": 6
}
3) separators:
separators:参数的作用是去掉逗号”,”和分号”;”后面的空格,从上面的输出结果都能看到”,”与”:”后面都有个空格,这都是为了美化输出结果的作用,但是在我们传输数据的过程中,越精简越好,冗余的东西全部去掉,因此就可以加上separators参数对传输的json串进行压缩。该参数是元祖格式的。
>>> data = {"1":"2","53":4,"a":6}
>>> json.dumps(data)
'{"1": "2", "53": 4, "a": 6}' #”:”和”,”后都有空格
>>> len(json.dumps(data)) #不去掉”:”和”,”后的空格,长度是27
27
>>> json.dumps(data,separators = (",",":"))
'{"1":"2","53":4,"a":6}' #json串进行了压缩,在”:”和”,”后都没有空格
>>> len(json.dumps(data,separators = (",",":")))#去掉空格,长度是22
22
#从结果看出,通过移除多余的空白字符,达到了压缩数据的目的。
#海量数据处理时,很重要,能省很多字节
>>> len(json.dumps(data,separators = (",")))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "D:Python36libjson\__init__.py", line 238, in dumps
**kw).encode(obj)
File "D:Python36libjsonencoder.py", line 154, in __init__
self.item_separator, self.key_separator = separators
ValueError: not enough values to unpack (expected 2, got 1)
#报错,separators后面必须俩参数
4) skipkeys:
在encoding过程中,dict对象的key只可以是基本数据类型(str,Unicode,int,long,float,bool,None),如果是其他类型,那么在编码过程中就会抛出TypeError的异常。skipkeys可以跳过那些非string对象的key的处理,就是不处理。
>>> data= [ { 'a':'A', 'b':(2, 4), 'c':3.0, (1,2):'D tuple' } ]
>>> print(u"不设置skipkeys 参数")
不设置skipkeys 参数
>>> try :
... res1 = json.dumps(data) #skipkeys参数默认为False时
... except Exception as e:
... print(e)
...
keys must be a string
>>> print(u"设置skipkeys 参数")
设置skipkeys 参数
>>> print(json.dumps(data, skipkeys=True)) # skipkeys=True时
[{"a": "A", "b": [2, 4], "c": 3.0}] #不处理key值是(1:2)的数据
#list,set,dict不能做字典的key,tuple和类的实例可以做字典的key,所以skipkeys基本也就是跳过了tuple和类的实例
>>> data = [{"sr":2,(1,2):1,p:1},1]
>>> json.dumps(data,skipkeys = True)
'[{"sr": 2}, 1]'
5) ensure_ascii:
表示编码使用的字符集,默认是True,表示使用ascii码进行编码。如果设置为False.就会以Unicode进行编码。由于解码json字符串时返回的就是Unicode字符串,所以可以直接操作Unicode字符,然后直接编码Unicode字符串,这样会简单些。
>>> json.dumps("中国") #默认使用ascii码进行编码,中文不可直接使用
'"\u4e2d\u56fd"'
>>> json.dumps("中国",ensure_ascii = False)
'"中国"' #使用unicode进行编码,中文可以直接使用
11、将类对象(实例)编码成Json串
Python中的dict对象可以直接序列化为json的{},但是很多时候,可能用class表示对象,比如定义Employe类,然后直接去序列化就会报错。原因是类不是一个可以直接序列化的对象,但我们可以使用dumps()函数中的default参数来实现。
>>> json.dumps({1:2}) #Python中的dict对象可以直接序列化为json的{}
'{"1": 2}'
>>> json.dumps([{1:2}]) #注意区别以上的例子
'[{"1": 2}]'
import json
class Employee(object): #定义类Employe
def __init__(self, name, age, sex, tel):
self.name = name
self.age = age
self.sex = sex
self.tel = tel
def obj_json(self, obj_instance): #定义方法obj_json,参数obj_instance,就是实例对象
return {
'name': obj_instance.name,
'age': obj_instance.age,
'sex': obj_instance.sex,
'tel': obj_instance.tel }
emp = Employee('Lily', 24, 'female', '18223423423')
print(json.dumps(emp, default = emp.obj_json))
# {"name": "Lily", "age": 24, "sex": "female", "tel": "18223423423"}
#emp实例首先使用emp.obj_json方法,拼成了一个dict,搞成了一个json串。
12、JSON反序列化为类对象
json串反序列化成类对象或者类的实例,使用的是loads方法中的object_hook参数来实现。
import json
class Employee(object):
def __init__(self, name, age, sex, tel):
self.name = name
self.age = age
self.sex = sex
self.tel = tel
emp = Employee('Lily', 24, 'female', '18223423423')
def jsonToClass(emp): # jsonToClass是函数,不是方法,emp是dict,不是实例
return Employee(emp['name'], emp['age'], emp['sex'], emp['tel'])
json_str = '{"name": "Lucy", "age": 21, "sex": "female", "tel": "15834560985"}' #json串
e = json.loads(json_str, object_hook = jsonToClass)
json_str作为一个参数,先转化为字典,然后传递给jsonToClass,返回一个实例
print(e)
print(e.name)
#<__main__.Employee object at 0x0000020EC3C4E668>
#Lucy
小练习:
1. 匹配ip
ip = 0.0.0.0
每一位的数字的范围是0-255
首先分析ip地址的特征:255.255.255.255;
1位: 0-9 [0-9] d
2位:10-99 [1-9]d
2位以内: [1-9]?d
3位:100-199 1d{2}
3位:200-249 2[0-4]d
3位:250-255 25[0-5]
import re
pattern = r"(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}("
r"?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
pattern = re.compile(pattern)
print(pattern.search("255.213.2.345"))
print(pattern.search("0.0.0.0").group())
print(pattern.search("2.0.0.0").group())
(?:)代表括号不代表分组,取消分组,使用group(1)是读不到分组的内容的。
import re
print(re.search("a(d)c","a1c").group(1))
#1
print(re.search("a(?:d)c","a1c").group(1))
#IndexError: no such group
匹配一个单词边界
(?:pattern)匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用或字符“(|)"来组合一个模式的各个部分是很有用。例如"industr(?:y|ies)"就是一个比"industry|industries"更简略的表达式。
{n}n是一个非负整数。匹配确定的n次。