Python爬虫(2)正则表达式

re包

1.函数

1)re.match(pattern, string, flags=0)

如果 string 开头的零个或多个字符与正则表达式 pattern 匹配,则返回相应的 
Match。 如果字符串与模式不匹配则返回 None;请注意这与零长度匹配是不同的。表达式的行为可通过指定 flags 值来修改。

import re
str_1 = 'abcd'
str_2 = 'abcdabcd'
str_3 = 'dcab'
res_1 = re.match('ab', str_1)
res_2 = re.match('ab', str_2)
res_3 = re.match('ab', str_3)
print(res_1.group())    # ab
print(res_2.group())    # ab
print(res_3)    # None

2)re.findall(patternstringflags=0)

返回 pattern 在 string 中的所有非重叠匹配,以字符串列表字符串元组列表的形式。对 string 的扫描从左至右,匹配结果按照找到的顺序返回。 空匹配也包括在结果中。返回结果取决于模式中捕获组的数量。如果没有组,返回与整个模式匹配的字符串列表。如果有且仅有一个组,返回与该组匹配的字符串列表。如果有多个组,返回与这些组匹配的字符串元组列表。非捕获组不影响结果。

import re
str_1 = 'abcd'
str_2 = 'abcdabcd'
str_3 = 'dcab'
res_1 = re.findall('ab', str_1)
res_2 = re.findall('ab', str_2)
res_3 = re.findall('ab', str_3)
print(res_1)    # ['ab']
print(res_2)    # ['ab', 'ab']
print(res_3)    # ['ab']

3)re.search(patternstringflags=0)

扫描整个 string 查找正则表达式 pattern 产生匹配的第一个位置,并返回相应的 Match。 如果字符串中没有与模式匹配的位置则返回 None

import re
str_1 = 'abcd'
str_2 = 'abcdabcd'
str_3 = 'dcab'
res_1 = re.search('ab', str_1)
res_2 = re.search('ab', str_2)
res_3 = re.search('ab', str_3)
print(res_1.group())    # ab
print(res_2.group())    # ab
print(res_3.group())    # ab

4)re.fullmatch(patternstringflags=0)

如果整个 string 与正则表达式 pattern 匹配,则返回相应的 Match。 如果字符串与模式不匹配则返回 None

import re
print(re.fullmatch('Hello', 'Hello!'))    # None
print(re.fullmatch('Hello', 'Hello'))    # <re.Match object; span=(0, 5), match='Hello'>

5)re.compile(patternflags=0)

将正则表达式的样式编译为一个正则表达式对象,可以用于匹配。如果需要多次使用这个正则表达式的话,使用re.compile()保存这个正则对象以便复用,可以让程序更加高效。

  • 匹配对象re.Match

  1. Match.group([group1...])   返回一个或者多个匹配的子组。如果只有一个参数,结果就是一个字符串,如果有多个参数,结果就是一个元组(每个参数对应一个项),如果没有参数,组1默认到0(整个匹配都被返回)。 如果一个组N 参数值为 0,相应的返回值就是整个匹配字符串;如果它是一个范围 [1..99],结果就是相应的括号组字符串。
  2. Match.span([group])   对于一个匹配 m , 返回一个二元组 (m.start(group), m.end(group)) 。 注意如果 group 没有在这个匹配中,就返回 (-1, -1) 。group 默认为0,就是整个匹配。

6)re.sub(patternreplstringcount=0flags=0)

返回通过使用 repl 替换在 string 最左边非重叠出现的 pattern 而获得的字符串。 如果样式没有找到,则不加改变地返回 string。 repl 可以是字符串或函数。如为字符串,则其中任何反斜杠转义序列都会被处理。 也就是说,\n 会被转换为一个换行符,\r 会被转换为一个回车符,依此类推。如果 repl 是一个函数,则它会针对每次 pattern 的非重叠出现的情况被调用。 该函数接受单个Match参数,并返回替换字符串。

import re
print(re.sub('hello', 'Hello', 'hello, Oliver!'))    # Hello, Oliver!

def transform_0_1(paramete):
    s = paramete.group()
    if int(s):
        return '1'
    else:
        return '0'
print(re.sub('\d', transform_0_1, '0123456789'))    # 0111111111

7)re.split(patternstringmaxsplit=0flags=0)

