Markdown
- Number lists are sequential: 不管你前面的数字是多少,run之后会自动排序。
- *,-,_等是无序的。
- latex等式:
Basic Python
Magic commands:
?abc -abc的help;%whos :当前存在的object,包括variable,type,Data/Info;%quickref :所有magic command的信息%latex :可使用latex语法,等式前\ [等式后 \ ]
Main types of containers:
- lists,
[ ] , mutable, iterable. - tuples,
( ) , immutable, iterable. - dictionaries,
{ } , keys and items are mutable, iterable.
range(start, 不含end, step) creates iterables.
f-string:格式f’string’
- 用大括号{variable}来表示被替换字段,返回的字符串直接填入替换内容。
- 大括号{ }可以填入表达式或调用函数,其结果会填入返回的字符串内。
- 大括号{ }可进行(lambda匿名函数),做复杂的数值运算
- 大括号{ }内使用的引号不能和大括号外的引号定界符引号冲突,灵活切换单双三引号。
- 大括号外的引号可使用\转义,内不可。
- 大括号外如果需要显示大括号,应输入连续两个大括号{{ }},大括号内需要引号,使用引号即可。
:> 左填充,:< 右填充,:^ 中间填充。默认填充空格,指定字符放在:后面。- 数字符号相关格式描述符 {a:+}等
- 宽度和精度相关格式描述符,保留小数点位数
举例 reference
name = "Li Hua"
f"Hello, my name is {name}"
num = 2
f"I have {num} apples"
price = 95.5
f"He has {price}$ "
f"They have {2 + 2 * 5} apples."
f"My name is {name.lower()}"
import math
f"the value of n is {math.pi}."
aa = 123.456
f"{(lambda x : x * 5 - 2)(aa):.2f}"
bb = 8
cc = 2
f"{(lambda x,y : x + y)(bb,cc)}"
f"{(lambda x,y : x + y)(bb,cc):.2f}"
f'I am {"Huang Wei"}.'
f'''I am {'Huang Wei'}.'''
f"""I am {"Huang Wei"}."""
f"He\'ll go to {'Shang Hai'}."
f"""He said {"I'm Tom"}."""
f"5{'{apples}'}"
f"{{5}}{'apples'}"
f"{name:>20}"
f"{name:<20}"
f"{name:^20}"
f"{name:$>20}"
a = 12
b = -25
print(f"{a:+}")
print(f"{a:-}")
print(f"{b:+}")
print(f"{b:-}")
print(f"{a: }")
print(f"{b: }")
c = 123.456
print(f"{c:10}")
print(f"{c:010}")
print(f"{c:8.1f}")
print(f"{c:8.2f}")
print(f"{c:.2f}")
print(f"{c:2f}")
d = 'Hello'
print(f"{d:10.3}")
print(f"{d:->10.3}")
print(f"{d:-<10.3}")
for i in range(1,10):
for j in range(1,i+1):
print(f"{j} * {i} = {j * i}",end=" ")
print("\n")
We can convert range/finite iterables to list .
list(range(0,10,2))
Dictionary
- key - value pairs
- {‘key’:value, ‘key’:value,…}
- name.keys() 表示字典的key
- name.values() 表示字典的value
- name.items() 表示key-value二元tuple组成的list
String
- iterable and immutable.
- 连接字符串的方法:
- a = x + y + z
- ’
空格 ’. join([x, y, z]) - a = x y z
str.find( a ) , 在str中找a字符串,返回字符串a的第一个字幕的位置str.replace(a, b) ,在str中将a改成b,返回新的字符串
Regular Expressions
- 正则表达式是一个特殊的字符序列
- 能帮助检查一个字符串是否与某种模式
匹配 。 - re 模块
- 正则表达式包括普通字符和特殊字符/元字符 metacharacters
- 普通字符匹配自己(even case-insensitive);但是
元字符无法自我匹配 ,往往通过重复或改变来影响RE其他部分。 - 元字符:. ^ $ * + ? { } [ ] \ | ( )
匹配字符
[ ]
- 用于指定一个符号类。
- 符号可以是单独被列出,也可由“-”来组合连续符号。
· 如,[abc]和[a-c]等价 ;如果你想匹配lowercase letters,[a-z] - 元字符在类中不活跃。
· 如,[akm\$]可以match任一字符 ‘a’, ‘k’, ‘m’, ‘\$’。而’\$'通常为元字符,但是在class中就不再特殊 。
- 可通过将
^ 放在首位来 complement the set(补集),从而match不在class里的符号。 · 如,[^5]将会match除了5以外的所有符号
- 但如果caret^没有出现在class的首位,则无特殊含义,仅表示其中一个符号。
· 如,[5]将match‘5’或‘’。
backslash\
- 可跟各种字符来表示特殊序列。
- 可帮助元字符摆脱特殊身份。
· 可用\[ 和 \\ 来表示元字符[ 和\ 。
- 有很多预设序列(如\后跟一些数字,字母或者其他非空格字符)
· 如: |举例 |含义| |—|:—| |\d|match任何十进制数字,相当于class[0-9]| |\D|match任何非数字字符,相当于class[^0-9]| |\s|match任何空格字符,相当于class[\t\n\r\f\v] | |\S|match任何非空格字符,相当于class[^\t\n\r\f\v] | |\w|match任何字母和数字alphanumeric,相当于class[a-zA-Z0-9]| |\W|match任何非字母数字,相当于class[^a-zA-Z0-9]|
- 上述的序列可以包含在一个字符类中。如,
[\s,.] 表示match任何空格字符,或‘,’或‘.’。
.
- match任何字符,除了newline character。通常用于你想match“any character”的地方。
正则表达式的第二个作用:重复
*
- 指前面的字符可以match
零次或更多次 ,而不是只是1次。 - 如,ca*t 匹配 ‘ct’,‘cat’,‘caaat’,ect。
- repetitions are greedy: 重复RE时,matching engine会重复尽可能多的次数,如果后续不再match,matching engine将会后退并且再少量重复几次。
- 一个 step-by-step 例子如下:考虑RE:
a[bcd]*b , match ‘a’,0或多个从class[bcd]中选择的字母,并最终以‘b’结尾。现与字符串‘abcbd’ 进行匹配。 |step|matched|explanation| |—|---|—| |1|a |在RE中的‘a’成功match| |2|abcbd |engine和[bcd]*进行match,在此例中,最多能进行到最后一个字母| |3|failure|engine想和RE的最后一个字母b进行match,但由于上一步已经进行到最后,所以失败了| |4|abcb |后退,所以[bcd]*的match将少一个字符| |5|failure|再次尝试RE的末位‘b’,但是此时最后一个字母为‘d’| |6|abc |后退,所以[bcd]*只和‘bc’进行match| |7|abcb |再次尝试RE的末位‘b’,此时字符串的末位未被match且为‘b’,因此成功 |
+
- +将会进行
大于1 的match(而*包括0) - 如,ca+t 将会match ‘cat’,‘caat’,‘caaat’.etc. 但没有ct。
?
- match
1次或0次 - 如,home-?brew 将会match ‘homebrew’或‘home-brew’
{m, n}
- m和n为十进制整数,decimal integer。
- 这个修饰符qualifier表明进行
最少m次、最多n次 的重复。 - 如,a/{1,3}b 将会match ‘a/b’‘a//b’‘a///b’。
- 可以omit省略m或n,m的default为0,n为infinity。
{0,} = *, {1,} = +, {0,1} = ?
Using RE
Compiling RE
re.compile()
- re.compile(pattern,flags=0)
- 将一个RE pattern 转换为一个
RE object ,而RE object可以通过match( ), search( ) 等方法被用于matching。
import re
p = re.compile('ab*')
p
RE作为字符串传递给了re.compile( )。(因为re不是python核心语言,转换为字符串使运行更加方便,但有一个缺点:backslash plague)
The Backslash Plague 反斜杠瘟疫
- 反斜杠可以用来表示特殊形式或用来将特殊字符失去特殊含义。
- 这与python中反斜杠在string literals字符串常量里的作用冲突。
- 如, 想写一个\section的RE,大量\使字符串难以理解。
|characters|stage|comment| |—|---|—| |\section |需要被匹配的字符串|在LaTeX file中可能被找到| |\\section |escaped backslash|将需要match的字符串中的反斜杠escape,并传递给re.comple( ) | |"\\\\section" |escaped backslashes for a string literal|在python语法中,两个反斜杠都得escape| - solution:使用Python的
raw string notation 来表示RE。如果一个字符串常量以‘r’ 开头,则\不用以任何特殊方式处理。 - 如,
r"\n" 是一个两字符字符串,包含‘\’和‘n’;而“\n”是一个包含换行符的单字符。 |Regular String|Raw String| |—|---| |"ab*" |r"ab*"| |"\\\\section" |r"\section"| |"\\w+\\s+\\1" |r"\w+\s+\1"|
Performing Matches
Method/Attribute | Purpose |
---|
match( ) | 确定RE是否和字符串的开始 match,总是0 | search( ) | 扫描一个字符串,寻找这个RE匹配的任何位置 。 | findall( ) | 找到RE匹配的所有子字符串 ,并将它们作为列表 返回 | finditer( ) | 找到RE匹配的所有子字符串 ,并将它们作为迭代器 返回 |
- 注意到,如果没有相关匹配存在,match()和search()返回
None ;如果成功匹配,则会返回一个object ,包含匹配的基本信息:开始和结束的位置,匹配的子字符串,.etc。 - object的方法
|Method/Attribute|Purpose| |—|---| |group( ) |返回匹配的字符串| |start( ) |返回匹配的第一个位置| |end( ) |返回匹配的末位位置| |span( ) |返回一个包含(start,end)位置的tuple|
import re
p = re.compile('[a-z]+')
print(p.match(""))
m = p.match('tempo')
m
None
<re.Match object; span=(0, 5), match='tempo'>
m.group()
'tempo'
m.start(),m.end()
(0, 5)
m.span()
(0, 5)
print(p.match('::: message'))
None
m2 = p.search('::: message')
print(m2)
<re.Match object; span=(4, 11), match='message'>
m2.group()
'message'
m2.span()
(4, 11)
- 通常来说,最常见的样式是将匹配对象存储在变量中,然后检查它是否为None
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aAIHsbKk-1633421683827)(attachment:image.png)]
p = re.compile(r'\d+')
string1 = p.findall('12 drummers drumming, 11 pipers piping, 10 lords a-leaping')
print(string1)
['12', '11', '10']
iterator = p.finditer('12 drummers drumming, 11 pipers piping, 10 lords a-leaping')
iterator
<callable_iterator at 0x1c560f4b9a0>
for match in iterator:
print(match.span())
(0, 2)
(22, 24)
(40, 42)
Module-Level Functions
- 可以再循环中使用re.match/search/findall/sub(RE, String)来减少调用函数时间;循坏外都差不多,因为有内部缓存。
Compilation Flags
- 用于修改RE的某些方面
- flags有两种名字:长名字-如IGNORECASE; 短名字-如I。
- 许多Flag可以通过按位运算OR来组合,如
re.I|re.M 同时设置的I和M两个flags。 |Flag|Meaning| |—|---| |ASCII,A|使转义字符\w ,\b ,\s ,\d 等只和ASCII码进行匹配,只对unicode有意义,byte pattern将被忽略| |DOTALL,S|使. 匹配任一字符,包括newlines(\n )| |IGNORECASE,I|忽略字母大小写。当unicode patterns[a-z] ,[A-Z] 用了此标志,则将会匹配53个ASCII字母和4个多余的non-ASCII字符。| |LOCALE,L|进行locale-aware区域感知匹配。使 \w 、\W 、\b 、\B 和大小写敏感 匹配依赖于当前区域 而不是 Unicode 数据库| |MULTILINE,M|多行匹配,影响^ 和$ 。当指定了这个标志时,^ 匹配字符串的开头和字符串中每一行的开头,紧跟在每个换行符之后。 类似地,$ 元字符匹配字符串的结尾和每行的结尾(紧接在每个换行符之前)| |VERBOSE,X(for ‘extended’)|启用详细的正则,可以更清晰,更容易理解。指定此标志后,将忽略正则字符串中的空格,除非空格位于字符类中或前面带有未转义的反斜杠;这使你可以更清楚地组织和缩进正则。 此标志还允许你将注释放在正则中,引擎将忽略该注释;注释标记为 ‘#’ 既不是在字符类中,也不是在未转义的反斜杠之前。|
import re
charref = re.compile(r"""
&[#] # Start of a numeric entity reference
(
0[0-7]+ # Octal form
| [0-9]+ # Decimal form
| x[0-9a-fA-F]+ # Hexadecimal form
)
; # Trailing semicolon
""", re.VERBOSE)
charref = re.compile("&#(0[0-7]+"
"|[0-9]+"
"|x[0-9a-fA-F]+);")
More Pattern Power
More metacharacters
- Zero-width assertions.
- 是一种零宽度的匹配,它匹配到的内容不会保存到匹配结果中去,最终匹配结果只是一个位置。
- 作用是给指定位置添加一个限定条件,用来规定此位置之前或者之后的字符必须满足限定条件才能使正则中的子表达式匹配成功。
- 不应重复零宽度断言,因为如果它们在给定位置匹配一次,它们显然可以无限次匹配。例如,\b 是一个断言,指明当前位置位于字边界;这个位置根本不会被 \b 改变。
|
- or运算符
- A|B将匹配任何A或B匹配的字符串
- 低优先级
- 如,
crow|servo 将匹配crow 或servo - 如果要匹配
| 本身,则使用\| 或将其放在class中[|]
^
- 在行的开头匹配
- 在MUTILINE模式下,在字符串的每个换行符后立即匹配。
- 如,希望仅在行的开头匹配
from ,则使用RE ^from - 如果要匹配
^ 本身,则使用\^
$
- 在行的末尾匹配,或后面是换行符的任何位置。
- 如果要匹配
$ 本身,则使用\$^ 或将其放在class中[$]
\A
- 仅匹配字符串开头
- 非MULTILINE模式,
\A 和^ 相同。 - MULTILINE模式,
\A 只在字符串开头匹配;而^ 也可以再换行符后进行匹配。
\Z
\b
- 字边界,为Zero-width assertions,仅在单词的开头或结尾处匹配。
- 单词被定义为一个字母数字字符序列,因此单词的结尾由空格或非字母数字字符表示。
- 仅当它是一个完整的单词时匹配;当它包含在另一个单词中时将不会匹配。
- 如果你没有使用r字符串,那么 Python 会将
\b 转换为退格,你的正则不会按照你的预期匹配。
\B
- 非字边界,也为Zero-width assertions,仅在单词的非边界处匹配。
print("开头匹配例子^")
print(re.search('^From', 'From Here to Eternity'))
print(re.search('^From', 'Reciting From Memory'))
print("\n末尾匹配例子$")
print(re.search('}$', '{block}'))
print(re.search('}$', '{block} '))
print(re.search('}$', '{block}\n'))
print("\n边界匹配例子\\b")
p = re.compile(r'\bclass\b')
print(p.search('no class at all'))
print(p.search('the declassified algorithm'))
print(p.search('one subclass is'))
开头匹配例子^
<re.Match object; span=(0, 4), match='From'>
None
末尾匹配例子$
<re.Match object; span=(6, 7), match='}'>
None
<re.Match object; span=(6, 7), match='}'>
边界匹配例子\b
<re.Match object; span=(3, 8), match='class'>
None
None
Grouping
- RE除了可以判断它本身是否匹配,还可以通过将RE分成几个分组,来分组匹配,从而进行分析字符串。
- 如,在电子邮件的标准格式RFC-822中,标题行分为了标题名称和值,二者用‘:’分开:
From: author@example.com User-Agent: Thunderbird 1.5.0.9 (X11/20061227) MIME-Version: 1.0 To: editor@example.com | - 为达到以上效果,我们可以定义一个匹配整行的RE,其中一个分组匹配标题名称,另一个分组匹配内容。
- 分组由元字符小括号
‘( )’ 来表示,内部放入表达式,外部可添加重复限定符. - 组内的小括号能表示他们匹配内容的开始和结束索引;并且组永远由0开始编号,group 0 表示整个字符串;然后根据括号的位置进行编号。
- group也可以一次运行多个小组; 方法groups返回一个元祖,包含所有子组的字符串,从1开始。
\1 表示复用第1个分组
import re
print('使用小括号来表示分组')
p1 = re.compile('(ab)*')
print(p1.match('ababababab').span())
print('\n分组编号')
p2 = re.compile('(a(b)c)d')
m = p2.match('abcd')
print([m.group(0), m.group(1), m.group(2)])
print('group也可以一次运行多个小组')
print(m.group(2,1,2))
print('groups的返回值为一个从group1开始的元祖')
print(m.groups())
print('\n检测双字')
p3 = re.compile(r'\b(\w+)\s+\1\b')
print(p3.search('Paris in the the spring').group())
使用小括号来表示分组
(0, 10)
分组编号
['abcd', 'abc', 'b']
group也可以一次运行多个小组
('b', 'abc', 'b')
groups的返回值为一个从group1开始的元祖
('abc', 'b')
检测双字
the the
Non-capturing and Named Groups
- 对于复杂的RE,我们很难追踪分组编号
- Perl expression: extension syntax:
(?...) - 问号后紧跟一个P表示python专属
(?P...) - 如果想用组来表示RE的一部分,但对组的内容不感兴趣,不捕捉模式
(?: ...) ,则匹配使会忽略冒号后的内容
- 命名组:`(?P…)
- retrieve named groups as a dictionary with
groupdict() \b(\w+)\s+\1\b 也可写成\b(?P<word>\w+)\s+(?P=word)\b:
m1 = re.match("([abc])+", "abc")
print(m1.groups())
m2 = re.match("(?:[abc])+", "abc")
print(m2.groups())
('c',)
()
import re
p4 = re.compile(r'(?P<word>\b\w+\b)')
m3 = p4.search( '(((Lots of punctuation)))' )
print(m3.group('word'))
print(m3.group(1))
Lots
Lots
m4 = re.match(r'(?P<first>\w+) (?P<last>\w+)', 'Jane Doe')
print(m4.groupdict())
{'first': 'Jane', 'last': 'Doe'}
p5 = re.compile(r'\b(?P<word>\w+)\s+(?P=word)\b')
p5.search('Paris in the the spring').group()
'the the'
Lookahead Assertions
(?=…)
Functions
lambda fuction
- g = lambda x: x + 1(, [x的取值])
↓ def g(x): return x + 1
map function
map(function, iterable, ...) - 返回值为迭代器,可用
list[map( )] 来表示值
list comprehension
[var for x in range(n) if b==0]
其他
!r 就是连引号一起输出字符串,即原本式子来是啥就是啥。key.__repr__() 等于 rept(key) , 即将object key的原本形式打印,类似上面.将对象转化为供解释器读取的形式.返回一个对象的 string 格式。read more 函数str() 用于将值转化为适于人阅读的形式,而repr() 转化为供解释器读取的形式。通常情况下obj==eval(repr(obj))这个等式是成立的- RE reference 博客园
- re module py
- tkinter intro application
bool(" ")
True
|