python进阶(20) 正则表达式的超详细使用
正则表达式
正则表达式(Regular Expression
,在代码中常简写为regex
、 regexp
、RE
或re
)是预先定义好的一个“规则字符率”,通过这个“规则字符串”可以匹配、查找和替换那些符合“规则”的文本。
虽然文本的查找和替換功能可通过字符串提供的方法实现,但是实现起来极为困难,而且运算效率也很低。而使用正则表达式实现这些功能会比较简单,而且效率很高,唯一的困难之处在于编写合适的正则表达式。
Python 中正则表达式应用非常广泛,如数据挖掘、数据分析、网络爬虫、输入有效性验证等,Python 也提供了利用正则表达式实现文本的匹配、查找和替换等操作的 re
模块。
1.1 正则表达式字符串
正则表达式是一种字符串,正则表达式字符串是由普通字符和元字符组成的。
1)普通字符
普通字符是按照字符字面意义表示的字符。
2)元字符
元字符是预先定义好的一些特定字符,比如\w
、\.
都属于元字符。
1.1.1 元字符
元字符(Metacharacters)是用来描述其他字符的特殊字符,它由基本元字符和普通字符构成。基本元字符是构成元字符的组成要素。基本元字符主要有14个,具体如下图所示。
字符 | 说明 |
---|---|
\ | 转义符,表示转义 |
. | 表示任意一个字符 |
+ | 表示重复1次或多次 |
* | 表示重复0次或多次 |
? | 表示重复0次或1次 |
| |
选择符号,表示“或关系”,例如:A | B 表示匹配A或B |
{} | 定义量词 |
[] | 定义字符类 |
() | 定义分组 |
^ | 可以表示取反,或匹配一行的开始 |
$ | 匹配一行的结束 |
上面表格中\w+
是元字符,它由两个基本元字符(\
和+
)和一个普通字符 w
构成。另外,还有.
元字符,它由两个基本元字符\
和,
构成。
学习正则表达式某种意义上讲就是在学习元字符的使用
,元字符是正则表达式的重点也是难点。下面会分门别类地介绍元字符的具体使用。
1.1.2 字符转义
在正则表达式中有时也需要字符转义,比如 w字符
不表示英文字母 w,而是表示任何语言的单词字符(如英文字母、亚洲文字等)、数字和下画线等内容时,需要在w
字母前加上反斜杠\
。反斜杠\
也是基本元字符,与 Python
语言中的字符转义是类似的。不仅可以对普通字符进行转义,还可以对基本元字符进行转义。如上面的表格,其中点.
字符是希望按照点.
的字面意义使用,作为.com
域名的一部分,而不是作为.
基本元字符使用,所以需要加反斜杠\
进行转义,即\.
才是表示点.
的字面意义。
1.1.3 开始与结束字符
本节通过一个示例介绍在 Python中如何使用正则表达式。
在1.1.1 节介绍基本元字符时介绍了^
和$
,它们可以用于匹配一行字符串的开始和结束。当以^
开始时,要求一行字符串的开始位置匹配:当以$
结束时,要求一行字符串的结位置匹配。所以正则表达式\w+@jiakecong.com
和^w+@jiakecong.com$
是不同的。
示例代码如下:
import re
p1 = r'\w+@jiakecong\.com'
p2 = r'^\w+@jiakecong\.com$'
text = "Tony 's email is tony_guan111@jiakecong.com"
m = re.search(p1, text)
print(m)
m = re.search(p2, text)
print(m)
email = "tony_guan111@jiakecong.com"
m = re.search(p2, email)
print(m)
输出结果如下:
<re.Match object; span=(17, 43), match='tony_guan111@jiakecong.com'>
None
<re.Match object; span=(0, 26), match='tony_guan111@jiakecong.com'>
1..2 字符类
在正则表达式中可以使用字符类,一个字符类定义一组字符,其中的任一一个字符出现在输入字符串中即匹配成功。注意每次匹配只能匹配字符类中的一个字符。
1.2.1 定义字符类
定义一个普通的字符类需要使用[
和]
元字符类。例如想在输入字符串中匹配Java
或java
,可以使用正则表达式[Jj]ava
,示例代码如下:
p = r'[Jj]ava'
m = re.search(p, 'I like Java and Python')
print(m)
m = re.search(p, 'I like JAVA and Python')
print(m)
m = re.search(p, 'I like java and python')
print(m)
输出结果如下:
<re.Match object; span=(7, 11), match='Java'>
None
<re.Match object; span=(7, 11), match='java'>
上述代码中除了JAVA
不匹配正则表达式[Jj]ava
,其他都匹配
1.2.2 字符串取反
在正则表达式中指定不想出现的字符,可以在字符类前加^
符号。示例代码如下:
import re
p = r'[^0123456789]'
m = re.search(p, '1000')
print(m)
m = re.search(p, 'python')
print(m)
上述代码定义的正则表达式[^0123456789]
,它表示输入字符串中出现非0-9数字即匹配,即出现在[0123456789]
以外的任意一字符即匹配
1.2.3 区间
上面示例中的[^0123456789]
正则表达式,事实上有些麻烦,这种连续的数字可以使用区间表示。区间是用连字符-
表示的,例如[0123456789]
采用区间表示为[0-9]
,[^0123456789]
采用区间表示为[^0-9]
。区间还可以表示连续的英文字母字符类,例如[a-z]
表示所有小写字母字符类,[A-Z]
表示所有大写字母字符类。
另外,也可以表示多个不同区间,[A-Za-z0-9]
表示所有字母和数字字符类,[0-25-7]
表示0、1、2、5、6、7几个字符组成的字符类。
示例代码如下:
import re
m = re.search('[A-Za-z0-9]', 'A10.3')
print(m)
m = re.search(r'[0-25-7]', 'A3489C')
print(m)
输出结果如下:
<re.Match object; span=(0, 1), match='A'>
None
1.2.4 预定义字符类
有些字符类很常用,例如[0-9]
等。为了书写方便,正则表达式提供了预定义的字符类,例如预定义字符类\d
等价于[0-9]
字符类。预定义字符类如下图所示
字符 | 说明 |
---|---|
. | 匹配任意一个字符 |
\ | 匹配反斜杠\字符 |
\n | 匹配换行 |
\r | 匹配回车 |
\f | 匹配一个换页符 |
\t | 匹配一个水平制表符 |
\v | 匹配一个垂直制表符 |
\s | 匹配一个空格符,等价于[\t\n\r\f\v] |
\S | 匹配一个非空格符,等价于[^\s] |
\d | 匹配一个数字字符,等价于[0-9] |
\D | 匹配一个非数字字符,等价[^0-9] |
\w | 匹配任意语言的单词字符、数字和下划线'_'等字符,如果正则表达式标志设置为ASCII,则只匹配[a-zA-Z0-9] |
\W | 等价于[^\w] |
示例代码如下:
import re
p = r'\D'
m = re.search(p, 'assss')
print(m)
m = re.search(p, '1000')
print(m)
text = '你们好hello'
m = re.search(r'\w', text)
print(m)
输出结果如下:
<re.Match object; span=(0, 1), match='a'>
None
<re.Match object; span=(0, 1), match='你'>
上述代码正则表达式\D
就等于[^0123456789]
。另一个正则表达式\w
表示任意字符,会在text
字符串中查找匹配字符,找到的结果是你
字符。
1.3 量词
之前学习的正则表达式元字符只能匹配显示一次字符或字符串,如果想匹配显示多次字符或字符串可以使用量词
1.3.1 量词的使用
量词表示字符或字符串重复的次数,正则表达式中的量词如下表:
字符 | 说明 |
---|---|
? | 出现0或1次 |
* | 出现0或多次 |
+ | 出现1或多次 |
{n} | 出现n次 |
{n,m} | 至少出现n次,但不超过m次 |
{n,} | 至少出现n次 |
量词的使用示例代码如下:
import re
m = re.search(r'\d?', '87654321')
print(m)
m = re.search(r'\d?', 'ABC')
print(m)
m = re.search(r'\d*', '87654321')
print(m)
m = re.search(r'\d*', 'ABC')
print(m)
m = re.search(r'\d+', '87654321')
print(m)
m = re.search(r'\d+', 'ABC')
print(m)
m = re.search(r'\d{8}', '87654321')
print(m)
m = re.search(r'\d{8}', 'ABC')
print(m)
m = re.search(r'\d{7,8}', '87654321')
print(m)
m = re.search(r'\d{9, }', '87654321')
print(m)
输出结果如下:
<re.Match object; span=(0, 1), match='8'>
<re.Match object; span=(0, 0), match=''>
<re.Match object; span=(0, 8), match='87654321'>
<re.Match object; span=(0, 0), match=''>
<re.Match object; span=(0, 8), match='87654321'>
None
<re.Match object; span=(0, 8), match='87654321'>
None
<re.Match object; span=(0, 8), match='87654321'>
None
1.3.2 贪婪量词和懒惰量词
量词还可以细分为贪婪量词和懒惰量词,贪婪量词会尽可能多地匹配字符,懒惰量词会尽可能少地匹配字符。大多数计算机语言的正则表达式量词默认是贪婪的,要想使用懒惰量词在量词后面加?
即可
示例代码如下:
import re
m = re.search(r'\d{5,8}', '87654321')
print(m)
m = re.search(r'\d{5,8}?', '87654321')
print(m)
输出结果如下:
<re.Match object; span=(0, 8), match='87654321'>
<re.Match object; span=(0, 5), match='87654'>
上述代码使用了贪婪量词{5,8}
,输入字符串87654321
是长度8位的数字字符串,尽可能多地匹配字符结果是87654321
。代码使用懒惰量词{5,8}?
,输入字符串87654321
是长度8位的数字字符串,尽可能少的匹配字符结果是87654
。
1.4 分组
在此之前学习的量词只能重复显示一个字符,如果想让一个字符串作为整体使用量词,可将整个字符串放到一对小括号中,这就是分组(也称子表达式)
1.4.1 分组的使用
对正则表达式进行分组不经可以对一个字符串整体使用量词,还可以在正则表达式中引用已经存在的分组。示例代码如下:
import re
p = r'(121){2}'
m = re.search(p, '121121abcabc')
print(m)
print(m.group()) # 返回匹配的字符串
print(m.group(1)) # 返回第一组内容
p = r'(\d{3,4})-(\d{7,8})'
m = re.search(p, '010-87654321')
print(m)
print(m.group()) # 返回匹配字符串
print(m.groups()) # 获得所有组内容
输出结果如下:
<re.Match object; span=(0, 6), match='121121'>
121121
121
<re.Match object; span=(0, 12), match='010-87654321'>
010-87654321
('010', '87654321')
上述代码定义的正则表达式(121)是将121字符串分为一组,(121){2}表示对121重复两次,即121121。代码调用match
对象的group()
方法返回匹配的字符串,group()
方法语法如下:
match.group([group1, ...])
其中参数group1
是组编号,在正则表达式中组编号是从1开始的,所以代码正则表达式m.group(1)
表示返回第一组内容
代码 r'(\d{3,4})-(\d{7,8})'
正则表达式可以用来验证固定电话号码,在-
之前是3-4位的区号,-
之后是7-8位的电话号码。在该正则表达式中有两个分组。代码m.groups()
方法是返回所有分组,返回值是一个元组
1.4.2 分组命名
在Python程序中访问分组时,除了可以通过组编号进行访问,还可以通过组名进行访问,前提是要在正则表达式中为组命名。组命名通过在组开头添加?P<分组名>
实现。
示例代码如下:
import re
p = r'(?P<area_code>\d{3,4})-(?P<phone_code>\d{7,8})'
m = re.search(p, '010-87654321')
print(m)
print(m.group()) # 返回匹配字符串
print(m.groups()) # 获得所有组内容
# 通过组编号返回组内容
print(m.group(1))
print(m.group(2))
# 通过组名返回组内容
print(m.group('area_code'))
print(m.group('phone_code'))
输出结果如下:
<re.Match object; span=(0, 12), match='010-87654321'>
010-87654321
('010', '87654321')
010
87654321
010
87654321
上述代码其实和1.4.1的代码是一样的,只是给正则表达式命名了,以后就可以通过组编号或组名字来访问
1.4.3 反向引用分组
除了可以在程序diamante中访问正则表达式匹配之后的分组内容,还可以再正则表达式内部引用之前的分组。
下面通过示例熟悉以下反向引用分组。假设由于工作需要想解析一段XML代码,需要找到某一个开始标签和结束标签,示例代码如下:
import re
p = r'<([\w]+)>.*</([\w]+)>'
m = re.search(p, '<a>abc</a>')
print(m)
p = r'<([\w]+)>.*</([\w]+)>'
m = re.search(p, '<a>abc</b>')
print(m)
输出结果如下:
<re.Match object; span=(0, 10), match='<a>abc</a>'>
<re.Match object; span=(0, 10), match='<a>abc</b>'>
上述代码的正则表达式分成了两组,两组内容完全一样。但是测试结果发现他们都是匹配的,但是<a>abc</b>
明显不是有效的XML代码,因为开始标签和结束标签应该是一致的。可见代码r'<([\w]+)>.*</([\w]+)>'
并不能保证开始标签和结束标签是一致的。为了解决此问题,可以引用反向引用,即让第二组反向引用第一组。在正则表达式中反向引用语法是\组编号
,组编号是从1开始的。示例代码如下:
import re
p = r'<([\w]+)>.*</\1>' # 使用了反向引用 ①
m = re.search(p, '<a>abc</a>')
print(m) # 匹配
m = re.search(p, '<a>abc</b>')
print(m) # 不匹配
输出结果如下:
<re.Match object; span=(0, 10), match='<a>abc</a>'>
None
上述代码第①行时定义正则表达式,其中\1
是反向引用第一个组,从运行结果可见字符串<a>abc</a>
是匹配的,而<a>abc</b>
字符串不匹配
1.4.4 非捕获分组
前面介绍的分组称为捕获分组。捕获分组的匹配子表达式结果被暂时保存到内存中,以备表达式或其他程序引用,这个过程称为"捕获",捕获结果可以通过组编号或组名进行引用。但是有时并不想引用子表达式的匹配结果,不想捕获匹配结果,只是将小括号作为一个整体进行匹配,此时可以使用非捕获分组,在组开头使用?
,可以实现非捕获分组
示例代码如下:
import re
s = 'img1.jpg,img2.jpg,img3.bmp'
# 捕获分组
p = r'\w+(\.jpg)'
mlist = re.findall(p, s) ①
print(mlist)
# 非捕获分组
p = r'\w+(?:\.jpg)'
mlist = re.findall(p, s) ②
print(mlist)
输出结果如下:
['.jpg', '.jpg']
['img1.jpg', 'img2.jpg']
上述代码实现了从字符串中查找.jpg
结尾的文本,其中代码第①行和第②行的正则表达式区别在于前者是捕获分组,后者是非捕获分组。捕获分组将括号中的内容作为子表达式进行捕获匹配,将匹配的子表达式(即组的内容)返回,结果是['.jpg','.jpg']
。而非捕获分组将括号中的内容作为普通的正则表达式字符串进行整体匹配,即找到.jpg
结尾的文本,所以最后结果是['img1.jpg', 'img2.jpg']
。
1.5 re模块
re
是Python
内置的正则表达式模块,前面虽然使用过re
模块一些函数,但还有很多重要函数没有详细介绍,这一节将详细介绍这些函数
1.5.1 search()和match()函数
search()
和match()
函数非常相似,它们的区别如下所示
search()
:在输入字符串中查找,返回第一个匹配内容,如果找到一个则match
对象,如果没有找到返回None
match()
:在输入字符串开始处查找匹配内容,如果找到一个则match
对象,如果没有找到返回None
示例代码如下:
import re
p = r'\w+@jiakecong\.com'
text = "Tony 's email is tony_guan111@jiakecong.com" ①
m = re.search(p, text)
print(m)
m = re.match(p, text)
print(m)
email = 'tony_guan111@jiakecong.com' ②
m = re.search(p, email)
print(m)
m = re.match(p, email)
print(m)
# match对象几个方法
print('match对象几个方法:') ③
print(m.group())
print(m.start())
print(m.end())
print(m.span())
输出结果如下:
<re.Match object; span=(17, 43), match='tony_guan111@jiakecong.com'>
None
<re.Match object; span=(0, 26), match='tony_guan111@jiakecong.com'>
<re.Match object; span=(0, 26), match='tony_guan111@jiakecong.com'>
match对象几个方法:
tony_guan111@jiakecong.com
0
26
(0, 26)
上述代码第①行输入字符串开头不是email
,search()
函数可以匹配成功,而match()
函数却匹配失败。代码第②行输入字符串开头就是email格式的邮箱,所以search()
和match()
函数都可以匹配成功
search
和match()
函数如果匹配成功都返回match
对象。match
对象有一些常用方法,见代码第③行。其中group()
方法返回匹配的子字符串;start()
方法返回子字符串的开始索引;end()
方法返回子字符串的结束索引;span
方法返回子字符串的跨度,它是一个二元素的元组。
1.5.2 findall()和finditer()函数
findall()
和finditer()
函数非常相似,它们的区别如下所示
- findall():在输入字符串中查找所有匹配内容,如果匹配成功,则返回
match
列表对象,如果匹配失败则返回None
- finditer():在输入字符串中查找所有匹配内容,如果匹配成功,则返回容纳
match
的可迭代对象,通过迭代对象每次可以返回一个match
对象,如果匹配失败则返回None
示例代码如下:
import re
p = r'[Jj]ava'
text = 'I like Java and java'
match_list = re.findall(p, text) ①
print(match_list)
match_iter = re.finditer(p, text) ②
for m in match_iter: ③
print(m.group())
输出结果如下:
['Java', 'java']
Java
java
上述代码第①行的findall()
函数返回match
列表对象。代码第②行的finditer()
函数返回可迭代对象。代码第③行通过for
循环遍历可迭代对象
1.5.3 字符串分割
字符串分割使用split
函数,该函数按照匹配的子字符串进行字符串分割,返回字符串列表对象
re.split(pattern, string, maxsplit=0, flags=0)
其中参数pattern
是正则表达式;参数string
是要分割的字符串;参数maxsplit
是最大分割次数,maxsplit
默认值为零,表示分割次数没有限制;参数flags
是编译标志
示例代码如下:
import re
p = r'\d+'
text = 'AB12CD34EF'
clist = re.split(p, text) ①
print(clist)
clist = re.split(p, text, maxsplit=1) ②
print(clist)
clist = re.split(p, text, maxsplit=2) ③
print(clist)
输出结果如下:
['AB', 'CD', 'EF']
['AB', 'CD34EF']
['AB', 'CD', 'EF']
上述代码调用split()
函数通过数字对AB12CD34EF
字符串进行分割,\d+
正则表达式匹配一到多个数字。代码第①行split()
函数中参数maxsplit
和flags
是默认的,分割的次数没有限制,分割结果是['AB', 'CD', 'EF']
列表
代码第②行split()
函数指定maxsplit
为1,分割结果是['AB', 'CD34EF']
列表,列表元素的个数是maxsplit+1
。
代码第③行split()
函数指定maxsplit
为2,2是最大可能的分割次数,因此maxsplit≥2
与maxsplit=0
是一样的。
1.5.4 字符串替换
字符串替换使用sub()
函数,该函数用于替换匹配的子字符串,返回值是替换之后的字符串。
re.sub(pattern, rep1, string, count=0, flags=0)
其中参数pattern
是正则表达式;参数rep1
是替换字符串;参数string
是要提供的字符串;参数count
是要替换的最大数量,默认值为零,表示替换数量没有限制;参数flags
是编译标志
示例代码如下:
import re
p = r'\d+'
text = 'AB12CD34EF'
replace_text = re.sub(p, ' ', text) ①
print(replace_text)
replace_text = re.sub(p, ' ', text, count=1) ②
print(replace_text)
replace_text = re.sub(p, ' ', text, count=2) ③
print(replace_text)
输出结果如下:
AB CD EF
AB CD34EF
AB CD EF
上述代码调用sub()
函数替换AB12CD34EF
字符串中的数字。代码第①行sub()
函数中参数count
和flags
都是默认的,替换的最大数量没有限制,替换结果是AB CD EF
代码第②行sub()
函数指定count
为1,替换结果是AB CD34EF
代码第③行sub()
函数指定count
为2,2是最大可能的替换次数,因此count≥2
与count=0
是一样的。
python进阶(20) 正则表达式的超详细使用的更多相关文章
- python进阶11 正则表达式
python进阶11 正则表达式 一.概念 #正则表达式主要解决什么问题? #1.判断一个字符串是否匹配给定的格式,判断用户提交的又想的格式是否正确 #2.从一个字符串中按指定格式提取信息,抓取页面中 ...
- Python 基础学习笔记(超详细版)
1.变量 python中变量很简单,不需要指定数据类型,直接使用等号定义就好.python变量里面存的是内存地址,也就是这个值存在内存里面的哪个地方,如果再把这个变量赋值给另一个变量,新的变量通过之前 ...
- JAVA 正则表达式 (超详细)
(PS:这篇文章为转载,我不喜欢转载的但我觉得这篇文章实在是超赞了,就转了过来,这篇可以说是学习JAVA正则表达的必读篇.作者是个正真有功力的人,阅读愉快) 在Sun的Java JDK 1.40版本中 ...
- 转载:JAVA 正则表达式 (超详细)
在Sun的JavaJDK 1.40版本中,Java自带了支持正则表达式的包,本文就抛砖引玉地介绍了如何使用Java.util.regex包. 可粗略估计一下,除了偶尔用Linux的外,其他Linu x ...
- python beautiful soup库的超详细用法
原文地址https://blog.csdn.net/love666666shen/article/details/77512353 参考文章https://cuiqingcai.com/1319.ht ...
- Python与Javascript相互调用超详细讲解(2022年1月最新)(三)基本原理Part 3 - 通过C/C++联通
目录 TL; DR python调javascript javascript调python 原理 基于Node.js的javascript调用python 从Node调用python函数 V8 嵌入P ...
- Python与Javascript相互调用超详细讲解(四)使用PyNode进行Python与Node.js相互调用项(cai)目(keng)实(jing)践(yan)
目录 前提 安装 使用 const pynode = require('@fridgerator/pynode')的时候动态链接错误 ImportError: math.cpython-39-x86_ ...
- python进阶之正则表达式
概念: 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑. 目的? 给定一个正则表 ...
- Python与Javascript相互调用超详细讲解(2022年1月最新)(一)基本原理 Part 1 - 通过子进程和进程间通信(IPC)
TL; DR 适用于: python和javascript的runtime(基本特指cpython[不是cython!]和Node.js)都装好了 副语言用了一些复杂的包(例如python用了nump ...
随机推荐
- springMVC-1-servlet回顾
SpringMVC重点学习 项目目标:SpringMVC+Vue+SpringBoot+SpringCloud+Linux spring:IOC+AOP SpringMVC:SpringMVC的执行流 ...
- PAT乙级:1066 图像过滤 (15分)
PAT乙级:1066 图像过滤 (15分) 题干 图像过滤是把图像中不重要的像素都染成背景色,使得重要部分被凸显出来.现给定一幅黑白图像,要求你将灰度值位于某指定区间内的所有像素颜色都用一种指定的颜色 ...
- YsoSerial 工具常用Payload分析之CC3(二)
这是CC链分析的第二篇文章,我想按着common-collections的版本顺序来介绍,所以顺序为 cc1.3.5.6.7(common-collections 3.1),cc2.4(common- ...
- 【洛谷1339 [USACO09OCT]】热浪Heat Wave 图论+最短路
AC代码 #include<bits/stdc++.h> using namespace std; const int MAXN=62000+10,INF=999999; struct E ...
- ECMAScript 2020(ES11)新特性简介
目录 简介 动态imports import.meta export加强 BigInt matchAll() globalThis Promise.allSettled() ??操作符 ?.操作符 总 ...
- python2 与 python3 依赖包冲突问题
原文链接 https://www.2cto.com/database/201805/749294.html 执行pip的时候取的是/usr/bin这里的pip,查看这里是否存在pip3,没有的话需 ...
- HTML5(五)——Canvas API
什么是 Canvas API? Canvas API(画布)提供了一个通过 javascript 和 html 的 canvas 元素来在网页上实时绘制图形的方式.可用于动画.游戏.图标.图片编辑等多 ...
- SSH远程端口转发实战详解
问题 前段时间在外地没有在实验室,随身携带了一个笔记本电脑.但是笔记本性能不够,想用SSH远程连接实验室的电脑.问如何连接?现有以下设备 设备 IP 备注 系统 实验室电脑C1 192.168.0.2 ...
- Prometheus + Alertmanager 实现企微告警
上一篇:二进制安装Prometheus 下面准备在监控的流程中呈现到告警到企微 查看企业ID,用于后续配置文件 四.安装Alertmanager1.准备安装的包 --选择上面链接给的Linux的ta ...
- spring框架的学习->从零开始学JAVA系列
目录 Spring框架的学习 框架的概念 框架的使用 Spring框架的引入 概念 作用 内容 SpringIOC的学习 概念 作用 基本使用流程 SpringIOC创建对象的三种方式 通过构造器方式 ...