用 pattern 分开 string 。 如果在 pattern 中捕获到括号,那么所有的组里的文字也会包含在列表里。如果 maxsplit 非零, 最多进行 maxsplit 次分隔, 剩下的字符全部返回到列表的最后一个元素。如果分隔符里有捕获组合,并且匹配到字符串的开始,那么结果将会以一个空字符串开始。对于结尾也是一样。

import re
print(re.split('\d', 'apple0banana1orange'))    # ['apple', 'banana', 'orange']
print(re.split('\W', 'Oliver, Peter, Steven'))    # ['Oliver', '', 'Peter', '', 'Steven']
print(re.split('\W+', 'Oliver, Peter, Steven'))    # 
['Oliver', 'Peter', 'Steven']
print(re.split('(\W+)', 'Oliver, Peter, Steven'))    # ['Oliver', ', ', 'Peter', ', ', 'Steven']

2.特殊字符

1).

在默认模式下,匹配除换行符以外的任意字符。 如果指定了flags=re.DOTALL ,它将匹配包括换行符在内的任意字符。(?s:.) 将匹配任意字符而无视相关旗标。

import re
str_1 = 'It is Saturday.'
str_2 = 'apple answer'
str_3 = 'blue b\nue blue'
res_1 = re.findall('.....day', str_1)
res_2 = re.findall('a...e', str_2)
res_3 = re.findall('b..e', str_3)
print(res_1)    # ['Saturday']
print(res_2)    # ['apple', 'answe']
print(res_3)    # ['blue', 'blue']

2)*

对它前面的正则式匹配0到任意次重复, 尽量多的匹配字符串。 ab* 会匹配 'a''ab',或者 'a' 后面跟随任意个 'b'

import re
str_1 = 'abcd'
str_2 = 'abbcd'
str_3 = 'acd'
res_1 = re.findall('ab*', str_1)
res_2 = re.findall('ab*', str_2)
res_3 = re.findall('ab*', str_3)
print(res_1)    # ['ab']
print(res_2)    # ['abb']
print(res_3)    # ['a']

3)?

对它前面的正则式匹配0到1次重复。 ab? 会匹配 'a' 或者 'ab'

import re
str_1 = 'a'
str_2 = 'ab'
str_3 = 'abb'
res_1 = re.findall('ab?', str_1)
res_2 = re.findall('ab?', str_2)
res_3 = re.findall('ab?', str_3)
print(res_1)    # ['a']
print(res_2)    # ['ab']
print(res_3)    # ['ab']

4)+

对它前面的正则式匹配1到任意次重复。 ab+ 会匹配 'a' 后面跟随1个以上到任意个 'b',它不会匹配 'a'

import re
str_1 = 'a'
str_2 = 'ab'
str_3 = 'abb'
res_1 = re.findall('ab+', str_1)
res_2 = re.findall('ab+', str_2)
res_3 = re.findall('ab+', str_3)
print(res_1)    # []
print(res_2)    # ['ab']
print(res_3)    # ['abb']

5){}

  • {m} 对它前面的正则式指定匹配 m 次重复;少于 m 的话就会导致匹配失败。比如, a{6} 将匹配6个 'a' , 但是不能是5个。
  • {m,n} 对它前面的正则式进行 m 到 n 次匹配,在 m 和 n 之间取尽量多。 比如,a{3,5} 将匹配 3 到 5个 'a'。忽略 m 意为指定下界为0,忽略 n 指定上界为无限次。 比如 a{4,}b 将匹配 'aaaab' 或者1000个 'a' 尾随一个 'b',但不能匹配 'aaab'。逗号不能省略,否则无法辨别修饰符应该忽略哪个边界。
  • {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})
import re
str_1 = 'aaa'
str_2 = 'aaaa'
str_3 = 'aaaaa'
print(re.findall('a{3}', str_1))    # ['aaa']
print(re.findall('a{4}', str_1))    # []
print(re.findall('a{2,4}', str_2))    # ['aaaa']
print(re.findall('a{2,5}', str_2))    # ['aaaa']
print(re.findall('a{2,3}?', str_2))    # ['aa', 'aa']
print(re.findall('a{2,4}?', str_2))    # ['aa', 'aa']
print(re.findall('a{3,5}+a', str_3))    # []
print(re.findall('a{3,5}a', str_3))    # ['aaaaa']

 6)[]

