Python正则表达式(re)
正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为regex、regexp或RE),是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符"),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式(规则)的文本。
正则表达式的“鼻祖”或许可一直追溯到科学家对人类神经系统工作原理的早期研究。美国新泽西州的Warren McCulloch和出生在美国底特律的Walter Pitts这两位神经生理方面的科学家,研究出了一种用数学方式来描述神经网络的新方法,他们创造性地将神经系统中的神经元描述成了小而简单的自动控制元,从而作出了一项伟大的工作革新。
在1951 年,一位名叫Stephen Kleene的数学科学家,他在Warren McCulloch和Walter Pitts早期工作的基础之上,发表了一篇题目是《神经网事件的表示法》的论文,利用称之为正则集合的数学符号来描述此模型,引入了正则表达式的概念。正则表达式被作为用来描述其称之为“正则集的代数”的一种表达式,因而采用了“正则表达式”这个术语。
正则表达式的特点:
- 灵活性、逻辑性和功能性非常强;
- 可以迅速地用极简单的方式达到字符串的复杂控制。
- 对于刚接触的人来说,比较晦涩难懂。
正则表达式的应用场景:
- 匹配 查看一个字符串是否符合正则表达式的语法,一般返回true或者false;
- 获取 正则表达式来提取字符串中符合要求的文本;
- 替换 查找字符串中符合正则表达式的文本,并用相应的字符串替换;
- 分割 使用正则表达式对字符串进行分割。
python使用正则表达式要导入re库。
#提取邮箱
pattern = re.compile(r"[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(?:\.[a-zA-Z0-9_-]+)")
strs = '我的私人邮箱是zhuwjwh@outlook.com,公司邮箱是123456@qq.org,麻烦登记一下?'
result = pattern.findall(strs)
print(result) #['zhuwjwh@outlook.com', '123456@qq.org’]#提取身份证号
pattern = re.compile(r"[1-9]\d{5}(?:18|19|(?:[23]\d))\d{2}(?:(?:0[1-9])|(?:10|11|12))(?:(?:[0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]")
strs = '小明的身份证号码是342623198910235163,手机号是13987692110'
result = pattern.findall(strs)
print(result) #['342623198910235163’]#提取电话号码
pattern = re.compile(r"\d{3}-\d{8}|\d{4}-\d{7}")
strs = '0511-1234567是小明家的电话,他的办公室电话是021-87654321'
result = pattern.findall(strs)
print(result) #['0511-1234567', '021-87654321']
正则表达式语法
正则表达式一般由普通字符、转义字符、特殊字符组成。
普通字符
字母、数字、汉字、下划线、以及没有特殊定义的标点符号,都是"普通字符"。表达式中的普通字符,在匹配一个字符串的时候,匹配与之相同的一个字符。
例如:表达式 “c”,在匹配字符串 “abcde” 时,匹配结果是:成功;匹配到的内容是:“c”;匹配到的位置是:开始于2,结束于3。(包含开始位置,不包含结束位置)例2:表达式 "bcd",在匹配字符串"abcde"时,匹配结果是:成功;匹配到的内容是:"bcd";匹配到的位置是:开始于1,结束于4。
转义字符
- 一些不便书写的字符,采用在前面加“\” 的方法。例如制表符、换行符等;
- 一些特殊字符,为了表示自己本来的含义,在前面加“\” 后,如{,}, [, ], /, \, +, *, ., $, ^, |, ? 等;
| 转义字符 | 说明 |
| \n | 匹配换行符 |
| \t | 匹配制表符 |
| \\ | 匹配\符号 |
| \^ | 匹配^符号 |
| \$ | 匹配$符号 |
| \. | 匹配.符号 |
| \? | 匹配?符号 |
| \* | 匹配*符号 |
| \+ | 匹配+符号 |
| \{、\} | 匹配大括号 |
| \[、\] | 匹配中括号 |
| \(、\) | 匹配小括号 |
| \| | 匹配|符号 |
转义字符的匹配方法与“普通字符”类似,也是匹配与之相同的一个字符。
例如:表达式 "\$d",在匹配字符串 "abc$de" 时,匹配结果是:成功;匹配到的内容是:"$d";匹配到的位置是:开始于3,结束于5。
特殊字符
特殊字符在正则表达式中有特殊的语法含义
| 字符 | 描述 |
|---|---|
| . | 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。 |
| \d | 匹配一个数字字符。等价于 [0-9]。 |
| \D | 匹配一个非数字字符。等价于 [^0-9]。 |
| \s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 |
| \S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 |
| \w | 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。 |
| \W | 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。 |
| ^ | 匹配字符串的开头 |
| $ | 匹配字符串的末尾。 |
| . | 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。 |
| [...] | 用于表示一个字符集合。参见后面的补充说明 |
| [^...] | 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。 |
| * | 对它前面的正则式匹配0到任意次重复, 尽量多的匹配字符串。 re* 会匹配 'r','re',或者 'r' 后面跟随任意个 'e'。 |
| + | 对它前面的正则式匹配1到任意次重复。 re+ 会匹配 'r' 后面跟随1个以上到任意个 'e',它不会匹配 'r'。 |
| ? | 对它前面的正则式匹配0到1次重复。 re? 会匹配 'r' 或者 're'。 |
| {m} | 对其之前的正则式指定匹配 m 个重复;少于 m 的话就会导致匹配失败。比如, a{6} 将匹配6个 'a' , 但是不能是5个。 o{2} 不能匹配 "Bob" 中的 "o",但是能匹配 "food" 中的两个 o。 |
| {m,n} | 对正则式进行 m 到 n 次匹配,在 m 和 n 之间取尽量多。 比如,a{3,5} 将匹配 3 到 5个 'a'。 |
| {m,} | 匹配至少m个前面表达式。例如, o{2,} 不能匹配"Bob"中的"o",但能匹配 "foooood"中的所有 o。"o{1,}" 等价于 "o+"。"o{0,}" 则等价于 "o*"。a{4,}b 将匹配 'aaaab' 或者1000个 'a' 尾随一个 'b',但不能匹配 'aaab'。逗号不能省略,否则无法辨别修饰符应该忽略哪个边界。 |
| {,n} | 匹配至多n个前面表达式 |
| {m,n}? | 将导致结果 RE 匹配之前 RE 的 m 至 n 次重复,尝试匹配尽可能 少的 重复次数。 这是之前数量限定符的非贪婪版本。 例如,在 6 个字符的字符串 'aaaaaa' 上,a{3,5} 将匹配 5 个 'a' 字符,而 a{3,5}? 将只匹配 3 个字符。 |
| {m,n}+ | 将导致结果 RE 匹配之前 RE 的 m 至 n 次重复,尝试匹配尽可能多的重复而 不会 建立任何反向追溯点。 这是上述数量限定符的占有型版本。 例如,在 6 个字符的字符串 |
| a|b | 匹配a或b |
| (...) | (组合),匹配括号内的任意正则表达式,并标识出组合的开始和结尾。匹配完成后,组合的内容可以被获取,并可以在之后用 \number 转义序列进行再次匹配,之后进行详细说明。要匹配字符 '(' 或者 ')', 用 \( 或 \), 或者把它们包含在字符集合里: [(], [)]. |
| (?...) | 这是个扩展标记法 (一个 '?' 跟随 '(' 并无含义)。 '?' 后面的第一个字符决定了这个构建采用什么样的语法。这种扩展通常并不创建新的组合; (?P<name>...) 是唯一的例外。针对这种扩展语法,参见补充说明。 |
| \w | 匹配字母数字及下划线 |
| \W | 匹配非字母数字及下划线 |
| \s | 匹配任意空白字符,等价于 [ \t\n\r\f]。 |
| \S | 匹配任意非空字符 |
| \d | 匹配任意数字,等价于 [0-9]. |
| \D | 匹配任意非数字 |
| \A | 匹配字符串开始 |
| \Z | 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。 |
| \z | 匹配字符串结束 |
| \G | 匹配最后匹配完成的位置。 |
| \b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。 |
| \B | 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。 |
| \n, \t, 等. | 匹配一个换行符。匹配一个制表符。等 |
| \1...\9 | 匹配第n个分组的内容。 |
| \10 | 匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。 |
补充说明:
[]
用于表示一个字符集合:
- 字符可以单独列出,比如 [amk] 匹配 'a', 'm', 或者 'k'。
- 可以表示字符范围,通过用 '-' 将两个字符连起来。比如 [a-z] 将匹配任何小写ASCII字符, [0-5][0-9] 将匹配从 00 到 59 的两位数字, [0-9A-Fa-f] 将匹配任何十六进制数位。 如果 - 进行了转义 (比如 [a\-z])或者它的位置在首位或者末尾(如 [-a] 或 [a-]),它就只表示普通字符 '-'。
- 特殊字符在集合中会失去其特殊意义。比如 [(+*)] 只会匹配这几个字面字符之一 '(', '+', '*', or ')'。
- 字符类如 \w 或者 \S (如下定义) 在集合内可以接受,它们可以匹配的字符由 ASCII 或者 LOCALE 模式决定。
- 不在集合范围内的字符可以通过 取反 来进行匹配。如果集合首字符是 '^' ,所有 不 在集合内的字符将会被匹配,比如 [^5] 将匹配所有字符,除了 '5', [^^] 将匹配所有字符,除了 '^'. ^ 如果不在集合首位,就没有特殊含义。
- 要在集合内匹配一个 ']' 字面值,可以在它前面加上反斜杠,或是将它放到集合的开头。 例如,[()[\]{}] 和 []()[{}] 都可以匹配右方括号,以及左方括号,花括号和圆括号。
- Unicode Technical Standard #18 里的嵌套集合和集合操作支持可能在未来添加。这将会改变语法,所以为了帮助这个改变,一个 FutureWarning 将会在有多义的情况里被 raise,包含以下几种情况,集合由 '[' 开始,或者包含下列字符序列 '--', '&&', '~~', 和 '||'。为了避免警告,需要将它们用反斜杠转义。
贪婪模式
在使用修饰匹配次数的特殊符号时,如“?”,“*”, “+”等,可以使同一个表达式能够匹配不同的次数,具体匹配的次数随被匹配的字符串而定。这种重复匹配不定次数的表达式在匹配过程中,总是尽可能多的匹配,这种匹配原则就叫作"贪婪" 模式 。
'*', '+' 和 '?' 数量限定符都是 贪婪的;它们会匹配尽可能多的文本。 有时这种行为并不被需要;如果 RE <.*> 针对 '<a> b <c>' 进行匹配,它将匹配整个字符串,而不只是 '<a>'。 在数量限定符之后添加 ? 将使其以 非贪婪 或 最小 风格来执行匹配;也就是将匹配数量尽可能 少的 字符。 使用 RE <.*?> 将只匹配 '<a>'。
*+, ++, ?+
类似于 '*', '+' 和 '?' 数量限定符,添加了 '+' 的形式也将匹配尽可能多的次数。 但是,不同于真正的贪婪型数量限定符,这些形式在之后的表达式匹配失败时不允许反向追溯。 这些形式被称为 占有型 数量限定符。 例如,a*a 将匹配 'aaaa' 因为 a* 将匹配所有的 4 个 'a',但是,当遇到最后一个 'a' 时,表达式将执行反向追溯以便最终 a* 最后变为匹配总计 3 个 'a',而第四个 'a' 将由最后一个 'a' 来匹配。 然而,当使用 a*+a 时如果要匹配 'aaaa',a*+ 将匹配所有的 4 个 'a',但是在最后一个 'a' 无法找到更多字符来匹配时,表达式将无法被反向追溯并将因此匹配失败。 x*+, x++ 和 x?+ 分别等价于 (?>x*), (?>x+) 和 (?>x?)。
{m,n}、{m,n}?、{m,n}+
{m,n}对正则式进行 m 到 n 次匹配,在 m 和 n 之间取尽量多。 比如,a{3,5} 将匹配 3 到 5个 'a'。{m,n}?将导致结果 RE 匹配之前 RE 的 m 至 n 次重复,尝试匹配尽可能 少的 重复次数。 这是之前数量限定符的非贪婪版本。 例如,在 6 个字符的字符串 'aaaaaa' 上,a{3,5} 将匹配 5 个 'a' 字符,而 a{3,5}? 将只匹配 3 个字符。{m,n}+将导致结果 RE 匹配之前 RE 的 m 至 n 次重复,尝试匹配尽可能多的重复而 不会 建立任何反向追溯点。 这是上述数量限定符的占有型版本。 例如,在 6 个字符的字符串 'aaaaaa' 上,a{3,5}+aa 将尝试匹配 5 个 'a' 字符,然后,要求再有 2 个 'a',这将需要比可用的更多的字符因而会失败,而 a{3,5}aa 的匹配将使 a{3,5} 先捕获 5 个,然后通过反向追溯再匹配 4 个 'a',然后用模式中最后的 aa 来匹配最后的 2 个 'a'。 x{m,n}+ 就等同于 (?>x{m,n})。
>>> re.search(r'a{3,5}', 'baaac')
<re.Match object; span=(1, 4), match='aaa'>
>>> re.search(r'a{3,5}', 'baaaaaac')
<re.Match object; span=(1, 6), match='aaaaa'>
>>> re.search(r'a{3,5}?', 'baaaaaac')
<re.Match object; span=(1, 4), match='aaa'>
>>> re.search(r'a{3,5}+', 'baaaaaac')
<re.Match object; span=(1, 6), match='aaaaa'>
(?...)
扩展标记法,'?' 后面的第一个字符决定了这个构建采用什么样的语法。
(?aiLmsux)
( 'a', 'i', 'L', 'm', 's', 'u', 'x' 中的一个或多个) 这个组合匹配一个空字符串;这些字符对正则表达式设置以下标记 re.A (只匹配ASCII字符), re.I (忽略大小写), re.L (语言依赖), re.M (多行模式), re.S (点dot匹配全部字符), re.U (Unicode匹配), and re.X (冗长模式)。 (这些标记在 模块内容 中描述) 如果你想将这些标记包含在正则表达式中,这个方法就很有用,免去了在 re.compile() 中传递 flag 参数。标记应该在表达式字符串首位表示。
(?:…)
正则括号的非捕获版本。 匹配在括号内的任何正则表达式,但该分组所匹配的子字符串 不能 在执行匹配后被获取或是之后在模式中被引用。
(?aiLmsux-imsx:…)
('a', 'i', 'L', 'm', 's', 'u', 'x' 中的0或者多个, 之后可选跟随 '-' 在后面跟随 'i' , 'm' , 's' , 'x' 中的一到多个 .) 这些字符为表达式的其中一部分 设置 或者 去除 相应标记 re.A (只匹配ASCII), re.I (忽略大小写), re.L (语言依赖), re.M (多行), re.S (点匹配所有字符), re.U (Unicode匹配), and re.X (冗长模式)。(标记描述在 模块内容 .)
'a', 'L' and 'u' 作为内联标记是相互排斥的, 所以它们不能结合在一起,或者跟随 '-' 。 当他们中的某个出现在内联组中,它就覆盖了括号组内的匹配模式。在Unicode样式中, (?a:...) 切换为 只匹配ASCII, (?u:...) 切换为Unicode匹配 (默认). 在byte样式中 (?L:...) 切换为语言依赖模式, (?a:...) 切换为 只匹配ASCII (默认)。这种方式只覆盖组合内匹配,括号外的匹配模式不受影响。
(?>...)
尝试匹配 ... 就像它是一个单独的正则表达式,如果匹配成功,则继续匹配在它之后的剩余表达式。 如果之后的表达式匹配失败,则栈只能回溯到 (?>...) 之前 的点,因为一旦退出,这个被称为 原子化分组 的表达式将会丢弃其自身所有的栈点位。 因此,(?>.*). 将永远不会匹配任何东西因为首先 .* 将匹配所有可能的字符,然后,由于没有任何剩余的字符可供匹配,最后的 . 将匹配失败。 由于原子化分组中没有保存任何栈点位,并且在它之前也没有任何栈点位,因此整个表达式将匹配失败。
(?P<name>…)
与常规圆括号类似,但组匹配的子字符串可以通过符号组名称访问。组名必须是有效的Python标识符,并且每个组名在正则表达式中只能定义一次。符号组也是一个有编号的组,就像该组没有命名一样。
命名组合可以在三种上下文中引用。如果样式是 (?P<quote>['"]).*?(?P=quote) (也就是说,匹配单引号或者双引号括起来的字符串):
| 引用组合 "quote" 的上下文 | 引用方法 |
|---|---|
| 在正则式自身内 |
|
| 处理匹配对象 m |
|
| 传递到 |
|
(?P=name)
反向引用一个命名组合;它匹配前面那个叫 name 的命名组中匹配到的串同样的字串。
(?#…)
注释;里面的内容会被忽略。
前瞻(?=…)
exp1(?=exp2) exp1后面的内容要匹配exp2
当 … 匹配时,匹配成功,但不消耗字符串中的任何字符。这个叫做 前视断言 (lookahead assertion)。比如, Isaac (?=Asimov) 将会匹配 'Isaac ' ,仅当其后紧跟 'Asimov' 。
负前瞻(?!…)
exp1(?!exp2) exp1后面的内容不能匹配exp2
当 … 不匹配时,匹配成功。这个叫 否定型前视断言 (negative lookahead assertion)。例如, Isaac (?!Asimov) 将会匹配 'Isaac ' ,仅当它后面 不是 'Asimov' 。
后顾(?<=…)
(?<=exp2)exp1 exp1前面的内容要匹配exp2
如果 ... 的匹配内容出现在当前位置的左侧,则匹配。这叫做 肯定型后视断言 (positive lookbehind assertion)。 (?<=abc)def 将会在 'abcdef' 中找到一个匹配,因为后视会回退3个字符并检查内部表达式是否匹配。内部表达式(匹配的内容)必须是固定长度的,意思就是 abc 或 a|b 是允许的,但是 a* 和 a{3,4} 不可以。注意,以肯定型后视断言开头的正则表达式,匹配项一般不会位于搜索字符串的开头。
>>> m = re.search('(?<=abc)def', 'abcdef')
>>> m.group(0)
'def'
>>> m = re.search(r'(?<=-)\w+', 'spam-egg')
>>> m.group(0)
'egg'
负后顾(?<!…)
(?<!exp2)exp1 exp1前面的内容不能匹配exp2
如果 ... 的匹配内容没有出现在当前位置的左侧,则匹配。这个叫做 否定型后视断言 (negative lookbehind assertion)。类似于肯定型后视断言,内部表达式(匹配的内容)必须是固定长度的。以否定型后视断言开头的正则表达式,匹配项可能位于搜索字符串的开头。
>>> re.search(r'(?<!-)\w+', 'spam-egg')
<re.Match object; span=(0, 4), match='spam'>
>>> re.search(r'(?<=-)\w+', 'spam-egg')
<re.Match object; span=(5, 8), match='egg'>
条件匹配(?(id/name)yes-pattern|no-pattern)
对应id的子表达式如果匹配到内容,则这里匹配yes_exp,否则匹配no_exp
如果给定的 id 或 name 存在,将会尝试匹配 yes-pattern ,否则就尝试匹配 no-pattern,no-pattern 可选,也可以被忽略。比如, (<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$) 是一个email样式匹配,将匹配 '<user@host.com>' 或 'user@host.com' ,但不会匹配 '<user@host.com' ,也不会匹配 'user@host.com>'。
由 '\' 和一个字符组成的特殊序列在以下列出。 如果普通字符不是ASCII数位或者ASCII字母,那么正则样式将匹配第二个字符。比如,\$ 匹配字符 '$'.
主要函数
- re库是Python的标准库,不需要额外安装,主要用于字符串匹配
- 调用方式:import re
- re 库采用raw string类型表示正则表达式,rawstring是不包含对转义符再次转义的字符串。例如:r'[1‐9]\d{5}’
- re库也可以采用string类型表示正则表达式,但更繁琐,例如“'[1‐9]\\d{5}'”
- 当正则表达式包含转义符时,建议使用raw string
主要功能函数有:
| 函数 | 说明 |
| re.seach() | 扫描整个字符串并返回第一个成功的匹配 |
| re.match() | 尝试从字符串的起始位置匹配一个模式 |
| re.fullmatch() | 完全匹配,即从字符串开始到结束都能匹配正则表达式 |
| re.findall() | 在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果有多个匹配模式,则返回元组列表,如果没有找到匹配的,则返回空列表。 |
| re.finditer() | 和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。 |
| re.split() | 按照能够匹配的子串将字符串分割后返回列表 |
| re.sub() re.subn() | 替换掉所有匹配正则表达式的子串 |
| re.compile() | 编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。 |
re.seach()
re.search(pattern, string, flags=0)
参数说明:
- pattern:匹配的正则表达式
- string:要匹配的字符串。
- flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
扫描整个字符串并返回第一个成功的匹配。
>>> import re
>>> re.search('www', 'www.csdn.net')
<re.Match object; span=(0, 3), match='www'>
>>> re.search('www', 'www.csdn.net').span()
(0, 3)
>>> re.search('csdn', 'www.csdn.net').span()
(4, 8)
从上面的例子可以看到,search()返回的是re.Match对象。
标志位
正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:
| 标志位 | 描述 |
|---|---|
| re.I | 使匹配对大小写不敏感 |
| re.L | 做本地化识别(locale-aware)匹配 |
| re.M | 多行匹配,影响 ^ 和 $ |
| re.S | 使 . 匹配包括换行在内的所有字符 |
| re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. |
| re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。 |
re.match()
re.match(pattern, string, flags=0)
参数说明:
- pattern:匹配的正则表达式
- string:要匹配的字符串。
- flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
re.match与re.search的区别
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
>>> re.match('www', 'www.csdn.net').span()
(0, 3)
>>> re.match('csdn', 'www.csdn.net').span()
Traceback (most recent call last):File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'span'
re.Match
由成功的 match 和 search 所返回的匹配对象。
主要方法和属性:
| 方法和属性名 | 说明 |
| Match.span([group]) | 对于一个匹配 m , 返回一个二元组 (m.start(group), m.end(group)) 。 注意如果 group 没有在这个匹配中,就返回 (-1, -1) 。group 默认为0,就是整个匹配。 |
| Match.groups(default=None) | 返回一个元组,包含所有匹配的子组,在样式中出现的从1到任意多的组合。 default 参数用于不参与匹配的情况,默认为 None。 |
| Match.start([group]) Match.end([group]) | 返回 group 匹配到的字串的开始和结束标号。group 默认为0(意思是整个匹配的子串)。如果 group 存在,但未产生匹配,就返回 -1 。对于一个匹配对象 m, 和一个未参与匹配的组 g ,组 g (等价于 m.group(g))产生的匹配是m.string[m.start(g):m.end(g)] |
| Match.expand(template) | 对 template 进行反斜杠转义替换并且返回,就像 sub() 方法中一样。转义如同 \n 被转换成合适的字符,数字引用(\1, \2)和命名组合(\g<1>, \g<name>) 替换为相应组合的内容。 |
| Match.group([group1, ...]) | 返回一个或者多个匹配的子组。如果只有一个参数,结果就是一个字符串,如果有多个参数,结果就是一个元组(每个参数对应一个项),如果没有参数,组1默认到0(整个匹配都被返回)。 如果一个组N 参数值为 0,相应的返回值就是整个匹配字符串;如果它是一个范围 [1..99],结果就是相应的括号组字符串。如果一个组号是负数,或者大于样式中定义的组数,就引发一个 IndexError 异常。如果一个组包含在样式的一部分,并被匹配多次,就返回最后一个匹配。 |
| Match.__getitem__(g) | 等价于 m.group(g) |
| Match.groupdict(default=None) | 返回一个字典,包含了所有的 命名 子组。key就是组名。 default 参数用于不参与匹配的组合;默认为 None。 |
| Match.pos | pos 的值,会传递给 search() 或 match() 的方法 a 正则对象 。这个是正则引擎开始在字符串搜索一个匹配的索引位置。 |
| Match.endpos | endpos 的值,会传递给 search() 或 match() 的方法 a 正则对象 。这个是正则引擎停止在字符串搜索一个匹配的索引位置。 |
| Match.lastindex | 捕获组的最后一个匹配的整数索引值,或者 None 如果没有匹配产生的话。比如,对于字符串 'ab',表达式 (a)b, ((a)(b)), 和 ((ab)) 将得到 lastindex == 1 , 而 (a)(b) 会得到 lastindex == 2 。 |
| Match.lastgroup | 最后一个匹配的命名组名字,或者 None 如果没有产生匹配的话。 |
| Match.re | 返回产生这个实例的 正则对象 , 这个实例是由 正则对象的 match() 或 search() 方法产生的。 |
| Match.string | 传递到 match() 或 search() 的字符串。 |
注意:group在Match中是一个非常重要的概念,它是通过小括号匹配出来的一段,而不是多个匹配的串。
>>> m=re.match(r'(\d{4})[/-](\d{2})[/-](\d{2})', '2023-09-17 && 2022-08-11')
>>> m
<re.Match object; span=(0, 10), match='2023-09-17'>
>>> m.groups()
('2023', '09', '17')
上面的例子可以看到,string中有两个可以匹配上的子串,但match只匹配了第一个子串,而所谓的组就是这个匹配的串中,如果在正则表达式中有小括号,则表示的是小括号的匹配子串。如果正则表达式中没有小括号来分组,就不会有groups的内容。
>>> m=re.match(r'\d{4}[/-]\d{2}[/-]\d{2}', '2023-09-17 && 2022-08-11')
>>> m
<re.Match object; span=(0, 10), match='2023-09-17'>
>>> m.groups()
()
groups表示的是匹配的字符串元组,group是指定取其中的一个,也可以通过[]按下标去取,如果取第0个,会把所有的都取出来。
>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
>>> m.group(0)
'Isaac Newton'
>>> m.group(1)
'Isaac'
>>> m[0]
'Isaac Newton'
>>> m[1]
'Isaac'
>>> m[2]
'Newton'
>>> m[3]
Traceback (most recent call last):File "<stdin>", line 1, in <module>
IndexError: no such group
>>> m.groups()
('Isaac', 'Newton')
>>> m.lastindex
2
>>> m.lastgroup
>>> m.re
re.compile('(\\w+) (\\w+)')
>>> m.string
'Isaac Newton, physicist’
>>> m.span()
(0, 12)
>>> m.span(1)
(0, 5)
>>> m.start()
0
>>> m.end()
12
>>> m.end(1)
5
>>> m.groupdict()
{}
>>> m.pos
0
>>> m.endpos
23
re.fullmatch()
re.fullmatch(pattern, string, flags=0)
参数:
- pattern:匹配的正则表达式
- string:要匹配的字符串。
- flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等
如果整个 string 与此正则表达式匹配,则返回相应的 Match。 如果字符串与模式不匹配则返回 None;请注意这与零长度匹配是不同的。
>>> re.fullmatch('o[gh]', 'dog')
>>> m = re.fullmatch('o[gh]', 'dog')
>>> m
>>> m = re.fullmatch('o[gh]', 'ogg')
>>> m
>>> m = re.fullmatch('o[gh]', 'oh')
>>> m
<re.Match object; span=(0, 2), match='oh'>
re.findall()
re.findall(pattern, string, flags=0)
参数:
- pattern:匹配的正则表达式
- string:要匹配的字符串。
- flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等
在字符串中找到正则表达式所匹配的所有子串(不是Match对象),并返回一个列表,如果有多个匹配模式,则返回元组列表,如果没有找到匹配的,则返回空列表。
注意: match 和 search 是匹配一次,而 findall是匹配所有。
>>> m = re.findall(r'\d+', 'python3 c++2 Java18')
>>> m
['3', '2', '18']
>>> type(m)
<class 'list'>
>>> re.findall("(ab)*","aabz1144c")
['', 'ab', '', '', '', '', '', '', '']
>>> re.findall("(ab)+","aabz1144c")
['ab']
re.finditer()
和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。
re.finditer(pattern, string, flags=0)
参数说明:
- pattern:匹配的正则表达式
- string:要匹配的字符串。
- flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
import reit = re.finditer(r'\d+', 'abc123efg5994&&&*987---')
print(type(it))
for m in it:print(m)‘’’
<class 'callable_iterator'>
<re.Match object; span=(3, 6), match='123'>
<re.Match object; span=(9, 13), match='5994'>
<re.Match object; span=(17, 20), match='987’>
’‘’
re.split()
按照能够匹配的子串将字符串分割后返回列表
re.split(pattern, string[, maxsplit=0, flags=0])
参数说明:
- pattern:匹配的正则表达式
- string:要匹配的字符串。
- maxsplit:分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数。
- flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
>>> re.split(r'\W+', 'python.org,Python-c,PYTHON+JAVA.python*',0,re.I)
['python', 'org', 'Python', 'c', 'PYTHON', 'JAVA', 'python', '']
>>> re.split(r'\d', 'one1two2three3four4')
['one', 'two', 'three', 'four', '']
>>> re.split(r'\d', 'one1two20three3four4')
['one', 'two', '', 'three', 'four', '']
>>> re.split(r'\d+', 'one1two20three3four4')
['one', 'two', 'three', 'four', '']
>>> re.split(r'\b', 'one two cc three four')
['', 'one', ' ', 'two', ' ', 'cc', ' ', 'three', ' ', 'four', '']
>>> re.split(r' ', 'one two cc three four')
['one', 'two', 'cc', 'three', 'four']
re.sub()
re.sub(pattern, repl, string, count=0, flags=0)
参数说明:
- pattern : 正则表达式
- repl : 替换的字符串,也可为一个函数。
- string : 要被查找替换的原始字符串。
- count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
import rephone = "081-956-559 # 这是一个国外电话号码"# 删除字符串中的 Python注释
num = re.sub(r'#.*$', '', phone)
print("电话号码是: ", num) #电话号码是: 081-956-559# 删除非数字(-)的字符串
num = re.sub(r'\D', '', phone)
print("电话号码是 : ", num) #电话号码是 : 081956559
如果 repl 是一个函数,则它会针对每次 pattern 的非重叠出现的情况被调用。 该函数接受单个 Match 参数,并返回替换字符串。 例如:
import re# 将匹配的数字乘以 2
def double(matched):value = int(matched.group('value'))return str(value * 2)s = 'A23G4HFD567'
print(re.sub('(?P<value>\d+)', double, s))‘’'
A46G8HFD1134
‘''
re.subn()
行为与 sub() 相同,但是返回一个元组 (字符串, 替换次数).
re.subn(pattern, repl, string, count=0, flags=0)
re.compile()
用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。 re.compile(pattern[, flags])
参数说明:
- pattern : 一个字符串形式的正则表达式
- flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
>>>import re
>>> pattern = re.compile(r'\d+') # 用于匹配至少一个数字
>>> m = pattern.match('one12twothree34four') # 查找头部,没有匹配
>>> print m
None
>>> m = pattern.match('one12twothree34four', 2, 10) # 从'e'的位置开始匹配,没有匹配
>>> print m
None
>>> m = pattern.match('one12twothree34four', 3, 10) # 从'1'的位置开始匹配,正好匹配
>>> print m # 返回一个 Match 对象
<_sre.SRE_Match object at 0x10a42aac0>
>>> m.group(0) # 可省略 0
'12'
>>> m.start(0) # 可省略 0
3
>>> m.end(0) # 可省略 0
5
>>> m.span(0) # 可省略 0
(3, 5)
class re.Pattern
由 re.compile() 返回的已编译正则表达式对象。
主要的属性和方法有:
Pattern.search(string[, pos[, endpos]])
扫描整个 string 查找该正则表达式产生匹配的第一个位置,并返回相应的 Match。 如果字符串中没有与模式匹配的位置则返回 None;请注意这不同于在字符串的某个位置上找到零长度匹配。
可选的第二个参数 pos 给出了字符串中开始搜索的位置索引;默认为 0,它不完全等价于字符串切片; '^' 样式字符匹配字符串真正的开头,和换行符后面的第一个字符,但不会匹配索引规定开始的位置。
可选参数 endpos 限定了字符串搜索的结束;它假定字符串长度到 endpos , 所以只有从 pos 到 endpos - 1 的字符会被匹配。如果 endpos 小于 pos,就不会有匹配产生;另外,如果 rx 是一个编译后的正则对象, rx.search(string, 0, 50) 等价于 rx.search(string[:50], 0)。
>>>pattern = re.compile("d")
>>>pattern.search("dog") # Match at index 0
<re.Match object; span=(0, 1), match='d'>
>>>pattern.search("dog", 1) # No match; search doesn't include the "d"
Pattern.match(string[, pos[, endpos]])
如果字符串 开头 的零个或多个字符与此正则表达式匹配,则返回相应的 Match。 如果字符串与模式不匹配则返回 None;请注意这与零长度匹配是不同的。
可选参数 pos 和 endpos 与 search() 含义相同。
>>>pattern = re.compile("o")
>>>pattern.match("dog") # No match as "o" is not at the start of "dog".
>>>pattern.match("dog", 1) # Match as "o" is the 2nd character of "dog".
<re.Match object; span=(1, 2), match='o'>
Pattern.fullmatch(string[, pos[, endpos]])
如果整个 string 与此正则表达式匹配,则返回相应的 Match。 如果字符串与模式不匹配则返回 None;请注意这与零长度匹配是不同的。
可选参数 pos 和 endpos 与 search() 含义相同。
>>>pattern = re.compile("o[gh]")
>>>pattern.fullmatch("dog") # No match as "o" is not at the start of "dog".
>>>pattern.fullmatch("ogre") # No match as not the full string matches.
>>>pattern.fullmatch("doggie", 1, 3) # Matches within given limits.
<re.Match object; span=(1, 3), match='og'>
Pattern.split(string, maxsplit=0)
等价于 split() 函数,使用了编译后的样式。
Pattern.findall(string[, pos[, endpos]])
类似函数 findall() , 使用了编译后样式,但也可以接收可选参数 pos 和 endpos ,限制搜索范围,就像 search()。
Pattern.finditer(string[, pos[, endpos]])
类似函数 finditer() , 使用了编译后样式,但也可以接收可选参数 pos 和 endpos ,限制搜索范围,就像 search()。
Pattern.sub(repl, string, count=0)
等价于 sub() 函数,使用了编译后的样式。
Pattern.subn(repl, string, count=0)
等价于 subn() 函数,使用了编译后的样式。
Pattern.flags
正则匹配标记。这是可以传递给 compile() 的参数,任何 (?…) 内联标记,隐性标记比如 UNICODE 的结合。
Pattern.groups
捕获到的模式串中组的数量。
Pattern.groupindex
映射由 (?P<id>) 定义的命名符号组合和数字组合的字典。如果没有符号组,那字典就是空的。
Pattern.pattern
编译对象的原始样式字符串。
re.escape(pattern)
转义 pattern 中的特殊字符。如果你想对任意可能包含正则表达式元字符的文本字符串进行匹配,它就是有用的。
>>>print(re.escape('https://www.python.org'))
https://www\.python\.org>>>legal_chars = string.ascii_lowercase + string.digits + "!#$%&'*+-.^_`|~:"
>>>print('[%s]+' % re.escape(legal_chars))
[abcdefghijklmnopqrstuvwxyz0123456789!\#\$%\&'\*\+\-\.\^_`\|\~:]+>>>operators = ['+', '-', '*', '/', '**']
>>>print('|'.join(map(re.escape, sorted(operators, reverse=True))))
/|\-|\+|\*\*|\*
re.purge()
清除正则表达式的缓存。
常用正则表达式
邮箱
包含大小写字母,下划线,阿拉伯数字,点号,中划线
表达式:
[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(?:\.[a-zA-Z0-9_-]+)
>>> re.match(r'[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(?:\.[a-zA-Z0-9_-]+)', 'ssxw@qq.com')
<re.Match object; span=(0, 11), match='ssxw@qq.com'>
>>> re.search(r'[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(?:\.[a-zA-Z0-9_-]+)', 'my email is ssxw@qq.com.')
<re.Match object; span=(12, 23), match='ssxw@qq.com'>
身份证号码
xxxxxx yyyy MM dd 375 0 十八位
- 地区: [1-9]\d{5}
- 年的前两位: (18|19|([23]\d)) 1800-2399
- 年的后两位: \d{2}
- 月份: ((0[1-9])|(10|11|12))
- 天数: (([0-2][1-9])|10|20|30|31) 闰年不能禁止29+
- 三位顺序码: \d{3}
- 两位顺序码: \d{2}
- 校验码: [0-9Xx]
表达式:
[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]
>>> re.match(r'[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]', '450104197710101516')
<re.Match object; span=(0, 18), match='450104197710101516'>
国内手机号码
手机号都为11位,且以1开头,第二位一般为3、5、6、7、8、9 ,剩下八位任意数字
例如:13987692110、15610098778
表达式:
1(3|4|5|6|7|8|9)\d{9}
>>> re.search(r'1(3|4|5|6|7|8|9)\d{9}', '我的手机号为:17910880306,希望常联系')
<re.Match object; span=(7, 18), match='17910880306'>
国内固定电话
区号3\~4位,号码7\~8位
例如:0571-1234567、010-87654321
表达式:
\d{3}-\d{8}|\d{4}-\d{7}
>>> re.search(r'\d{3}-\d{8}|\d{4}-\d{7}', 'Our phone number is 010-68820403. Welcome to inquire')
<re.Match object; span=(20, 32), match='010-68820403'>
域名
包含http:\\或https:\\
表达式:
(?:(?:http:\/\/)|(?:https:\/\/))?(?:[\w](?:[\w\-]{0,61}[\w])?\.)+[a-zA-Z]{2,6}(?:\/)?
>>> re.search(r'(?:(?:http:\/\/)|(?:https:\/\/))?(?:[\w](?:[\w\-]{0,61}[\w])?\.)+[a-zA-Z]{2,6}(?:\/)?', 'The official website address of Python is http://www.python.org')
<re.Match object; span=(42, 63), match='http://www.python.org'>
IP地址
IP地址的长度为32位(共有2^32个IP地址),分为4段,每段8位,用十进制数字表示
每段数字范围为0~255,段与段之间用句点隔开
表达式:
((?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d))
>>> re.search(r'((?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d))', 'IP192.168.1.4')
<re.Match object; span=(2, 13), match='192.168.1.4'>
日期
常见日期格式:yyyyMMdd、yyyy-MM-dd、yyyy/MM/dd、yyyy.MM.dd
表达式:
\d{4}(?:-|\/|.)\d{1,2}(?:-|\/|.)\d{1,2}
>>> re.search(r'\d{4}(?:-|\/|.)\d{1,2}(?:-|\/|.)\d{1,2}', 'Yesterday2023-9-17, was a sad day')
<re.Match object; span=(9, 18), match='2023-9-17'>
国内邮政编码
我国的邮政编码采用四级六位数编码结构
前两位数字表示省(直辖市、自治区)
第三位数字表示邮区;第四位数字表示县(市)
最后两位数字表示投递局(所)
表达式:
[1-9]\d{5}(?!\d)
>>> re.search(r'[1-9]\d{5}(?!\d)', 'BEIJING100073')
<re.Match object; span=(7, 13), match='100073'>
中文字符
表达式:
[\u4e00-\u9fa5]
>>> re.search(r'[\u4e00-\u9fa5]+', 'name:李寻欢')
<re.Match object; span=(5, 8), match='李寻欢'>
>>>
数字
- 验证数字:
^[0-9]*$ - 验证n位的数字:
^\d{n}$ - 验证至少n位数字:
^\d{n,}$ - 验证m-n位的数字:
^\d{m,n}$ - 验证零和非零开头的数字:
^(0|[1-9][0-9]*)$ - 验证有两位小数的正实数:
^[0-9]+(.[0-9]{2})?$ - 验证有1-3位小数的正实数:
^[0-9]+(.[0-9]{1,3})?$ - 验证非零的正整数:
^\+?[1-9][0-9]*$ - 验证非零的负整数:
^\-[1-9][0-9]*$ - 验证非负整数(正整数 + 0)
^\d+$ - 验证非正整数(负整数 + 0)
^((-\d+)|(0+))$ - 整数:
^-?\d+$ - 非负浮点数(正浮点数 + 0):
^\d+(\.\d+)?$ - 正浮点数
^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$ - 非正浮点数(负浮点数 + 0)
^((-\d+(\.\d+)?)|(0+(\.0+)?))$ - 负浮点数
^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$ - 浮点数
^(-?\d+)(\.\d+)?$
字符串
- 英文和数字:
^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$ - 长度为3-20的所有字符:
^.{3,20}$ - 由26个英文字母组成的字符串:
^[A-Za-z]+$ - 由26个大写英文字母组成的字符串:
^[A-Z]+$ - 由26个小写英文字母组成的字符串:
^[a-z]+$ - 由数字和26个英文字母组成的字符串:
^[A-Za-z0-9]+$ - 由数字、26个英文字母或者下划线组成的字符串:
^\w+$ 或 ^\w{3,20}$ - 中文、英文、数字包括下划线:
^[\u4E00-\u9FA5A-Za-z0-9_]+$ - 中文、英文、数字但不包括下划线等符号:
^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$ - 可以输入含有^%&',;=?$\”等字符:
[^%&',;=?$\x22]+ - 禁止输入含有\~的字符:
[^~\x22]+
相关文章:
Python正则表达式(re)
正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为regex、regexp或RE),是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为…...
【PyTorch 08】如果要手动安装对应的包
例如有时候我们要下载 PyG ,但是需要手动下载,需要进行以下步骤: 网站链接:https://data.pyg.org/whl/ 首先查看当前安装好的Pytorch版本和对应的cuda版本 1. pip list:查看torch版本 2. torch.version.cuda…...
黑马JVM总结(十二)
(1)五种引用_强软弱 实线箭头表示强引用,虚心线表示软弱虚终结器引用 在平时我们用的引用,基本都为强引用 ,比如说创建一个对象通过运算符赋值给了一个变量,那么这个变量呢就强引用了刚刚的对象 强引用的…...
彻底搞懂线程池原理以及创建方式
1. 为什么要使用线程池 在实际使用中,线程是很占用系统资源的,如果对线程管理不善很容易导致系统问题。因此,在大多数并发框架中都会使用线程池来管理线程,使用线程池管理线程主要有如下好处: 降低资源消耗。通过复用…...
FreeSWITCH 1.10.10 简单图形化界面9 - 鼎兴FXO网关SIP中继内网IPPBX落地
FreeSWITCH 1.10.10 简单图形化界面9 - 鼎兴FXO网关SIP中继内网IPPBX落地 0、 界面预览1、创建一个话务台2、创建PBX SIP中继并设置呼入权限3、设置呼出规则4、设置分机呼出权限5、设置FXO 网关相关信息6、设置FXO网关端口组呼入号码7、设置FXO网关的SIP中继8、设置FXO网关呼叫…...
Oracle数据如何迁移导入到MySQL
使用Navicat工具建立数据连接,进行数据传输 1、打开Navicat工具,分别连接Oracle数据库和MySQL数据库。 2、连接源选择你的oracle数据,目标选mysql 即可成功导入...
卡尔曼滤波(Kalman Filter)原理浅析-数学理论推导-1
目录 前言数学理论推导1. 递归算法2. 数学基础结语参考 前言 最近项目需求涉及到目标跟踪部分,准备从 DeepSORT 多目标跟踪算法入手。DeepSORT 中涉及的内容有点多,以前也就对其进行了简单的了解,但是真正去做发现总是存在这样或者那样的困惑…...
Linux 文件创建、查看
touch、cat、more命令 ①touch命令——创建文件 ②cat命令——查看文件内容全部显示 这是txt.txt文件内容 使用cat命令查看 ③more命令——查看文件内容支持翻页 在查看的过程中,通过空格翻页,通过q退出查看...
WPF 如何让xmal的属性换行显示 格式化
WPF 如何让UI的xmal 按照下面的格式化显示 首先格式化显示在VS中的快捷键是 Ctrl KD 然后需要配置,工具 选项 -文本编辑器 -xmal -格式化-间距 更改成如下就可以了...
Linux学习之MySQL主从复制
MySQL配置一主一从 环境准备: 两台服务器: Master:192.168.88.53,Slave:192.168.88.54 在两台服务器上安装mysql-server # 配置主服务器192.168.88.53 # 启用binlog日志 [rootmysql53 ~]# yum -y install mysql-ser…...
【JavaSE笔记】抽象类与接口
一、抽象类 1、概念 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。 package demo2…...
详谈操作系统中的内核态和用户态
不知道大家有没有思考过这样一个问题:什么是处理器(CPU)的状态?🤔 其实CPU和人一样,没有执行程序的时候,是没有什么状态的,当它执行的程序是用户程序的时候就叫用户态,当执行的程序是操作系统的代码时就叫系统态或者内…...
OpenWrt KernelPackage分析
一. 前言 KernelPackage是OpenWrt用来编译内核模块的函数,其实KernelPackage后面会调用BuildPackage,这里会一块将BuildPackage也顺便分析,本文以gpio-button-hotplug驱动模块为例,讲解整个编译过程。 gpio-button-hotplug驱动编译…...
第 363 场 LeetCode 周赛题解
A 计算 K 置位下标对应元素的和 模拟 class Solution { public:int pop_cnt(int x) {//求x的二进制表示中的1的位数int res 0;for (; x; x >> 1)if (x & 1)res;return res;}int sumIndicesWithKSetBits(vector<int> &nums, int k) {int res 0;for (int i…...
ffplay源码解析-main入口函数
main入口函数 初始化 变量、缓存区、SDL窗口初始化等 int main(int argc, char **argv) {int flags;VideoState *is; // av_log_set_level(AV_LOG_TRACE);init_dynload();av_log_set_flags(AV_LOG_SKIP_REPEATED);parse_loglevel(argc, argv, options);/// av_log_set_le…...
这些Coding套路你不会还不知道吧?
对于一名程序员来说,编码进阶是成为优秀工程师非常重要的一步,它可以让我们更加熟练地掌握编程,深入理解数据结构和算法,从而更好地完成复杂的任务,提高工作效率。而我认为熟练使用设计模式就是编码进阶的最好方式之一…...
Spring Boot深度解析:快速开发的秘密
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…...
mysql数据库备份(mysqldump)
mysqldump命令备份数据 mysqldump -u root -p --databases 数据库1 数据库2 > xxx.sqlmysqldump常用操作示例 1. 备份全部数据库的数据和结构 mysqldump -uroot -p123456 -A > /data/mysqlbackup/mydb.sql2. 备份全部数据库的结构(加 -d 参数) …...
linux Nginx+Tomcat负载均衡、动静分离
linux NginxTomcat负载均衡、动静分离 1、Tomcat的基本介绍1.1Tomcat是什么?1.2Tomcat的构成组件1.3Tomcat的核心功能1.4Tomcat请求过程 2、Tomcat部署2.1安装tomcat2.2优化tomcat启动速度2.4主要目录说明 3、Tomcat 虚拟主机配置3.1创建fsj和mws项目目录和文件3.2修…...
ts 枚举类型原理及其应用详解
ts 枚举类型介绍 TypeScript的枚举类型是一种特殊的数据类型,它允许开发者为一组相关值定义一个共同的名称,使我们可以更清晰、更一致地使用这些值。 枚举类型在TypeScript中用enum关键字定义,每个枚举值默认都是数字类型,从0开…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...
