python 正则使用详解

python 正则使用详解

  • 什么是正则
  • 在 python 中使用正则
    • 一些正则的定义
    • python 正则的方法
      • match 从字符串开头匹配
        • 正则返回的结果分析(重要)
      • fullmatch 严格匹配整个字符串
      • search 任意位置开始匹配
      • sub 替换匹配内容
      • subn 以元组方式返回替换结果
      • split 正则切割
      • findall 查找所有匹配结果
      • finditer 返回一个迭代结果
      • compile 正则表达式的预编译
      • purge 清除缓存
      • escape 正则表达式格式化

什么是正则

正则很简单的哦,不要因为看到和乱码差不多的样子就望而却步了,他很有规律的。

简单来说,就是用来描述字符串格式的,比如数字就可以是 [0-9],也可以是 [0123456789],还可以是 \d

而日常我们使用正则,则就是用这个描述格式来验证或匹配提取或批量替换用的,比如 html 代码,用 <[^<>]*?> 来匹配或删除所有标签

关于正则的入门知识,可以围观一下老顾的文章《文盲的正则表达式入门》,在这个文章里,老顾以正则各种符号使用的场景用途做了区分,和其他正则入门的教程不一样哦,当然,也没那么完整就是了。这个文章主要是用来方便理解正则的。

在 python 中使用正则

大部分的开发语言中,都有对正则的支持,毕竟,这也是字符验证的一个主要流派了,甚至不少数据库、命令行都有正则的支持,比如 linux系统,比如 mysql、oracle 数据库等,所以正则还是有必要学一学的。

在 python 中,正则的内容则放在 re 这个包里,使用也很简单,只要引用这个包就可以了

import re
print(re.findall('\d','123456 78/*9')) # 一个简单的例子,找出字符串中所有数字

在这里插入图片描述
在 python 的 re 包里,他提供了不少的指令,咱们来一一查看并学习,为了不遗漏内容,咱们把 re.py 这个文件打开,照着这个文档的内容来进行。文件位置如图,在 python 安装路径下的 lib 文件夹内。
在这里插入图片描述

一些正则的定义

在 re.py 这个文件中,从第29行开始,他简单的介绍了一些基本的特殊符号定义

