正则表达式教程 概念+实战

转载请注明预见才能遇见的博客:http://my.csdn.net/

原文地址:http://blog.csdn.net/pcaxb/article/details/70621698

正则表达式教程 概念+实战
正则表达式(regular expression)就是用一个“字符串”来描述一个特征,然后去验证另一个“字符串”是否符合这个特征。比如 表达式“ab+” 描述的特征是“一个 'a' 和 任意个 'b' ”,那么 'ab', 'abb', 'abbbbbbbbbb' 都符合这个特征。

1.普通字符

字母,数字,汉字,下划线及一些没有特殊定义的标点符号,都属于普通字符,正则中的普通字符,在匹配字符串的时候,匹配与之相同的字符即可。
str = 'abcde';
//2
value = str.search(/c/);
//["c", index: 2, input: "abcde"]
value = str.match(/c/);
表达式 "c",在匹配字符串 "abcde" 时,匹配结果是:成功;匹配到的内容是:"c";匹配到的位置是:开始于2,结束于3。(注:下标从0开始还是从1开始,因当前编程语言的不同而可能不同)

2.简单的转义字符

(1)\n 匹配一个换行符

(2)\f 匹配一个换页符

(3)\r 匹配一个回车符

(4)\t 匹配一个制表符

(5)\v 匹配一个垂直制表符

案例(\n):匹配一个换行符,返回换行符被找到的位置,其他简单转义字符同理
基本语法:new RegExp(“\n”) 或直接量 /\n/
str = 'My name \n is RegExp. \n My name is RegExp.';
//["↵", index: 8, input: "My name ↵ is RegExp. ↵ My name is RegExp."]
value = /\n/g.exec(str);
//["↵", "↵"]
value = str.match(/\n/g);
//8
value = str.search(/\n/g);
//true
value = /\n/g.test(str);

3.某些的转义字符(初期可以了解一下,熟悉正则表达式之后再重点的学习)
(1)\0 查找NUL字符

(2)\xxx 查找一个以八进制数xxx规定的字符

(3)\xdd 查找以16进制数dd规定的字符

(4)\uxxxx 查找以16进制数的xxxx规定的Unicode字符

匹配中文字符正则:\u4E00-\u9FA5\uf900-\ufa2d

str = "659157faha获取字符串中的中文fhal47194fafl";
//["获", "取", "字", "符", "串", "中", "的", "中", "文"]
value = str.match(/[\u4E00-\u9FA5\uf900-\ufa2d]/g);

4.能够匹配'多种字符'的表达式
(1) . 查找任意的单个字符,除换行符(\n)外

(2) \w 任意一个字母或数字或下划线,A_Za_Z0_9,_中任意一个
     \W 查找非单词的字符,等价于[^A_Za_z0_9_]

(3) \d 匹配一个数字字符,等价于[0-9]
     \D 匹配一个非数字字符,等价于[^0-9]

(4) \s 匹配任何空白字符,包括空格,制表符,换行符等等。等价于[\f\n\r\t\v]
     \S 匹配任何非空白字符,等价于[^\f\n\r\t\v]

(5) \b 匹配一个单词边界,也就是指单词和空格间的位置,比如’er\b’可以匹配”never”中的”er”,但是不能匹配”verb”中的”er”

     \B 匹配非单词边界,’er\B’能匹配’verb’中的’er’,但不能匹配’never’中的’er’

//(1). . 任意的单个字符除(\n)外
value = /^.+$/.test('h7_#');//true
value = /^.+$/.test('h7_#\n');//false

//(2). \w 字母、数字、下划线
value = /^\w+$/.test('h7_');//true
value = /^\w+$/.test('h7_#');//false

//(3). \d 数字
value = /\d{3}/.test('789');//true
value = /\d{3}/.test('7r9');//false

//(4). \s 匹配任何空白字符,包括空格,制表符,换行符等等。等价于[\f\n\r\t\v]
value = /^\s+$/.test('\f\n\r\t\v');//true
value = /^\s+$/.test('\s\w\f\n\r\t\v');//false
value = /\s+/.test('hello longen hello el');//true


//(5). \b 匹配一个单词边界
str = "hello longen hello el";
value = /\bhello\b/.test(str);//true
value = /\bhell\b/.test(str);//false

元字符(Metacharacter)是拥有特殊含义的字符:

元字符 描述
. 查找单个字符,除了换行和行结束符。
\w 查找单词字符。
\W 查找非单词字符。
\d 查找数字。
\D 查找非数字字符。
\s 查找空白字符。
\S 查找非空白字符。
\b 匹配单词边界。
\B 匹配非单词边界。
\0 查找 NUL 字符。
\n 查找换行符。
\f 查找换页符。
\r 查找回车符。
\t 查找制表符。
\v 查找垂直制表符。
\xxx 查找以八进制数 xxx 规定的字符。
\xdd 查找以十六进制数 dd 规定的字符。
\uxxxx 查找以十六进制数 xxxx 规定的 Unicode 字符。