用于表示一个字符集合。在一个集合中:

  •  字符可以单独列出,比如 [amk] 匹配 'a', 'm', 或者 'k'。 
  •  可以表示字符范围,通过用 '-' 将两个字符连起来。比如 [a-z] 将匹配任何小写ASCII字符, [0-5][0-9] 将匹配从 00 到 59 的两位数字, [0-9A-Fa-f] 将匹配任何十六进制数位。
  •  特殊字符在集合中会失去其特殊意义。比如 [(+*)] 只会匹配这几个字面字符之一 '(''+''*', or ')'。
  •  字符类如 \w 或者 \S 也在集合内被接受,不过它们可匹配的字符则依赖于所使用的flags。
  •  不在集合范围内的字符可以通过取反来进行匹配。如果集合首字符是 '^' ,所有不在集合内的字符将会被匹配,比如 [^5] 将匹配所有字符,除了 '5', [^^] 将匹配所有字符,除了 '^'^ 如果不在集合首位,就没有特殊含义。
import re
str_1 = 'banana'
str_2 = '1 plus 1 equals 2'
str_3 = '1 + 1 = 2'
str_4 = '0123456789'
print(re.findall('[ab]', str_1))    # ['b', 'a', 'a', 'a']
print(re.findall('[0-9a-g]',str_2))    # ['1', '1', 'e', 'a', '2']
print(re.findall('[+=]', str_3))    # ['+', '=']
print(re.findall('[^0]', str_4))    # ['1', '2', '3', '4', '5', '6', '7', '8', '9']

7)^

(插入符) 匹配字符串的开头, 并且在flags=re.MULTILINE模式下也匹配换行后的首个符号。

import re
str_1 = 'abcd'
str_2 = 'dcba'
str_3 = 'apple'
print(re.findall('^a.', str_1))    # ['ab']
print(re.findall('^a.', str_2))    # []
print(re.findall('^a.', str_3))    # ['ap']

8)$

匹配字符串尾或者在字符串尾的换行符的前一个字符,在flags=re.MULTILINE模式下也会匹配换行符之前的文本。

import re
str_1 = 'abcd'
str_2 = 'dcba'
str_3 = 'banana'
print(re.findall('.a$', str_1))    # []
print(re.findall('.a$', str_2))    # ['ba']
print(re.findall('.a$', str_3))    # ['na']

9)|

A|B, A 和 B 可以是任意正则表达式,创建一个正则表达式,匹配 A 或者 B任意个正则表达式可以用 '|' 连接。它也可以在组合(见下列)内使用。扫描目标字符串时, '|' 分隔开的正则样式从左到右进行匹配。当一个样式完全匹配时,这个分支就被接受。意思就是,一旦 A 匹配成功, B 就不再进行匹配,即便它能产生一个更好的匹配。或者说,'|' 操作符绝不贪婪。 

import re
str = 'abcdefg'
print(re.findall('.a|d$', str))    # []
print(re.findall('.a|g$', str))    # ['g']
print(re.findall('a.|d$', str))    # ['ab']
print(re.findall('a.|g$', str))    # ['ab', 'g']

10)\

转义特殊字符(允许你匹配 '*''?', 或者此类其他)。

import re
str = '1 + 1 = 2'
print(re.findall('\+', str))    # ['+']

11)\A

只匹配字符串开始

import re
print(re.findall('\AHello', 'Hello, Oliver!'))    # ['Hello']
print(re.findall('\AHello', 'Oliver, Hello!'))    # []
print(re.findall('\AHello', 'Hi, Oliver!'))    # []

12)\b

字边界。 这是一个零宽度断言,仅在单词的开头或结尾处匹配。 单词被定义为一个字母数字字符序列,因此单词的结尾由空格或非字母数字字符表示。

注:在 Python 的字符串文字中,\b 是退格字符。

import re
print(re.findall(r'\bHello\b', 'Hello, Oliver!'))    # ['Hello']
print(re.findall(r'\bOliver\b', 'Hello, Oliver!'))    # ['Oliver']
print(re.findall(r'\bHello\b', 'HelloOliver'))    # []

13)\B

另一个零宽度断言,这与 \b 相反,仅在当前位置不在字边界时才匹配。

