特殊字符转义
以下字符都需要用 反斜线(\)来进行特殊字符的转义。
\n - 换行符
\t - 制表符
\ - 反斜线本身
. - 点号(任意单个字符)
星号(0次或多次重复前面的元素)
加号(1次或多次重复前面的元素)
? - 问号(零次或一次重复前面的元素)
[] - 方括号内的任何字符集合
() - 分组操作符
{} - 花括号内指定数量的重复次数
起因,python正则匹配,从'你好aaa+'匹配‘aaa+’,我就想完整的匹配aaa+,但是实际效果是'你好a'这种的也能匹配上。
debug发现原来+在正则中是特殊字符。如果要匹配 +
字符本身,你需要使用反斜杠 \
对它进行转义。即遇见 + 的pattern用 /+ 来替换,
modified_string = original_string.replace("+", "/+")
‘aaa+’被解释为:匹配前面的字符 'aaa'
一次或多次。
import re
re.search('aaa+', 'a') # none
re.search('aaa+', 'aaab') # <_sre.SRE_Match object; span=(0, 3), match='aaa'>
re.search('aaa+', 'ab') # none
re.search('aaa+', 'aab') # none
re.search('aaa+', 'aaaaaab') # <_sre.SRE_Match object; span=(0, 6), match='aaaaaa'>
re.match() 与 re.search() 的区别
1. `re.match()`:
- `re.match()` 用于从字符串的起始位置开始匹配正则表达式。
- 如果匹配成功,`re.match()` 返回一个匹配对象;如果匹配失败,它返回 `None`。
- 它只匹配字符串的第一个子串,也就是说,它不会扫描整个字符串,而是在找到第一个匹配项后停止。
re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。
2. `re.search()`:
- `re.search()` 用于在字符串中扫描正则表达式,并返回第一个匹配项。
- 如果匹配成功,`re.search()` 返回一个匹配对象;如果匹配失败,它返回 `None`。
- 它会扫描整个字符串,直到找到第一个匹配项为止。
简而言之,`re.match()` 通常用于检查字符串的起始部分是否与正则表达式匹配,而 `re.search()` 用于在整个字符串中查找匹配项。下面是一个示例,展示这两个函数的区别:
总结:search()更符合需求。
import re
# 示例字符串
text = "这是一个测试字符串,包含多个部分。"
# 正则表达式
pattern1 = r'测试'
pattern2 = r'多个部分'
# 使用re.match()
match1 = re.match(pattern1, text)
match2 = re.match(pattern2, text)
print(f"match1: {match1}") # match1: None
print(f"match2: {match2}") # match2: None
# 使用re.search()
search1 = re.search(pattern1, text)
search2 = re.search(pattern2, text)
print(f"search1: {search1}") # search1: <_sre.SRE_Match object; span=(4, 6), match='测试'>
print(f"search2: {search2}") # search2: <_sre.SRE_Match object; span=(12, 16), match='多个部分'>
re.search()与 re.findall() 的区别
re.search(pattern, string, flags=0)
- re.search() 函数用于搜索字符串中是否有匹配正则表达式的部分。
- re.search() 通常用于检查一个字符串是否包含某个模式,或者找到匹配模式的第一个位置。
re.findall(pattern, string, flags=0)
- re.findall() 函数用于找到字符串中所有匹配正则表达式的部分,并返回一个列表。
- 它返回所有匹配项的列表,如果没有找到任何匹配项,则返回空列表。
- re.findall() 通常用于提取字符串中所有匹配模式的部分。
总结一下,re.search() 用于查找单个匹配项,而 re.findall() 用于查找所有匹配项。
如果你只需要找到第一个匹配项,可以使用 re.search();如果你需要找到所有匹配项,应该使用 re.findall()。
注意: match 和 search 是匹配一次 findall 匹配所有。
re.findall()
matches = re.findall(pattern, str)
text = '这是一款项链含有很多配件例如吊坠你肯定觉得很好'
res = re.findall(r'项链|吊坠', text)
res # ['项链', '吊坠']
re.sub()
# 将str中匹配到的pattern部分替换为''
new_str = re.sub(pattern, '', str)
re.compile()
compile2个()是什么意思?组合的意思,括号1+括号2组成一个匹配模式。
e.g. case分析
(.卖店|(官方)?旗舰店|专营店|专卖)
- . 表示任何单个字符(除了换行符)。
- 卖店、(官方)?旗舰店、专营店 或 专卖:这些是不同的选项,匹配与之相匹配的字符串。
- 括号 () 用于组匹配,() 中的表达式可以作为一个组一起被引用。
- (官方)? 表示“官方”这个词是可选的,? 表示前面的元素出现零次或一次。
pattern = re.compile("(.{0,30})(.卖店|(官方)?旗舰店|专营店|专卖)")
# |是或的意思,“.卖店” or “(官方)?旗舰店” 都匹配了一次
# (.{0,30}) 是在“.卖店” or “(官方)?旗舰店”,前最多出现30个字符。
mystr = '官方旗舰店是卖店'
find_all = re.findall(pattern, mystr)
find_all # [('官方旗舰店', '是卖店', '')]
# '这是一'????
mystr = '这是一个卖店'
find_all = re.findall(pattern, mystr)
find_all # [('这是一', '个卖店', '')]
# “.卖店” or “专营店” 都匹配了一次
mystr = '专营店是卖店'
find_all = re.findall(pattern, mystr)
find_all # [('专营店', '是卖店', '')]
# 不 从哪来?
mystr = '专卖不是卖店'
find_all = re.findall(pattern, mystr)
find_all # [('专卖不', '是卖店', '')]
# .是必须要匹配一个字符的
mystr = '卖店这是一个'
find_all = re.findall(pattern, mystr)
find_all # []
mystr = '旗舰店是卖店这不是官方'
find_all = re.findall(pattern, mystr)
find_all # [('旗舰店', '是卖店', '')]
case2, 其实没太理解
第一个()感觉有和没有没区别。
但是匹配的字符串,必须要以第二个括号里的词结束。
pattern = re.compile("(去|厨房卫浴|^)(.卖店|(官方)?旗舰店|专营店|专卖)") # 2个()什么意思?
mystr = '去迭戈'
find_all = re.findall(pattern, mystr)
find_all # []
# ------------------------------------------------------------------
mystr = '去迭戈专卖'
find_all = re.findall(pattern, mystr)
print(f"find_all: {find_all}")
print(f"re: {re.search(pattern, mystr)}")
find_all: [('去', '专卖', '')]
re: <_sre.SRE_Match object; span=(0, 3), match='去专卖'>
# ------------------------------------------------------------------
mystr = 'c去迭戈专卖'
find_all = re.findall(pattern, mystr)
print(f"find_all: {find_all}")
print(f"re: {re.search(pattern, mystr)}")
find_all: [('c去迭戈', '专卖', '')]
re: <_sre.SRE_Match object; span=(0, 6), match='c去迭戈专卖'>
# ------------------------------------------------------------------
mystr = '专卖'
find_all = re.findall(pattern, mystr)
print(f"find_all: {find_all}")
print(f"re: {re.search(pattern, mystr)}")
find_all: [('', '专卖', '')]
re: <_sre.SRE_Match object; span=(0, 2), match='专卖'>
常用匹配符
模式 | 描述 |
---|---|
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
. | 匹配任意字符 |
* | 匹配前面的字符零次或多次 |
+ | 匹配前面的字符一次或多次 |
? | 匹配前面的字符零次或一次 |
[] | 匹配括号中列举的任意一个字符 |
[^] | 匹配除了括号中列举的字符以外的任意一个字符 |
其他匹配1-n个,见python str 正则匹配两个标点符号之间的内容 python正则匹配多个数字_lanhy的技术博客_51CTO博客
^说明
^
是一个特殊字符,它表示“匹配输入字符串的开始位置”。具体来说,当 ^
与一个字符集或字符串前缀相结合时,它表明匹配必须从该字符集或字符串的开始处发生。
以下是一些使用 ^
的例子:
^abc
:匹配任何以 "abc" 开头的字符串。^A
:匹配任何以大写字母 'A' 开头的字符串。^[a-z]
:匹配任何以小写字母开头的字符串。^[0-9]
:匹配任何以数字开头的字符串。
需要注意的是,^
只在正则表达式的第一个字符位置有特殊含义。如果在正则表达式中它不是第一个字符,它就仅仅是一个普通的字符,而不是表示行的开始。例如,在 a^b
中,^
只是字符 '^' 本身,而不是特殊符号。
*、+、?的用法
* :——表示匹配前面的字符0个或多个; + :——表示前面的字符1个或多个; ?:——(1)放在其他字符后面:表示匹配0次或1次; (2)放在*、+后面:表示匹配尽可能少的字符 举例, 字符串fooooo: fo*和fo+:表示匹配整个字符串 fo+?:表示匹配fo fo*?:表示匹配f
举例
实践1:匹配12g
pattern = r"\d+\s*[Gg][Bb]?" # 256g, 12g
实践2:匹配12g+12g, 12gb+12gb, 12g+1
pattern = r"\d+\s*[g]?[b]?\+\d+\s*[Gg]?[Bb]?"
希望匹配12g+8, 126gb+8g, 8+126等字符串。
结论
pattern1 = r"\d+\s*[g]?[b]?\+\s*\d+\s*[Gg]?[Bb]?" # '128gb+256gb', '8+256g', '8+128'
matches = re.findall(pattern1, text) # list
print('matches:', matches)
pattern2 = r"\d+\s*[Gg][Bb]?" # 256g, 12g
pattern = r"\d+\s*[mm]" # 20mm
- \d+ 匹配一系列数字。
- \s* 匹配零个或多个空格。
- \+? 匹配零个或一个加号。
- \d+ 再次匹配一系列数字。
- \s* 再次匹配零个或多个空格。
- [Gg] 匹配字母 "G" 无论大小写。
- [Bb]? 匹配零个或一个字母 "B" 无论大小写。
实践3:判断字符串时候含有list中的某个词
rule_set # 很长的一个含各种关键词的set(去重)
rule_pattern = re.compile("|".join(rule_set))
find_rule = re.findall(rule_pattern, text)
if find_rule:
print("匹配到的关键词", find_rule[0])
实践4:匹配整数+小数
pattern = r'\d+\.?\d*' # 匹配小数
text = '今天周二5.0'
digit = re.search(pattern, text)
digit.group() # '5.0'
text = '今天周二5'
digit = re.search(pattern, text)
digit.group() # '5'
text = '今天1.325周二'
digit = re.search(pattern, text)
digit.group() # '1.325'
实践5:匹配模型中加数字
{m,n}
是一个量词,用来指定前面的元素出现的次数范围。
所以,(.{0,30})
表示匹配任意0到30个除换行符之外的任意字符。这意味着这个表达式可以匹配一个空字符串,或者任意数量(最多30个)的任意字符。
e.g. 匹配“今日特价”,今日和特价中间最多出现0-2个字符。
pattern = re.compile("今日.{0,2}特价")
text = '今日特价'
re.search(pattern,text) # <_sre.SRE_Match object; span=(0, 4), match='今日特价'>
text = '今日你好特价'
re.search(pattern,text) # <_sre.SRE_Match object; span=(0, 6), match='今日你好特价'>
text = '今日你好好特价'
re.search(pattern,text) # 无
实践6:非汉字部分全部剔除*
pattern = re.compile(r'[^\u4e00-\u9fff]') # 用于匹配任何不在汉字范围内的 Unicode 字符。
text = '198301周二:'
text_clear = re.sub(pattern, '', text).strip() # 是所有非汉字的字符
text_clear # '周二'
text = ':你好:'
text_clear = re.sub(pattern, '', text).strip() # 是所有非汉字的字符
text_clear # '你好'