5.自定义能够匹配 '多种字符' 的表达式 使用方括号 [ ] 包含一系列字符,能够匹配其中任意一个字符。用 [^ ] 包含一系列字符,则能够匹配其中字符之外的任意一个字符。同样的道理,虽然可以匹配其中任意一个,但是只能是一个,不是多个。
(1)[abc]:  查找在方括号中的任意一个字符;

(2)[^abc]: 查找不在方括号中的任意一个字符;

(3)[0-9]: 查找0-9中的任意一个数字;

(4)[a-z]: 查找从小写a到z中的任意一个字符;

(5)(red|blue|green); 查找小括号中的任意一项,小括号中的 | 是或者的意思;
案例:
value = /^[abc]+$/.test('abch');//false
value = /^[abc]+$/.test('abc');//true
//["bac", index: 0, input: "bac"]
value = 'bac'.match(/^[abc]+$/);

表达式/^[abc]+$/匹配 "bac" 时,匹配的结果是:成功;匹配到的内容是:"bac";匹配到的位置是:开始于0,结束于3

方括号用于查找某个范围内的字符:

表达式 描述
[abc] 查找方括号之间的任何字符。
[^abc] 查找任何不在方括号之间的字符。
[0-9] 查找任何从 0 至 9 的数字。
[a-z] 查找任何从小写 a 到小写 z 的字符。
[A-Z] 查找任何从大写 A 到大写 Z 的字符。
[A-z] 查找任何从大写 A 到小写 z 的字符。
[adgk] 查找给定集合内的任何字符。
[^adgk] 查找给定集合外的任何字符。
(red|blue|green) 查找任何指定的选项。

6.特殊字符中的需要转义字符

需要转义的特殊字符前面加 \
(1) $ 匹配输入字符串的结尾位置,如果需要匹配匹配输入字符串的结尾位置,如果需要匹配本身的话,使用\$

(2) ^ 匹配输入字符串的开始位置,匹配^本身的话,使用\^

(3) . 匹配除换行符之外的任何一个字符,匹配.本身的话,使用\.

(4) * 匹配前面的子表达式的零次或者多次,匹配*本身的话,使用\*

(5) + 匹配子表达式的1次或者多次,匹配+本身的话,使用\+

(6) ? 匹配前面的子表达式的零次或者1次,或指明一个非贪婪限定符,要匹配本身的话,使用\?

(7) () 标记一个子表达式的开始和结束位置。要匹配小括号,请使用\( 和 \)

(8) [] 匹配一个中括号开始,匹配本身的,使用\[ 和 \]

(9) {} 标记限定符开始的地方,要匹配{},请使用\{ 和 \}

(10) \ 匹配本身的话,请使用\\

(11) | 指明多项中的一个选择,可以理解含义为或的意思,匹配本身的话,使用\|

7.修饰匹配次数的特殊符号
(1)n+ 匹配任何至少包含一个n的字符串  (n >= 1)

(2)n* 匹配零个或者多个n的字符串 (n >= 0)

(3)n? 匹配零个或者1个n的字符串 (0|1)

(4)n{x} 匹配包含x个n的序列字符串 (n = x)

(5)n{x,y} 匹配至少x个,最多y个n的字符串 (x <= n >= y)

(6)n{x,} 匹配至少x个的字符串 (n >= x)

str = "hello longen hello el";
//(1). n+ 匹配至少1个n的字符串 >= 1
value = str.match(/l+/g);//["ll", "l", "ll", "l"]

//(2). n* 匹配0个或者多个n的字符串 >= 0
value = str.match(/el*/g);//["ell", "e", "ell", "el"]

//(3). n? 匹配0个或者1个n的字符串 0|1
value = str.match(/el?/g);//["el", "e", "el", "el"]

//(4). n{x} 匹配x个n的字符串   x
value = str.match(/l{2}/g);//["ll", "ll"]

str = "hello longen hello el aaa";
//(5). n{x,y} 匹配至少x个,最多y个n的字符串  x <= n个数 <= y
value = str.match(/l{1,2}/g);//["ll", "l", "ll", "l"]

//(6). n{x,} 匹配至少x个n的字符串 >= x
value = str.match(/l{1,}/g);//["ll", "l", "ll", "l"]


8.代表抽象意义的特殊符号

(1)n$ 匹配以n结尾的字符串

(2)^n 匹配以n开头的字符串

(3)?=n 匹配其后紧接指定的n字符串

(4)?!n 匹配其后没有紧接指定的n字符串

(5) |  左右两边表达式之间 “或” 关系,匹配左边或者右边

(6) () 在被修饰匹配次数的时候,括号中的表达式可以作为整体被修饰。取匹配结果的时候,括号中的表达式匹配到的内容可以被单独得到