import re
print(re.findall('\BHello\B', 'Hello, Oliver!'))    # []
print(re.findall('\BOliver\B', 'Hello, Oliver!'))    # []
print(re.findall('\BHello\B', 'OliverHelloOliver'))    # ['Hello']

14)\d

匹配任何十进制数字,等价于字符类 [0-9] 。

15)\D

匹配任何非数字字符,等价于字符类 [^0-9] 。

16)\s

匹配任何空白字符,等价于字符类 [\t\n\r\f\v]。

17)\S

匹配任何非空白字符,等价于字符类 [^\t\n\r\f\v] 。

18)\w

匹配任何字母与数字字符,等价于字符类 [a-zA-Z0-9_] 。

19)\W

匹配任何非字母与数字字符,等价于字符类 [^a-zA-Z0-9_] 。

20)\Z

只匹配字符串尾

import re
print(re.findall('Hello\Z', 'Hello, Oliver!'))    # []
print(re.findall('Hello!\Z', 'Oliver, Hello!'))    # ['Hello!']
print(re.findall('Hello\Z', 'Hi, Oliver!'))    # []

21)()

(组合),匹配与括号内的任意正则表达式完全相等的字符串,并标识出组合的开始和结尾。

import re
print(re.findall('(Hello)', 'HelloHiGoodmorningHelloHello'))    # ['Hello', 'Hello', 'Hello']
print(re.findall('(Hello){2}', 'HelloHiGoodmorningHelloHello'))    # ['Hello']

3.匹配模式参数

可使用按位 OR (| 运算符) 进行组合。

1)re.Ire.IGNORECASE常用

忽略大小写

import re
print(re.findall('hello', 'HellohelloHi', flags=re.IGNORECASE))    # ['Hello', 'hello']

2)re.Mre.MULTILINE

在指定之后,模式字符 '^' 将匹配字符串的开始和每一行的开头(紧随在换行符之后);而模式字符 '$' 将匹配字符串的末尾和每一行的末尾(紧接在换行符之前)。

import re
print(re.findall('^Hello', 'Hello, Oliver!\nHello, Peter!'))    # ['Hello']
print(re.findall('^Hello', 'Hello, Oliver!\nHello, Peter!', flags=re.MULTILINE))    # ['Hello', 'Hello']
print(re.findall('Hello!$', 'Oliver, Hello!\nPeter, Hello!'))    # ['Hello!']
print(re.findall('Hello!$', 'Oliver, Hello!\nPeter, Hello!', flags=re.MULTILINE))    # ['Hello!', 'Hello!']

3)re.Sre.DOTALL

使 '.' 特殊字符匹配任意字符,包括换行符。

import re
print(re.findall('Hello!.', 'Oliver, Hello!\nPeter, Hello!'))    # []
print(re.findall('Hello!.', 'Oliver, Hello!\nPeter, Hello!', flags=re.DOTALL))    # ['Hello!\n']

4)re.Are.ASCII

使 \w\W\b\B\d\D\s 和 \S 执行仅限 ASCII 匹配而不是完整的 Unicode 匹配。 这仅对 Unicode (str) 模式有意义,而对字节串模式将被忽略。

5)re.Lre.LOCALE

使 \w\W\b\B 和忽略大小写的匹配依赖于当前语言区域。

6)re.Ure.UNICODE

在 Python 3 中,str 模式默认将匹配 Unicode 字符。 因此这个旗标多余且 无任何效果,仅保留用于向下兼容。

7)re.XVERBOSE