The special characters are:
特殊字符为:
    "."      Matches any character except a newline.
             匹配除换行符以外的任何字符。
    "^"      Matches the start of the string.
             匹配字符串的开头。
    "$"      Matches the end of the string or just before the newline at the end of the string.
             匹配字符串的末尾或位于的换行符之前新行的末端。
    "*"      Matches 0 or more (greedy) repetitions of the preceding RE.
             Greedy means that it will match as many repetitions as possible.
             匹配0个或多个(默认是贪婪模式)由前边的正则片段定义的重复内容。
             贪婪模式意味着它会匹配尽可能多的重复。
    "+"      Matches 1 or more (greedy) repetitions of the preceding RE.
             匹配1个或多个(默认是贪婪模式)由前边的正则片段定义的重复内容。
    "?"      Matches 0 or 1 (greedy) of the preceding RE.
             匹配0个或1个(默认是贪婪模式)由前边的正则片段定义的内容。
    *?,+?,?? Non-greedy versions of the previous three special characters.
             前边三个定义的非贪婪版本。(老顾的正则入门里说过的哦,+*? 是长度定义,在长度定义后加 ? 就表示非贪婪模式,这个可以引用到任何长度定义中,包括下边也有出现)
    {m,n}    Matches from m to n repetitions of the preceding RE.
             匹配至少 m 个,最多 n 个由前边正则片段定义的内容。默认是贪婪模式
    {m,n}?   Non-greedy version of the above.
             上边长度定义的非贪婪版本。
    "\\"     Either escapes special characters or signals a special sequence.
             要么转义特殊字符,要么就是一个已经预定义的特殊序列。(好吧,老顾也不知道怎么准确翻译,这里的特殊序列指的就是预定义的字符集,比如\d表示数字,\n表示回车)
    []       Indicates a set of characters.
             A "^" as the first character indicates a complementing set.
             表示一组字符。(也就是老顾说的字符集,比如 \d 是已经预定义好的,但是是全部数字,也许我们只需要123,不需要其他数字,那么就必须自己定义字符集 [123] 这个样子)
             作为第一个字符的“^”表示一个补集。(在字符集定义中,如果 ^ 是第一个字符,则表示这个是个补集,换个说法,就是不包含之后定义的字符集的其他字符集,比如 [^\d] 就是所有非数字的字符)
    "|"      A|B, creates an RE that will match either A or B.
             A|B,创建一个匹配A或B的正则片段。
    (...)    Matches the RE inside the parentheses.
             The contents can be retrieved or matched later in the string.
             匹配括号内的正则片段。
             稍后可以在字符串中检索或匹配内容。(事实上,除了稍后在其他地方使用,在当前正则片段后的部分也可以使用)
    (?aiLmsux) The letters set the corresponding flags defined below.
               字母设置下面定义的相应标志。(这个用法老顾还没试过,翻译为百度翻译的结果)
    (?:...)  Non-grouping version of regular parentheses.
             正则圆括号的非分组版本。(也就是不可引用、追溯的部分)
    (?P<name>...) The substring matched by the group is accessible by name.
                  组匹配的子字符串可以通过名称访问。(给分组定个名字,然后通过名字访问)
    (?P=name)     Matches the text matched earlier by the group named name.
                  匹配前面由组名称匹配的文本。
    (?#...)  A comment; ignored.
             一个注释,忽略掉。(嗯,我讨厌写注释)
    (?=...)  Matches if ... matches next, but doesn't consume the string.
             右断言,位置修饰,如果能匹配成功则匹配之后的正则片段,该修饰不占用匹配空间。
    (?!...)  Matches if ... doesn't match next.
             右断言,与上一个修饰意思相反,如果不符合之后的正则片段,则继续匹配。
    (?<=...) Matches if preceded by ... (must be fixed length).
             左断言,如果前边的字符符合正则片段...(必须定长)
    (?<!...) Matches if not preceded by ... (must be fixed length).
             左断言,如果前边的字符不符合正则片段...(必须定长)
    (?(id/name)yes|no) Matches yes pattern if the group with id/name matched, the (optional) no pattern otherwise.
                       如果具有id/name的组匹配,则匹配yes模式,否则为(可选)无模式。(同样没用过的方法)

通过这个内容,我们基本就可以确定 python 中,正则能完成哪些描述,这样的描述又有什么样的限制了。

再之后,从62 行开始,还介绍了一些预定义字符集,这里就不翻译了,大家随便看看就好,基本都差不多。

再然后,87 行开始,说明了, re 这个包之中包含的各种方法,嗯,之后一一讲解

以及102行开始的,正则修饰。。。。老顾最常用的就是忽略大小写修饰,这个修饰是在正则定义之外的,还有多行匹配也偶尔用用,其他的说实话,老顾基本用不上。

python 正则的方法

约定,之后的所有内容,默认都已经引入了 re 包,即,代码中已经包含了 import re

match 从字符串开头匹配

Match a regular expression pattern to the beginning of a string.
将正则表达式模式与字符串的开头匹配。

语法:
match(pattern, string, flags=0)
match(正则表达式,匹配字符串,正则表达式修饰(默认为0))

需要注意,这个方法时严格从字符串开头进行匹配的,如果想在字符串中间找到匹配,不要用这个方法哦。

示例:

print(re.match('\d+','123.548'))
# 返回结果
<re.Match object; span=(0, 3), match='123'>
print(re.match('\s\d+','123.548'))
# 返回结果,匹配失败,没有Match信息
None

在python中,使用匹配返回的结果,大部分都是 re.Match 对象,他包含了一个 span 元组,这个元组就是匹配字符串对应的切片位置,match 就是匹配的结果了

正则返回的结果分析(重要)

ans = re.match('\d+','123.548')
print(ans)
<re.Match object; span=(0, 3), match='123'>

我们通过一个变量,来分析返回的结果该如何使用

print(ans.re) # 输出这个匹配的正则
re.compile('\\d+') # 包含了我们正则片段的正则编译对象
print(ans.string) # 输出这个匹配的原始匹配字符串
123.548
print(ans.pos,ans.endpos) # 输出原始字符串的切片,包括起始位置和结束位置
0 7
print(ans.regs) # 输出匹配的结果,注意,这里是元组,每一个内层元组是一个匹配
((0, 3),)
print(ans.span) # 输出span方法
<built-in method span of re.Match object at 0x00000148614E76C0>
print(ans.span(0)) # 输出第一个匹配的切片信息
(0, 3)
print(ans.start(0),ans.end(0)) # 返回指定匹配顺序的切片开始和结束位置
0 3
print(ans.group(0)) # 返回第一个匹配结果匹配到的内容
123

嗯,由于刚才的匹配,我们简单的匹配了一个 \d+,没有带分组信息,这次我们加上一个分组来尝试

ans = re.match('(\d+)\.(\d+)','123.548') # 带有两个分组的正则匹配
print(ans)
<re.Match object; span=(0, 7), match='123.548'>
print(ans.span(0),ans.span(1),ans.span(2)) # 返回所有的切片信息
#这里需要注意的是,如果带有分组,那么原始字符串自动占据返回结果的第一个分组,即下标为0的分组
#所以,实时上我们需要提取的结果,应该是从下标1开始的
(0, 7) (0, 3) (4, 7)
print(ans.group(0),ans.group(1),ans.group(2)) # 输出该匹配结果的分组结果
123.548 123 548
print(ans.groups()) # 输出该匹配的分组内容,注意,这里的groups没有参数,输入参数也是无效的
# 所以想要引用结果,必须使用 group
('123', '548')
print(ans.groups(101))
('123', '548')
print(ans.expand('\\1 is \\2')) # 将匹配结果按照指定的字符串格式输出,这里可以引用分组结果
123 is 548

好了,经过这几个输出,我们应该明白了正则匹配结果返回的内容都包含哪些信息了,还有个别的属性方法老顾也不太清楚,这里就不再讲解了

有了这些方法和属性,我们就可以很方便的使用正则返回结果中的内容了

fullmatch 严格匹配整个字符串

Match a regular expression pattern to all of a string.
将正则表达式模式与所有字符串匹配。

语法:
fullmatch(pattern, string, flags=0)
fullmatch(正则表达式,匹配字符串,正则表达式修饰(默认为0))

print(re.fullmatch('[a-z]+','0123456')) # 由于没有字母,匹配失败
None
print(re.fullmatch('[a-z]+','Abcd efgh',re.IGNORECASE)) # 虽然忽略大小写了,但是中间有空格,不能严格匹配,匹配失败
None
print(re.fullmatch('\d+','0123456')) # 整个字符串严格匹配 \d+
<re.Match object; span=(0, 7), match='0123456'>
print(re.fullmatch('[a-z]+','Abcdefgh',re.IGNORECASE)) # 整个字符串严格匹配 [a-z]+
<re.Match object; span=(0, 8), match='Abcdefgh'>
print(re.fullmatch('[a-z]','Abcdefgh',re.IGNORECASE)) # 长度对应不上,没有长度修饰则只匹配一个字符的字符串才可以成功
None

嗯,就是严格匹配字符串首尾,默认相当于 search 的正则前边带 ^ 后边带 $

search 任意位置开始匹配

Search a string for the presence of a pattern.
在字符串中搜索是否存在模式。

语法:
search(pattern, string, flags=0)
search(正则表达式,匹配字符串,正则表达式修饰(默认为0))

print(re.search('[a-z]+','0123456')) # 没有匹配到结果,返回 None
None
print(re.search('[a-z]+','Abcd efgh',re.IGNORECASE)) # 返回第一个匹配成功的结果片段
<re.Match object; span=(0, 4), match='Abcd'>
print(re.search('\d+','abcde0123456')) # 返回第一个匹配成功的结果片段
<re.Match object; span=(5, 12), match='0123456'>
print(re.search('[a-z]+','Abcdefgh',re.IGNORECASE)) # 整个字符串都符合正则,所以完整返回了
<re.Match object; span=(0, 8), match='Abcdefgh'>
print(re.search('[a-z]','Abcdefgh',re.IGNORECASE)) # 返回第一个匹配成功的片段
<re.Match object; span=(0, 1), match='A'>

很明显,search 要比 match 和 fullmatch 要宽松很多,我们可以更自由的发挥

sub 替换匹配内容

Substitute occurrences of a pattern found in a string.
替换字符串中发现的模式的出现次数。(百度翻译的什么鬼?)
替换字符串中所有或指定次数的符合匹配的内容。(老顾翻译)

语法:
sub(pattern, repl, string, count=0, flags=0)
sub(正则表达式,替换表达式,匹配字符串,替换次数,正则表达式修饰(默认为0))

print(re.sub('(\d{2})','\\1-','18300183000')) # 将数字每两位之后加一个减号
18-30-01-83-00-0
----
print(re.sub('(?=\d+)(?<!\d)','\n','1开始2结束3运行4调试11开会12报告')) # 在每个连续数字前插入一个换行,大家可以和下一个比较一下有什么不同

1开始
2结束
3运行
4调试
11开会
12报告
----
print(re.sub('(?=\d+)','\n','1开始2结束3运行4调试11开会12报告')) # 在每个数字前,插入一个换行

1开始
2结束
3运行
4调试
1
1开会
1
2报告
----
print(re.sub('(?=\d+)(?<!\d)','\n','1开始2结束3运行4调试11开会12报告',count=5)) # 指定了替换次数的正则替换

1开始
2结束
3运行
4调试
11开会12报告

正则替换还是很好用的,但是,这里要说一个但是,python 的正则替换里描述的内容,有一个很重要的部分,很多人可能都忽略掉了。原文如下

def sub(pattern, repl, string, count=0, flags=0):
    """Return the string obtained by replacing the leftmost
    non-overlapping occurrences of the pattern in string by the
    replacement repl.  repl can be either a string or a callable;
    if a string, backslash escapes in it are processed.  If it is
    a callable, it's passed the Match object and must return
    a replacement string to be used."""
    return _compile(pattern, flags).sub(repl, string, count)

repl can be either a string or a callable;
repl可以是字符串,也可以是可调用的
If it is a callable, it’s passed the Match object and must return a replacement string to be used.
如果是可调用的的话,它传递Match对象,并且必须返回要使用的替换字符串。

也就是说,我可以通过委托的方法,来处理匹配到的内容,并返回指定的结果
来,我们试试看哦

def star(n): # 这里的 n 就是一个正则匹配对象Match
    return '*' * int(n.group(0)) + '\n' # 将匹配到的数字转成星星的数量,并返回星星

print(re.sub('\d',star,'123456789')) # 委托匹配到的内容使用 star 方法来处理
*
**
***
****
*****
******
*******
********
*********
import random
def star(n):
    return ''.join([random.choice('abcdefghijklmnopqrstuvwxyz') for _ in range(int(n.group(0)))]) + '\n'

print(re.sub('\d',star,'123454321'))
v
sr
lvd
trtm
rnhrq
loxb
vjd
su
i

以及,老顾在《在学习爬虫的路上,有多少坑在前边》一文中,实际用到的两个转编码的函数

正则替换如此强大,你还不心动吗?

subn 以元组方式返回替换结果

Same as sub, but also return the number of substitutions made.
与sub相同,但也返回进行的替换次数。(百度翻译持续不说人话)
和 sub 方法一样,但是,在元组中,记录了替换的次数。(老顾翻译)

语法:
subn(pattern, repl, string, count=0, flags=0)
subn(正则表达式,替换表达式,匹配字符串,替换次数,正则表达式修饰(默认为0))

print(re.subn('(?=\d+)(?<!\d)','\n','1开始2结束3运行4调试11开会12报告'))
('\n1开始\n2结束\n3运行\n4调试\n11开会\n12报告', 6) # 元组第一个元素为返回结果,第二个元素为替换次数

def star(n):
    return '*' * int(n.group(0)) + '\n'

print(re.subn('\d',star,'13243546576879'))
('*\n***\n**\n****\n***\n*****\n****\n******\n*****\n*******\n******\n********\n*******\n*********\n', 14)

subn 就不细说了,和sub一样的玩法

split 正则切割

Split a string by the occurrences of a pattern.
按出现的模式拆分字符串。

语法:
split(pattern, string, maxsplit=0, flags=0)
split(正则表达式,匹配字符串,最大切割次数(默认0,即不限制次数),正则表达式修饰(默认为0))

print(re.split('[^\d]','13 243,54uu6576879')) # 以非数字的字符为切割符,切割字符串
['13', '243', '54', '', '6576879'] # 由于两个 u 之间没有数字,所以结果中会出现空字符串

print(re.split('[^\d]','13 243,54uu6576879',maxsplit=2)) # 指定最大切割次数的分割字符串
['13', '243', '54uu6576879']

嗯。。。。很常用实用以及很容易用,不细说了

需要注意的是,这里返回的就是字符串数组,没有Match信息了

findall 查找所有匹配结果

Find all occurrences of a pattern in a string.
查找字符串中出现的所有模式。

语法:
findall(pattern, string, flags=0)
findall(正则表达式,匹配字符串,正则表达式修饰(默认为0))

额。。。怎么说呢,在抛弃了Match信息的情况下,以字符串数组方式返回所有匹配

print(re.findall('\d+','13 243,54uu6576879'))
['13', '243', '54', '6576879']

在大部分的工作中,其实这个也就够用了,因为我们并不关心他出现在什么地方,前后文有什么,但在一些需求比较复杂的时候,这个 findall 就不如 finditer 了,因为 findall 丢失了Match信息,而finditer还保留着Match信息

finditer 返回一个迭代结果

Return an iterator yielding a Match object for each match.
返回一个迭代器,为每个匹配生成一个Match对象。

语法:
finditer(pattern, string, flags=0)
finditer(正则表达式,匹配字符串,正则表达式修饰(默认为0))

print(re.finditer('\d+','13 243,54uu6576879')) # 返回了一个迭代器
<callable_iterator object at 0x00000148615CD540>

for m in re.finditer('\d+','13 243,54uu6576879'): #使用迭代,将所有匹配输出
    print(m)
<re.Match object; span=(0, 2), match='13'>  # 第一个匹配
<re.Match object; span=(3, 6), match='243'> # 第二个匹配
<re.Match object; span=(7, 9), match='54'>  # 第三个匹配
<re.Match object; span=(11, 18), match='6576879'> # 第四个匹配

由于这里完整的保留了Match的信息,所以我们可以对匹配到的结果进行定位,以及检查前后文之类的操作,需要用的人自然会用到,也就不细说了

compile 正则表达式的预编译

Compile a pattern into a Pattern object.
将模式编译为pattern对象。

语法:
compile(pattern, flags=0)

嗯。。。定义一个正则,也许复杂的正则会用到这个,老顾一般都直接写正则片段,除了上了1k的正则,老顾一般不会用这个

purge 清除缓存

Clear the regular expression cache.
清除正则表达式缓存。

语法:
purge()

没啥用,这是针对预编译的正则来说的,老顾基本上都是随手写正则随手用,没有预编译过

escape 正则表达式格式化

Backslash all non-alphanumerics in a string.
对正则表达式字符串中的所有非字母数字进行转义。

语法:
escape(pattern)

这个还算有点用,算是正则格式化的部分,比如我们想从字符串中提取到一部分作为匹配内容,但是匹配到的内容可能会有特殊符号,比如*号,?号之类的,这些在正则中有其他意义,所以我们需要提前将这些符号转义,escape就是干这个用的,将特殊符号都转义。老顾在 c# 中使用正则,还单独自己写了个FormatRegex 方法,就是干这个用的。郁闷。

print(re.escape('123.456*789=$100')) # 格式化正则片段,将其特殊符号都进行转义
123\.456\*789=\$100

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/579.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一 Go环境搭建

1. 下载地址 https://golang.google.cn/dl/ 傻瓜式安装&#xff0c;自动会配置path的变量&#xff0c;安装完成后可以使用go version 查看当前安装的版本 本文使用目前最新的1.20.2版本 2. 配置go环境 cmd控制栏打开输入以下命令&#xff08;如果cmd有问题可以尝试powershe…

面试了一个32岁的程序员,一个细节就看出来是培训班的····

首先&#xff0c;我说一句&#xff1a;培训出来的&#xff0c;优秀学员大有人在&#xff0c;我不希望因为带着培训的标签而无法达到用人单位和候选人的双向匹配&#xff0c;是非常遗憾的事情。 最近&#xff0c;在网上看到这样一个留言&#xff0c;引发了程序员这个圈子不少的…

Qt(c++)调用海康威视监控摄像头

文章目录一.海康威视监控摄像头开发SDK介绍二.海康SDK模块说明三.Qt项目中海康威视SDK配置四.实时预览摄像头图像程序一.海康威视监控摄像头开发SDK介绍 设备网络SDK是基于设备私有网络通信协议开发的&#xff0c;为嵌入式网络硬盘录像机、NVR、网络摄像机、网络球机、视频服务…

【Linux】冯诺依曼体系结构

冯诺依曼体系结构一、计算机结构体系来源二、冯诺依曼体系结构三、冯诺依曼体系结构中的数据流动一、计算机结构体系来源 研制电子计算机的想法产生于第二次世界大战期间&#xff0c;主要用来进行弹道计算&#xff0c;在"时间就是胜利"的战争年代&#xff0c;迫切需…

【JavaEE进阶篇1】认识Spring、认识IoC、使用spring创建对象

目录 一、什么是Spring 1.1容器 1.2什么是IoC 传统方式创建对象的问题&#xff1a; 类与类之间的耦合性过大 Ioc的优点 Spring IoC容器最核心的功能 1.3DI概念说明(Dependency Injection) IoC和DI的区别是什么 二、Spring项目的创建 三、Spring的使用(把对象存储到spr…

ChatGPT是如何训练得到的?通俗讲解

首先声明喔&#xff0c;我是没有任何人工智能基础的小白&#xff0c;不会涉及算法和底层原理。 我依照我自己的简易理解&#xff0c;总结出了ChatGPT是怎么训练得到的&#xff0c;非计算机专业的同学也应该能看懂。看完后训练自己的min-ChatGPT应该没问题 希望大牛如果看到这…

stm32外设-中断详解

0. 写在最前 本栏目笔记都是基于stm32F10x 1. 中断是啥&#xff1f; 什么是中断&#xff1a;CPU在处理某一事件A时&#xff0c;发生的另外某一事件B请求CPU去处理&#xff08;产生了中断&#xff09;&#xff0c;随后CPU暂时中断当前正在执行的任务&#xff0c;去对事件B进行处…

Java的二叉树、红黑树、B+树

数组和链表是常用的数据结构&#xff0c;数组虽然查找快&#xff08;有序数组可以通过二分法查找&#xff09;&#xff0c;但是插入和删除是比较慢的&#xff1b;而链表&#xff0c;插入和删除很快&#xff08;只需要改变一些引用值&#xff09;&#xff0c;但是查找就很慢&…

【C#】组件化开发,调用dll组件方法

系列文章 C#项目–业务单据号生成器&#xff08;定义规则、自动编号、流水号&#xff09; 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/129129787 C#项目–开始日期结束日期范围计算&#xff08;上周、本周、明年、前年等&#xff09; 本文链接&…

快排函数 -- qsort函数(Quick Sort)

文章目录&#x1f50e;1.qsort函数简介&#x1f4a1;1.1.函数原型&#x1f4a1;1.2.参数含义&#x1f50e;2.比较函数介绍&#x1f50e;3.比较函数使用案例&#x1f4a1;3.1.整型数组&#x1f4a1;3.2.浮点型数组&#x1f4a1;3.3.结构体类型 - 字符串&#x1f50e;4.利用冒泡排…

震撼,支持多模态模型的ChatGPT 4.0发布了

最近几个月&#xff0c;互联网和科技圈几乎ChatGPT刷屏了&#xff0c;各种关于ChatGPT的概念和应用的帖子也是围绕在周围。当去年年底ChatGPT发布的那几天&#xff0c;ChatGPT确实震撼到了所有人&#xff0c;原来AI还可以这么玩&#xff0c;并且对国内的那些所谓的人工智能公司…

Tesla都使用什么编程语言?

作者 | 初光 出品 | 车端 备注 | 转载请阅读文中版权声明 知圈 | 进“汽车电子与AutoSAR开发”群&#xff0c;请加微“cloud2sunshine” 总目录链接>> AutoSAR入门和实战系列总目录 带着对更美好未来的愿景&#xff0c;特斯拉不仅成为有史以来最有价值的汽车公司&…

多线程(初阶)

文章目录一.初始线程(Thread)1.1.线程的概念1.2.线程的优势1.2.1.线程比进程更轻量1.2.2.并发编程1.3.线程和进程的区别二.Thread类方法2.1. java 中创建线程的方法2.1.1. 继承Thread,重写run2.1.2. 实现Ruuable接口2.1.3. 使用匿名内部类,继承Thread2.1.4.使用匿名内部类,实现…

[蓝桥杯单片机]——八到十一届初赛决赛客观题

第八届初赛 一、填空题 采用外部12MHz晶振&#xff0c;经过系统12分频时定时器获得最大定时长度&#xff0c;此时定时器定时脉冲为1MHz&#xff0c;周期为1s&#xff0c;而定时器计时均为16位加法计数器&#xff0c;即计时长度为。 二、 选择题 ①带阻滤波器是指能通过大多数频…

处理窄区路径规划的业务问题

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 TODO:写完再整理 文章目录系列文章目录前言一、通过栅格地图的处理解决二、使用bug绕障的方式走出窄区&#xff0c;或者结合边界图形参考bug算法沿边出来三、使用维诺图计…

字符串函数和内存函数

&#x1f355;博客主页&#xff1a;️自信不孤单 &#x1f36c;文章专栏&#xff1a;C语言 &#x1f35a;代码仓库&#xff1a;破浪晓梦 &#x1f36d;欢迎关注&#xff1a;欢迎大家点赞收藏关注 字符串函数和内存函数 文章目录字符串函数和内存函数前言1. 字符串函数介绍1.1 s…

【MySQL】MySQL的优化(一)

目录 查看SQL执行频率 定位低效率执行SQL 定位低效率执行SQL-慢查询日志 定位低效率执行SQL-show processlist 查看SQL执行频率 MySQL 客户端连接成功后&#xff0c;通过 show [session|global] status 命令可以查看服务器状态信息。通 过查看状态信息可以查看对当…

jvm类与类加载

1.类加载过程&#xff1a; 首先要加载某个类一定是出于某种目的&#xff0c;比如要运行java程序&#xff0c;那么久必须加载主类才能运行其中的方法&#xff0c;所以一般在这些情况下&#xff0c;如果类没有被加载&#xff0c;就会自动被加载&#xff1a; 1.使用new创建对象时 …

MyBatis开发环境搭建

1.创建工程 2.引入相关的依赖 pom.xml <dependencies><!--1.引入mybatis包--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.6</version></dependency><!--2.单元…

FPGA和IC设计怎么选?哪个发展更好?

很多人纠结FPGA和IC设计怎么选&#xff0c;其实往小了说&#xff0c;要看你选择的具体是哪个方向岗位。往大了说&#xff0c;将来你要是走更远&#xff0c;要成为大佬&#xff0c;那基本各个方向的都要有涉及的。 不同方向就有不同的发展&#xff0c;目前在薪资上IC设计要比FP…