str = "hello longen hello el";
//(1). n$ 匹配以n结尾的字符串
value = str.match(/l$/g);//["l"]

//(2). ^n 匹配以n开头的字符串
value = str.match(/^h/g);//["h"]

//(3). ?=n 匹配任何其后紧接指定字符串n的字符串 /regexp(?=n)/
value = str.match(/he(?=l)/g);//["he", "he"]
value = str.match(/he(?=ll)/g);//["he", "he"]
value = str.match(/e(?=l+)/g);//["e", "e", "e"]

//(4). ?!n 匹配任何其后不紧接n的字符串 /regexp(?!n)/
value = str.match(/e(?!l)/g);//["e"]

//(5). |  左右两边表达式之间 “或” 关系,匹配左边或者右边
value = str.match(/(hello|el)/g);//["hello", "hello", "el"]
value = str.match(/(hello | el)/g);//["hello ", "hello "]
说明:| 的左右不能有空格,如果有空格结果就是只匹配了|的前面一个

//(6). () 括号中的表达式可以作为整体被修饰,匹配到的内容可以被单独得到
//["010-12345", "010", "12345", index: 0, input: "010-12345"]
value = '010-12345'.match(/^(\d{3})-(\d{3,8})$/);
//["010-12345", index: 0, input: "010-12345"]
value = '010-12345'.match(/^\d{3}-\d{3,8}$/);

量词

量词 描述
n+ 匹配任何包含至少一个 n 的字符串。
n* 匹配任何包含零个或多个 n 的字符串。
n? 匹配任何包含零个或一个 n 的字符串。
n{X} 匹配包含 X 个 n 的序列的字符串。
n{X,Y} 匹配包含 X 至 Y 个 n 的序列的字符串。
n{X,} 匹配包含至少 X 个 n 的序列的字符串。
n$ 匹配任何结尾为 n 的字符串。
^n 匹配任何开头为 n 的字符串。
?=n 匹配任何其后紧接指定字符串 n 的字符串。
?!n 匹配任何其后没有紧接指定字符串 n 的字符串。


9.贪婪模式与非贪婪模式讲解

(1)贪婪模式
概念:被量词修饰的子表达式的匹配行为,在整个表达式匹配成功的情况下尽可能多的匹配;
修饰贪婪模式的量词:{x,y} ,  {x,} ,  ? ,  * , 和  +
?:带 "?" 的表达式在可匹配可不匹配的时候,尽可能的 "要匹配"

(2)非贪婪模式
概念:被量词修饰的子表达式的匹配行为,在整个表达式匹配成功的前提下尽可能少的匹配;
修饰非贪婪模式的量词:在贪婪模式的量词后面加上? ,例如{x,y}?和*?
??:带 "?" 的表达式在可匹配可不匹配的时候,尽可能的 "不要匹配"

概念:被量词修饰的子表达式的匹配行为,在整个表达式匹配成功的情况下尽可能多的匹配;
修饰贪婪模式的量词:{x,y} ,  {x,} ,  ? ,  * , 和  +
?:带 "?" 的表达式在可匹配可不匹配的时候,尽可能的 "要匹配"

(2)非贪婪模式
概念:被量词修饰的子表达式的匹配行为,在整个表达式匹配成功的前提下尽可能少的匹配;
修饰非贪婪模式的量词:在贪婪模式的量词后面加上? ,例如{x,y}?和*?
??:带 "?" 的表达式在可匹配可不匹配的时候,尽可能的 "不要匹配"

str = "fhafh<p>这个可以有</p>HHFH<p>香菇蓝瘦</p>fagfa";
//贪婪模式 匹配最多字符
value = str.match(/<p>.*<\/p>/)[0];//<p>这个可以有</p>HHFH<p>香菇蓝瘦</p>
//非贪婪模式 匹配最少字符
//value = str.match(/<p>.*?<\/p>/)[0];//<p>这个可以有</p>
说明:说明:上面可以看出贪婪模式是在匹配成功的情况下尽可能多的匹配,所以贪婪模式的结果是<p>这个可以有</p>HHFH<p>香菇蓝瘦</p>;非贪婪模式是在匹配成功的情况下尽可能少的匹配,所以非贪婪模式的结果是<p>这个可以有</p>