这个旗标允许你通过在视觉上分隔表达式的逻辑段落和添加注释来编写更为友好并更具可读性的正则表达式。 表达式中的空白符会被忽略表达式可以是多行的。除非是在字符类中,或前面有一个未转义的反斜杠,或者是在 *?(?: 或 (?P<...> 等形符之内。

4.常用正则表达式 

查找数字字符串的正则表达式

字符串

正则表达式

数字

^[0-9]$

n位的数字

^\d{n}$

至少n位的数字

^\d{n,}$

m-n位的数字

^\d{m,n}$

零和非零开头的数字

^(0|[1-9][0-9]*)$

非零开头最多带两位小数的数字

^([1-9][0-9]*)+(.[0-9]{1,2})?$

带1-2位小数的正数或负数

^(\-)?\d+(\.\d{1,2})?$

正数、负数、和小数

^(\-|\+)?\d+(\.\d+)?$

有两位小数的正实数

^[0-9]+(.[0-9]{2})?$

有1~3位小数的正实数

^[0-9]+(.[0-9]{1,3})?$

非零的正整数

^[1-9]\d*$ 或

^([1-9][0-9]*){1,3}$ 或

^\+?[1-9][0-9]*$

非零的负整数

^\-[1-9][]0-9"*$ 或

^-[1-9]\d*$

非负整数

^\d+$ 或

^[1-9]\d*|0$

非正整数

^-[1-9]\d*|0$ 或

^((-\d+)|(0+))$

非负浮点数

^\d+(\.\d+)?$ 或

^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$

非正浮点数

^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或

^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$

正浮点数

^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或

^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$

负浮点数

^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或

^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$

浮点数

^(-?\d+)(\.\d+)?$ 或

^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$

查找含有汉字、字母和符号的字符串的正则表达式

字符串

正则表达式

汉字

^[\u4e00-\u9fa5]{0,}$

英文和数字

^[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]+

根据实际用途查找字符串的正则表达式

字符串

正则表达式

Email地址

^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$

域名

[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?

InternetURL

[a-zA-z]+://[^\s]* 或

^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$

手机号码

^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$

电话号码

("XXX-XXXXXXX"、

"XXXX-XXXXXXXX"、

"XXX-XXXXXXX"、

"XXX-XXXXXXXX"、

"XXXXXXX"和"XXXXXXXX)

^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$

国内电话号码

(0511-4405222、021-87888822)

\d{3}-\d{8}|\d{4}-\d{7}

身份证号

(15位、18位数字)

^\d{15}|\d{18}$

短身份证号码

(数字、字母x结尾)

^([0-9]){7,18}(x|X)?$ 或

^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$

帐号是否合法

(字母开头,允许5-16字节,

允许字母数字下划线)

^[a-zA-Z][a-zA-Z0-9_]{4,15}$

密码

(以字母开头,长度在6~18之间,

只能包含字母、数字和下划线)

^[a-zA-Z]\w{5,17}$

强密码

(必须包含大小写字母和数字的组合,

不能使用特殊字符,长度在8-10之间)

^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$ 

日期格式

^\d{4}-\d{1,2}-\d{1,2}

一年的12个月

(01~09和1~12)

^(0?[1-9]|1[0-2])$

一个月的31天

(01~09和1~31)

^((0?[1-9])|((1|2)[0-9])|30|31)$

有四种钱的表示形式:

"10000.00" 和 "10,000.00",

和没有 "分" 的 "10000" 和 "10,000"

^[1-9][0-9]*$

任意一个不以0开头的数字

^(0|[1-9][0-9]*)$

一个0或者一个不以0开头的数字

还可以允许开头有一个负号

^(0|-?[1-9][0-9]*)$

一个0或者一个可能为负的开头不为0的数字

^[0-9]+(.[0-9]+)?$

必须说明的是,小数点后面至少应该有1位数,所以"10."是不通过的,但是 "10" 和 "10.2" 是通过的

^[0-9]+(.[0-9]{2})?$

这样我们规定小数点后面必须有两位,如果你认为太苛刻了,可以这样

^[0-9]+(.[0-9]{1,2})?$

这样就允许用户只写一位小数.下面我们该考虑数字中的逗号了,我们可以这样

^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$

1到3个数字,后面跟着任意个 逗号+3个数字,逗号成为可选,而不是必须

^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$

xml文件

^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$

中文字符的正则表达式

[\u4e00-\u9fa5]

双字节字符

[^\x00-\xff]

(包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))

28 空白行的正则表达式:\n\s*\r (可以用来删除空白行)

HTML标记的正则表达式

<(\S*?)[^>]*>.*?</\1>|<.*? />

30 首尾空白字符的正则表达式:^\s*|\s*$ 或 (^\s*)|(\s*$)

(可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等))

腾讯QQ号

(腾讯QQ号从10000开始)

[1-9][0-9]{4,}

中国邮政编码

(中国邮政编码为6位数字)

[1-9]\d{5}(?!\d)

IP地址(提取IP地址时有用)

\d+\.\d+\.\d+\.\d+

IP地址

((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值