10.反向引用 \1, \2...
概念:匹配的结果除了可以在正则表达式外部通过程序进行引用,也可以在正则表达式内部进行引用,这种在正则表达式内部进行引用的形式就是反向引用
作用:用来查找或限定重复,查找或限定指定标识配对出现等
说明:"小括号包含的表达式所匹配到的字符串" 不仅是在匹配结束后才可以使用,在匹配过程中也可以使用。表达式后边的部分,可以引用前面 "括号内的子匹配已经匹配到的字符串"。引用方法是 "\" 加上一个数字。"\1" 引用第1对括号内匹配到的字符串,"\2" 引用第2对括号内匹配到的字符串……以此类推,如果一对括号内包含另一对括号,则外层的括号先排序号。换句话说,哪一对的左括号 "(" 在前,那这一对就先排序号。

str = "bbacabccba";
value = str.match(/([cab])\1/g);//["bb", "cc"]

str = "aa bbbb abcdefg ccccc 111121111 999999999";
value = str.match(/(\w)\1{4,}/g);//["ccccc", "999999999"]
value = str.match(/(\w)(\w)\2{2,}/g);//["bbbb", "ccccc", "1111", "21111", "999999999"]

11.RegExp的对象方法和支持正则表达式的String的对象方法
(1)RegExp的对象属性和方法

compile 编译正则表达式

exec 检索字符串中指定的值。返回找到的值,并确定其位置

test 检索字符串中指定的值。返回 true 或 false

(2)支持正则表达式的String的对象方法

search 检索与正则表达式相匹配的值

match 找到一个或多个正则表达式的匹配

replace 替换与正则表达式匹配的子串

split 把字符串分割为字符串数组

RegExp 对象属性

属性 描述 FF IE
global RegExp 对象是否具有标志 g。 1 4
ignoreCase RegExp 对象是否具有标志 i。 1 4
lastIndex 一个整数,标示开始下一次匹配的字符位置。 1 4
multiline RegExp 对象是否具有标志 m。 1 4
source 正则表达式的源文本。 1 4

RegExp 对象方法

方法 描述 FF IE
compile 编译正则表达式。 1 4
exec 检索字符串中指定的值。返回找到的值,并确定其位置。 1 4
test 检索字符串中指定的值。返回 true 或 false。 1 4

支持正则表达式的 String 对象的方法

方法 描述 FF IE
search 检索与正则表达式相匹配的值。 1 4
match 找到一个或多个正则表达式的匹配。 1 4
replace 替换与正则表达式匹配的子串。 1 4
split 把字符串分割为字符串数组。 1 4

参考资料:

1.深入浅出的javascript的正则表达式学习教程

2.W3C正则表达式教程

3.正则表达式菜鸟教程

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}
  • 电话号码正则表达式(支持手机号码,3-4位区号,7-8位直播号码,1-4位分机号): ((\d{11})|^((\d{7,8})|(\d{4}|\d{3})-(\d{7,8})|(\d{4}|\d{3})-(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1})|(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1}))$)
  • 身份证号(15位、18位数字),最后一位是校验位,可能为数字或字符X:(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)
  • 帐号是否合法(字母开头,允许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)$
  • 钱的输入格式:
    1. 有四种钱的表示形式我们可以接受:"10000.00" 和 "10,000.00", 和没有 "分" 的 "10000" 和 "10,000":^[1-9][0-9]*$
    2. 这表示任意一个不以0开头的数字,但是,这也意味着一个字符"0"不通过,所以我们采用下面的形式:^(0|[1-9][0-9]*)$
    3. 一个0或者一个不以0开头的数字.我们还可以允许开头有一个负号:^(0|-?[1-9][0-9]*)$
    4. 这表示一个0或者一个可能为负的开头不为0的数字.让用户以0开头好了.把负号的也去掉,因为钱总不能是负的吧。下面我们要加的是说明可能的小数部分:^[0-9]+(.[0-9]+)?$
    5. 必须说明的是,小数点后面至少应该有1位数,所以"10."是不通过的,但是 "10" 和 "10.2" 是通过的:^[0-9]+(.[0-9]{2})?$
    6. 这样我们规定小数点后面必须有两位,如果你认为太苛刻了,可以这样:^[0-9]+(.[0-9]{1,2})?$
    7. 这样就允许用户只写一位小数.下面我们该考虑数字中的逗号了,我们可以这样:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$
    8. 1到3个数字,后面跟着任意个 逗号+3个数字,逗号成为可选,而不是必须:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$
    9. 备注:这就是最终结果了,别忘了"+"可以用"*"替代如果你觉得空字符串也可以接受的话(奇怪,为什么?)最后,别忘了在用函数时去掉去掉那个反斜杠,一般的错误都在这里
  • xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
  • 中文字符的正则表达式:[\u4e00-\u9fa5]
  • 双字节字符:[^\x00-\xff] (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
  • 空白行的正则表达式:\n\s*\r (可以用来删除空白行)
  • HTML标记的正则表达式:<(\S*?)[^>]*>.*?|<.*? /> ( 首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)
  • 腾讯QQ号:[1-9][0-9]{4,} (腾讯QQ号从10000开始)
  • 中国邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为6位数字)
  • IP地址:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))

正则表达式教程 概念+实战

博客地址:http://blog.csdn.net/pcaxb/article/details/70621698




  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值