php之正则表达式

 一个正则表达式就是由普通字符(例如字符 a z)以及特殊字符(称为元字符)组成的文字模式。该模式描述在查找文字主体时待匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
 
下表是元字符及其在正则表达式上下文中的行为的一个完整列表:
字符描述
/
将下一个字符标记为一个特殊字符、或一个原义字符、或一个后向引用、或一个八进制转义符。
例如'n' 匹配字符 "n"'/n' 匹配一个换行符。序列 '//' 匹配 "/" "/(" 则匹配 "("
 
^
匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 '/n' '/r' 之后的位置。
 
$
匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 '/n' '/r' 之前的位置。
 
*
匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo" * 等价于{0,}
 
+
匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"+ 等价于 {1,}
 
ab+
表示一个字符串有一个a且其后面至少跟着一个b或更多。
 
?
匹配前面的子表达式零次或一次。例如"do(es)?" 可以匹配 "do" "does" 中的"do" ? 等价于 {0,1}
 
ab?
表示一个字符串有一个a且其后面跟着零个或者一个b
 
{n}
n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o
 
{n,}
n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o'o{1,}' 等价于 'o+''o{0,}' 则等价于 'o*'
ab{2,}
表示一个字符串有一个a且后面跟着至少2b;
 
{n,m}
m n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。 "o{1,3}" 将匹配 "fooooood" 中的前三个 o'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。
ab{3,5}
表示一个字符串有一个a且其后面跟着3--5b
 
x|y
匹配 x y。例如,'z|food' 能匹配 "z" "food"'(z|f)ood' 则匹配 "zood" "food"
 
(b|cd)ef
表示befcdef
 
hi|hello
表示一个字符串里有一个hihello
 
[xyz]
字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'
 
[^xyz]
负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'
 
[a-z]
字符范围。匹配指定范围内的任意字符。例如,'[a-z]' 可以匹配 'a' 'z' 范围内的任意小写字母字符。
 
[^a-z]
负值字符范围。匹配任何不在指定范围内的任意字符。例如,'[^a-z]' 可以匹配任何不在 'a' 'z' 范围内的任意字符。
 
[-a-z]
a~z26个字母再加1-
 
/b
匹配一个单词边界,包括前边界和后边界,也就是指单词和空格间的位置。例如, 'er/b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'
 
/B
匹配非单词边界。'er/B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'
 
/cx
匹配由x指明的控制字符。例如, /cM 匹配一个 Control-M 或回车符。 x 的值必须为 A-Z a-z 之一。否则,将 c 视为一个原义的 'c' 字符。
 
/d
匹配一个数字字符。等价于 [0-9]
 
/D
匹配一个非数字字符。等价于 [^0-9]
 
/f
匹配一个换页符。等价于 /x0c /cL
 
/n
匹配一个换行符。等价于 /x0a /cJ
 
/r
匹配一个回车符。等价于 /x0d /cM
 
/s
匹配任何空白字符包括空格、制表符、换页符等等。等价于 [ /f/n/r/t/v]
 
/S
匹配任何非空白字符。等价于 [^ /f/n/r/t/v]
 
/t
匹配一个制表符。等价于 /x09 /cI
 
/v
匹配一个垂直制表符。等价于 /x0b /cK
 
/w
匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'
 
/W
匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'
 
/xn
匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如, '/x41' 匹配 "A"'/x041' 则等价于 '/x04' & "1"。正则表达式中可以使用 ASCII 编码。.
 
/num
匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,'(.)/1' 匹配两个连续的相同字符。
 
/n
标识一个八进制转义值或一个后向引用。如果 /n 之前至少 n 个获取的子表达式,则 n 为后向引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。
 
/nm
标识一个八进制转义值或一个后向引用。如果 /nm 之前至少有is preceded by at least nm 个获取得子表达式,则 nm 为后向引用。如果 /nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的后向引用。如果前面的条件都不满足,若 n m 均为八进制数字 (0-7),则 /nm 将匹配八进制转义值 nm
 
/nml
如果 n 为八进制数字 (0-3),且 m l 均为八进制数字 (0-7),则匹配八进制转义值 nml
 
/un
匹配 n,其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如, /u00A9 匹配版权符号 (?)
 
^[0-9]+$
表示所有的正数
 
^/-?[0-9]+$
表示所有的整数
 
^/-?[0-9]*/.?[0-9]*$
表示所有的小数
 
常用邮件匹配表达式
^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(/.[a-zA-Z0-9_-])+
?
当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 "oooo"'o+?' 将匹配单个 "o",而 'o+' 将匹配所有 'o'
 
.
匹配除 "/n" 之外的任何单个字符。要匹配包括 '/n' 在内的任何字符,请使用像 '[./n]' 的模式。
 
(pattern)
匹配pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在Visual Basic Scripting Edition 中则使用 $0$9 属性。要匹配圆括号字符,请使用 '/(' '/)'
 
(?:pattern)
匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 "" 字符 (|) 来组合一个模式的各个部分是很有用。例如, 'industr(?:y|ies) 就是一个比 'industry|industries' 更简略的表达式。
 
(?=pattern)
正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如, 'Windows (?=95|98|NT|2000)' 能匹配 "Windows 2000" 中的 "Windows" ,但不能匹配 "Windows 3.1" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
 
(?!pattern)
负向预查,在任何不匹配Negative lookahead matches the search string at any point where a string not matching pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如'Windows (?!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows",但不能匹配 "Windows 2000" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始
 
 
字符串头部
搜索一个字符串的头部,用^,例如
 
<?php echo ereg("^hello", "hello world!"); ?>
将返回 true, 但是
<?php echo ereg("^hello", "i say hello world"); ?>
将返回 false, 因为hello不在字符串”I say hello world”的头部。
字符串尾部
 
搜索字符串尾部,用$,例如:
<?php echo ereg("bye$", "goodbye"); ?>
将返回true, 但是
<?php echo ereg("bye$", "goodbye my friend"); ?>
将返回 false,因为bye不在字符串”goodbye my friend”的尾部.
 
任意的单个字符
搜索任意字符,用点(.),例如:
<?php echo ereg(".", "cat"); ?>
将返回true,但是
<?php echo ereg(".", ""); ?>
将返回false,因为我们的要搜索字符串没有包含字符。你可以用花括号随意告诉正则表达式引擎它要匹配多少个单个字符。如果我只想匹配5个字符,我可以这样用ereg:
<?php echo ereg(".{5}$", "12345"); ?>
上面的这段代码告诉正则表达式引擎当且仅当至少5个连续的字符出现字符串的尾部时返回true.我们也可以限制连续出现的字符的数目:
<?php echo ereg("a{1,3}$", "aaa"); ?>
在上面的例子里,我们已经告诉正则表达式引擎,我们的搜索字符串来匹配表达式,它在尾部必须有介于13个的”a”字符。
<?php echo ereg("a{1,3}$", "aaab"); ?>
上面的例子将不会返回true,虽然有三个”a”字符在搜索字符串里,但是它们不是在字符串的尾部。如果我们把结尾字符串匹配$从正则表达式中去掉,那么这个字符串是匹配的。
我们也可以告诉正则表达式引擎来匹配至少有确定数目的字符在一行,如果它们存在的,可以匹配更多。我们可以这样做:
<?php echo ereg("a{3,}$", "aaaa"); ?>
 
零或多次重复字符
为了告诉正则表达式引擎一个字符可能存在,也可以重复,我们用*字符。这里的两个例子都将返回true.
 
<?php echo ereg("t*", "tom"); ?>
<?php echo ereg("t*", "fom"); ?>
即使第二个例子不包含”t”这个字符,但仍旧返回ture,因为*表示字符可以出现,但不是必须出现。事实上,任何普通的字符串模式都会使上面的ereg调用返回true,因为’t’字符是可选的.
 
 
一或多次重复字符
为了告诉正则表达式引擎一个字符必须存在,也可以重复不止一次,我们用+字符,像
 
<?php echo ereg("z+", "i like the zoo"); ?>
下面的例子也会返回true:
<?php echo ereg("z+", "i like the zzzzzzoo!"); ?>
 
零或一次重复字符
我们也可以告诉正则表达式引擎,一个字符必须是或者只存在一次,或者没有。我们用?字符来做这项工作,就像
<?php echo ereg("c?", "cats are fuzzy"); ?>
如果我们愿意,我们完全可以从上面的搜索字符串中删除’c’,这个表达式会仍旧返回true.?的意思是一个’c’可以出现在搜索字符串的任何地方,但不是必须的。
 
一个正则表达式是一个特定的格式化模式,可以用来找出一个字符串在另一个字符串中的使用情况。几个编程语言,包括Visual Basic,Perl,JavaScriptPHP都支持正则表达式,希望在这篇入门指导的结束,Mitchell(作者自己)可以让你在PHP程序中能应用一些基本的正则表达式。正则表达式是在各种各样的程序语言中突出的古怪特征中的一种,但是由于它们看起来是很难的一个概念,所以很多开发者就把它们放到了角落里,忘记了它们的存在。
 
让我们先来看看什么是正则表达式,为什么你要在PHP程序中用到它们。
 
什么是正则表达式?
 
你对从一个不错的老的基于控制的文本编辑器中分离出像BBEditnotepad的程序,有什么看法呢?两个都支持文本输入,可以让你保存文本到文件中,但是现在的文本编辑器也支持其它功能,包括查找–代替工具,这让编辑一个文本文件相当容易。
正则表达式也是相似的,只是更好一些。正则表达式可以被认为一个极其高级的查找-替换工具,让我们从痛苦中摆脱出来:不必再写定制的数据确认例子来检查电子邮件地址或者来确认电话号码的格式是正确的,如此等等。
任何程序中最普通的函数之一就是数据有效性检查,PHP捆绑了一些文本检查函数,允许我们用正则表达式匹配一个字符串,确认有一个空格,有一个问号,等等。
你不知道的可能是,正则表达式可以简单装备吗,当你掌握了一些正则表达式时(这个正则表达式可以用来告诉正则表达式引擎一个字符串中我们想要匹配的部分),你会自问为什么会把正则表达式扔到角落里这么久,^_^
PHP有两套函数,用来处理两种类型的正则表达式:Perl5兼容模式,和Posix标准兼容模式。在这篇文章中我们将看看ereg函数,用遵照Posix标准的搜索表达式工作。虽然它们并没有Perl5模式那样强大,但是一种不错的学习正则表达式的方法。如果你对PHP支持的Perl5兼容正则表达式感兴趣,可以到PHP.net网站找一些关于preg函数的细节。
PHP有六个函数来处理正则表达式,它们都把一个正则表达式作为它们的第一个参数,列出如下:
 
ereg: 最常用的正则表达式函数, ereg 允许我们搜索跟一个正则表达式匹配的一个字符串.
ereg_replace: 允许我们搜索跟正则表达式匹配的一个字符串,并用新的字符串代替所有这个表达式出现的地方。
eregi: ereg几乎是一样效果,不过忽略大小写。
eregi_replace: ereg_replace有着一样的搜索-替换功能,不过忽略大小写.
split: 允许我们搜索和正则表达式匹配的字符串,并且以字符串集合的方式返回匹配结果.
spliti: split函数忽略大小写的版本.
为什么使用正则表达式?
 
如果你不断地建立不同的函数来检查或者操作字符串的一部分,现在你可能要放弃所有的这些函数,取而代之的用正则表达式。如果你对下列的问题都答“是的”,那么你肯定要考虑使用正则表达式了:
 
你是否正在写一些定制的函数来检查表单数据(比如在电子信箱地址中的一个@,一个点)?
你是否写一些定制的函数,在一个字符串中循环每个字符,如果这个字符匹配了一个特定特征(比如它是大写的,或者它是一个空格),那么就替换它?
除了是令人不舒服的字符串检查和操作方法,如果没有有效率地写代码,上述的两条也会使你的程序慢下来。你是否更倾向于用下面的代码检查一个电子信箱地址呢:
 
<?php
function validateEmail($email)
{
$hasAtSymbol = strpos($email, "@");
$hasDot = strpos($email, ".");
if($hasAtSymbol && $hasDot)
return true;
else
return false;
}
echo validateEmail("mitchell@devarticles.com");
?>
... 或者使用下面的代码:
 
<?php
function validateEmail($email)
{
return ereg("^[a-zA-Z]+@[a-zA-Z]+/.[a-zA-Z]+$", $email);
}
echo validateEmail("mitchell@devarticles.com");
?>
 
可以肯定的是,第一个函数比较容易,而且看起来结构也不错。但是如果我们用上面的下一个版本的email地址检查函数不是更容易吗?
 
上面展示的第二个函数只用了正则表达式,包括了对ereg函数的一个调用。Ereg 函数返回true或者false,来声明它的字符串参数是否和正则表达式相匹配。
 
很多编程者避开正则表达式,只因为它们(在一些情况下)比其它的文本处理方法更慢。正则表达式可能慢的原因是因为它们涉及把字符串在内存中拷贝和粘贴,因为正则表达式的每一个新的部分都对应匹配一个字符串。但是,从我对正则表达式的经验来说,除非你在文本中几百个行运行一个复杂的正则表达式,否则性能上的缺陷都可以忽略不计,当把正则表达式作为输入数据检查工具时,也很少出现这种情况。
 
 
 
 
 
正则表达式语法 ()
空格字符
为了匹配一个搜索字符串中的空格字符,我们用预定义Posix的类,[[:space]].方括号标明连续字符的相关性,”:space:”是实际要匹配的类(在这种情形下,是任何空白字符)。空白包括tab字符,新行字符,空白字符。或者,如果搜索字符串必须包含只有一个空格,而不是一个tab或者新行字符,你可以用一个空格字符(" ")。在大多数情况下,我倾向于使用":space:",因为这意味着我的意图不仅仅是单个空格字符,这点很容易被忽视。这里有一些Posix-标准预定义类,
有一些我们可以作为正则表达式的部分的一些Posix-标准预定义类,包括[:alnum:], [:digit:], [:lower:]等等。完整的列表可以在这里查看
 
我们可以像这样匹配单个空白字符:
 
<?php echo ereg("Mitchell[[:space:]]Harper", "Mitchell Harper"); ?>
我们也可以通过在表达式后用?字符来告诉正则表达式引擎匹配没有空白或者一个空白。
<?php echo ereg("Mitchell[[:space:]]?Harper", "MitchellHarper"); ?>
 
模式分组
相关的模式可以在方括号里分在一起。很容易用[a-z][A-Z]指定只有一个小写字母或者一列大写字母以搜索字符串的一部分存在。
<?php
// 要求从第一个到最后一个都是小写字母
echo ereg("^[a-z]+$", "johndoe"); // 返回true
?>
或者像
<?php
// 要求从第一个到最后一个都是大写字母
ereg("^[A-Z]+$", "JOHNDOE"); // 返回 true?
?>
我们也可以告诉正则表达式引擎,我们希望或者是小写字母,或者是大写字母。我们只要把[a-z][A-Z]模式结合在一起就可以做到。
<?php echo ereg("^[a-zA-Z]+$", "JohnDoe"); ?>
在上面的例子里,如果我们能匹配"John Doe",而不是"JohnDoe",将是非常有意义的。我们用下面的正则表达式来做这个:
^[a-zA-Z]+[[:space:]]{1}[a-zA-Z]+$
很容易搜索一个数字字符串
<?php echo ereg("^[0-9]+$", "12345"); ?>
 
词语分组
不仅仅搜索模式可以分组,我们也可以用圆括号把相关的搜索词语进行分组。
<?php echo ereg("^(John|Jane).+$", "John Doe"); ?>
在上面的例子中,我们有一个字符串头部字符,紧跟着"John"或者"Jane",至少有一个其它字符,然后一个字符串尾部字符。所以…
<?php echo ereg("^(John|Jane).+$", "Jane Doe"); ?>
...将也匹配我们的搜索模式
 
特殊字符的情形
因为一些字符要用在一个搜索模式的明确分组或者语法上,像在(John|Jane)中的圆括号,我们需要告诉正则表达式引擎来屏蔽这些字符,加工它们使之成为被搜索字符串的一部分,而不是搜索表达式的一部分。我们所用的方法称为“字符转义”,涉及到将任何“专用符号”加上反斜杠。所以,例如,如果我想在我的搜索中包含’|’,那么我就可以这样做
<?php echo ereg("^[a-zA-z]+/|[a-zA-z]+$", "John|Jane"); ?>
这里只是少量的一些你要转义的字符,你必须转义^, $, (, ), ., [, |, *, ?, +, / and {
希望你现在对正则表达式实际上有多么强大有了一点点感觉了。现在让我们看两个用正则表达式来检查数据中一个字符串的例子。
 
 
正则表达式例子
例子1
让我们把第一个例子做的相当简单,检验一个标准的URL.一个标准的URL(没有端口号),有三个部分构成:
 
[协议]://[域名]
 
让我们从匹配URL的协议部分开始,并且让它只能用http或者ftp.我们可以用下面的正则表达式做到这点:
 
^(http|ftp)
^字符特指字符串的头部,利用圆括号把httpftp围住,且用“或者”符号(|)将它们分开,我们告诉正则表达式引擎httpftp两者之一必须在字符串的开头。
 
一个域名通常由www.somesite.com构成,但是可以随意选择要不要www部分。为了例子简单,我们只允许.com,.net,.org的域名是在考虑之中的。我们最好这样对正则表达式中的域名部分表示如下:
(www/.)?.+/.(com|net|org)$
把所有的东西放在一起,我们的正则表达式就可以用作检查一个域名,如:
 
<?php
function isValidDomain($domainName)
{
 
return ereg("^(http|ftp)://(www/.)?.+/.(com|net|org)$", $domainName);
}
//(true)
echo isValidDomain("http://www.somesite.com");
//(true)
echo isValidDomain("ftp://somesite.com");
// (false)
echo isValidDomain("ftp://www.somesite.fr");
// (false)
echo isValidDomain("www.somesite.com");
?>
 
用正则表达式判断输入的数字是否合法
<html>
<head>
<title>Untitled</title>
</head>
<body>
<?php
$in="2344";
if(ereg("^(-{0,1}|/+{0,1})[0-9]+(/.{0,1}[0-9]+)$",$in))
echo "Ok!";
else
echo "Sorry,Please input again!";
?>
<br>很简单的嘛!
 
</body>
</html>
php的正则表达式专题
字符/
意义:对于字符,通常表示按字面意义,指出接着的字符为特殊字符,不作解释。
例如:/b/匹配字符’b,通过在b 前面加一个反斜杠,也就是/b/,则该字符变成特殊字符,表示
匹配一个单词的分界线。
或者:
对于几个字符,通常说明是特殊的,指出紧接着的字符不是特殊的,而应该按字面解释。
例如:*是一个特殊字符,匹配任意个字符(包括0个字符);例如:/a*/意味匹配0个或多个a。为了匹配字面上的*,在a前面加一个反斜杠;例如:/a*/匹配’a*’。
 
字符^
意义:表示匹配的字符必须在最前边。
例如:/^A/不匹配"an A,"中的’A’,但匹配"An A."中最前面的’A’。
 
字符$
意义:与^类似,匹配最末的字符。
例如:/t$/不匹配"eater"中的’t’,但匹配"eat"中的’t’。
 
字符*
意义:匹配*前面的字符0次或n次。
例如:/bo*/匹配"A ghost booooed"中的’boooo’或"A bird warbled"中的’b’,但不匹配"Agoat g
runted"中的任何字符。
 
字符+
意义:匹配+号前面的字符1次或n次。等价于{ 1, }
例如:/a+/匹配"candy"中的’a’和"caaaaaaandy."中的所有’a’。
 
字符?
意义:匹配?前面的字符0次或1次。
例如:/e?le?/匹配"angel"中的’el’和"angle."中的’le’。
 
字符.
意义:(小数点)匹配除换行符外的所有单个的字符。
例如:/.n/匹配"nay, an apple is on the tree"中的’an’和’on’,但不匹配’nay’。
 
 
字符(x)
意义:匹配’x’并记录匹配的值。
例如:/(foo)/匹配和记录"foo bar."中的’foo’。匹配子串能被结果数组中的素[1], ...,[n]
回,或被RegExp对象的属性, ..., 返回。
 
字符xy
意义:匹配’x’或者’y’。
例如:/greenred/匹配"green apple"中的’green’和"red apple."中的’red’。
 
字符{ n }
意义:这里的n是一个正整数。匹配前面的n个字符。
例如:/a{ 2 }/不匹配"candy,"中的’a’,但匹配"caandy," 中的所有’a’和"caaandy."中前面的两个’a’。
 
字符{ n, }
意义:这里的n是一个正整数。匹配至少n个前面的字符。
例如:/a{ 2, }不匹配"candy"中的’a’,但匹配"caandy"中的所有’a’和"caaaaaaandy."中的所有’a
 
字符{ n,m }
意义:这里的nm都是正整数。匹配至少n个最多m个前面的字符。
例如:/a{ 1,3 }/不匹配"cndy"中的任何字符,但匹配 "candy,"中的’a’,"caandy," 中的前面两个
a’和"caaaaaaandy"中前面的三个’a’,注意:即使"caaaaaaandy" 中有很多个’a’,但只匹配前面的三个’a’即"aaa"
 
字符[xyz]
意义:一字符列表,匹配列出中的任一字符。你可以通过连字符-指出一个字符范围。
例如:[abcd][a-c]一样。它们匹配"brisket"中的’b’和"ache"中的’c’。
 
字符[^xyz]
意义:一字符补集,也就是说,它匹配除了列出的字符外的所有东西。你可以使用连字符-指出一字符范围。
例如:[^abc][^a-c]等价,它们最早匹配"brisket"中的’r’和"chop."中的’h’。
 
字符
意义:匹配一个空格(不要与b混淆)
 
字符b
意义:匹配一个单词的分界线,比如一个空格(不要与混淆)
例如:/bnw/匹配"noonday"中的’no’,/wyb/匹配"possibly yesterday."中的’ly’。
 
字符B
意义:匹配一个单词的非分界线
例如:/wBn/匹配"noonday"中的’on’,/yBw/匹配"possibly yesterday."中的’ye’。
 
字符cX
意义:这里的X是一个控制字符。匹配一个字符串的控制字符。
例如:/cM/匹配一个字符串中的control-M
 
字符d
意义:匹配一个数字,等价于[0-9]
例如:/d//[0-9]/匹配"B2 is the suite number."中的’2
 
字符D
意义:匹配任何的非数字,等价于[^0-9]
例如:/D//[^0-9]/匹配"B2 is the suite number."中的’B’。
 
字符f
意义:匹配一个表单符
 
字符n
意义:匹配一个换行符
 
字符r
意义:匹配一个回车符
 
字符s
意义:匹配一个单个white空格符,包括空格,tabform feed,换行符,等价于[ fnrtv]
例如:/sw*/匹配"foo bar."中的’ bar’。
 
字符S
意义:匹配除white空格符以外的一个单个的字符,等价于[^ fnrtv]
例如:/S/w*匹配"foo bar."中的’foo’。
 
字符t
意义:匹配一个制表符
 
字符v
意义:匹配一个顶头制表符
 
字符w
意义:匹配所有的数字和字母以及下划线,等价于[A-Za-z0-9_]
例如:/w/匹配"apple,"中的’a’,".28,"中的’5"3D."中的’3
 
字符W
意义:匹配除数字、字母外及下划线外的其它字符,等价于[^A-Za-z0-9_]
例如:/W/或者/[^$A-Za-z0-9_]/匹配"50%."中的’%’。
 
字符n
意义:这里的n是一个正整数。匹配一个正则表达式的最后一个子串的n的值(计数左圆括号)
 
例如:/apple(,)sorange1/匹配"apple, orange, cherry, peach."中的’apple, orange’,下面有一个更加完整的例子。
注意:如果左圆括号中的数字比n指定的数字还小,则n取下一行的八进制escape作为描述。
 
字符ooctalxhex
意义:这里的ooctal是一个八进制的escape值,而xhex是一个十六进制的escape值,允许在一个正则表达式中嵌入ASCII
 
:下表是元字符及其在正则表达式上下文中的行为的一个完整列表:
 
字符描述
/ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个后向引用、或一个八进制转义符。例如'n' 匹配字符 "n"'/n' 匹配一个换行符。序列 '' 匹配 "/" "/(" 则匹配 "("
^ 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 '/n' '/r' 之后的位置。
$ 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 '/n' '/r' 之前的位置。
* 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo" * 等价于{0,}
+ 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"+ 等价于 {1,}
? 匹配前面的子表达式零次或一次。例如"do(es)?" 可以匹配 "do" "does" 中的"do" ? 等价于 {0,1}
{n} n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o
{n,} n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o'o{1,}' 等价于 'o+''o{0,}' 则等价于 'o*'
{n,m} m n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。刘, "o{1,3}" 将匹配 "fooooood" 中的前三个 o'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。
? 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 "oooo"'o+?' 将匹配单个 "o",而 'o+' 将匹配所有 'o'
. 匹配除 "/n" 之外的任何单个字符。要匹配包括 '/n' 在内的任何字符,请使用象 '[./n]' 的模式。
(pattern) 匹配pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 {CONTENT}属性。要匹配圆括号字符,请使用 '/(' '/)'
(?:pattern) 匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 "" 字符 () 来组合一个模式的各个部分是很有用。例如, 'industr(?:yies) 就是一个比 'industryindustries' 更简略的表达式。
(?=pattern) 正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如, 'Windows (?=9598NT2000)' 能匹配 "Windows 2000" 中的 "Windows" ,但不能匹配 "Windows 3.1" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern) 负向预查,在任何不匹配Negative lookahead matches the search string at any point where a string not matching pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如'Windows (?!9598NT2000)' 能匹配 "Windows 3.1" 中的 "Windows",但不能匹配 "Windows 2000" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始
xy 匹配 x y。例如,'zfood' 能匹配 "z" "food"'(zf)ood' 则匹配 "zood" "food"
[xyz] 字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'
[^xyz] 负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'
[a-z] 字符范围。匹配指定范围内的任意字符。例如,'[a-z]' 可以匹配 'a' 'z' 范围内的任意小写字母字符。
[^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。例如,'[^a-z]' 可以匹配任何不在 'a' 'z' 范围内的任意字符。
/b 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er/b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'
/B 匹配非单词边界。'er/B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'
/cx 匹配由x指明的控制字符。例如, /cM 匹配一个 Control-M 或回车符。 x 的值必须为 A-Z a-z 之一。否则,将 c 视为一个原义的 'c' 字符。
/d 匹配一个数字字符。等价于 [0-9]
/D 匹配一个非数字字符。等价于 [^0-9]
/f 匹配一个换页符。等价于 /x0c /cL
/n 匹配一个换行符。等价于 /x0a /cJ
/r 匹配一个回车符。等价于 /x0d /cM
/s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ /f/n/r/t/v]
/S 匹配任何非空白字符。等价于 [^ /f/n/r/t/v]
/t 匹配一个制表符。等价于 /x09 /cI
/v 匹配一个垂直制表符。等价于 /x0b /cK
/w 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'
/W 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'
/xn 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如, '/x41' 匹配 "A"'/x041' 则等价于 '/x04' & "1"。正则表达式中可以使用 ASCII 编码。.
/num 匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,'(.)' 匹配两个连续的相同字符。
/n 标识一个八进制转义值或一个后向引用。如果 /n 之前至少 n 个获取的子表达式,则 n 为后向引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。
/nm 标识一个八进制转义值或一个后向引用。如果 /nm 之前至少有is preceded by at least nm 个获取得子表达式,则 nm 为后向引用。如果 /nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的后向引用。如果前面的条件都不满足,若 n m 均为八进制数字 (0-7),则 /nm 将匹配八进制转义值 nm
/nml 如果 n 为八进制数字 (0-3),且 m l 均为八进制数字 (0-7),则匹配八进制转义值 nml
/un 匹配 n,其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如, /u00A9 匹配版权符号 (?)
 
PERL里正则表达式的简介
 
一、简介
二、匹配操作符
三、模式中的特殊字符
1、字符+
2、字符 [][^]
3、字符 *?
4、转义字符
5、匹配任意字母或数字
6、锚模式
7、模式中的变量替换
8、字符范围转义前缀
9、匹配任意字符
10、匹配指定数目的字符
11、指定选项
12、模式的部分重用
13、转义和特定字符的执行次序
14、指定模式定界符
15、模式次序变量
四、模式匹配选项
1、匹配所有可能的模式(g选项)
2、忽略大小写(i选项)
3、将字符串看作多行(m选项)
4、只执行一次变量替换例
5、将字符串看作单行例
6、在模式中忽略空格
五、替换操作符
六、翻译操作符
七、扩展模式匹配
1、不存贮括号内的匹配内容
2、内嵌模式选项
3、肯定的和否定的预见匹配
4、模式注释
 
 
一、简介
模式指在字符串中寻找的特定序列的字符,由反斜线包含:/def/即模式def。其用法如结合函数split将字符串用某模式分成多个单词:@array = split(/ /, $line);
二、匹配操作符 =~!~
=~检验匹配是否成功:$result = $var =~ /abc/;若在该字符串中找到了该模式,则返回非零值,即true,不匹配则返回0,即false!~则相反。
这两个操作符适于条件控制中,如:
if ($question =~ /please/) {
print ("Thank you for being polite!/n");
}
else {
print ("That was not very polite!/n");
}
三、模式中的特殊字符
PERL在模式中支持一些特殊字符,可以起到一些特殊的作用。
1、字符 +
+意味着一个或多个相同的字符,如:/de+f/defdeefdeeeeef等。它尽量匹配尽可能多的相同字符,如/ab+/在字符串abbc中匹配的将是abb,而不是ab
当一行中各单词间的空格多于一个时,可以如下分割:
@array = split (/ +/, $line);
注:split函数每次遇到分割模式,总是开始一个新单词,因此若$line以空格打头,则@array的第一个元素即为空元素。但其可以区分是否真有单词,如若$line中只有空格,则@array则为空数组。且上例中TAB字符被当作一个单词。注意修正。
2、字符 [][^]
[]意味着匹配一组字符中的一个,如/a[0123456789]c/将匹配a加数字加c的字符串。与+联合使用例:/d[eE]+f/匹配defdEfdeefdEdfdEEEeeeEef等。^表示除其之外的所有字符,如:/d[^deE]f/匹配d加非e字符加f的字符串。
3、字符 *?
它们与+类似,区别在于*匹配0个、1个或多个相同字符,?匹配0个或1个该字符。如/de*f/匹配dfdefdeeeef等;/de?f/匹配dfdef
4、转义字符
如果你想在模式中包含通常被看作特殊意义的字符,须在其前加斜线"/"。如://*+//*即表示字符*,而不是上面提到的一个或多个字符的含义。斜线的表示为////。在PERL5中可用字符对/Q/E来转义。
5、匹配任意字母或数字
上面提到模式/a[0123456789]c/匹配字母a加任意数字加c的字符串,另一种表示方法为:/a[0-9]c/,类似的,[a-z]表示任意小写字母,[A-Z]表示任意大写字母。任意大小写字母、数字的表示方法为:/[0-9a-zA-Z]/
6、锚模式
 
 
描述
^ /A 仅匹配串首
$ /Z 仅匹配串尾
/b 匹配单词边界
/B 单词内部匹配
 
1/^def/只匹配以def打头的字符串,/$def/只匹配以def结尾的字符串,结合起来的/^def$/只匹配字符串def(?)/A/Z在多行匹配时与^$不同。
2:检验变量名的类型:
if ($varname =~ /^/$[A-Za-z][_0-9a-zA-Z]*$/) {
print ("$varname is a legal scalar variable/n");
} elsif ($varname =~ /^@[A-Za-z][_0-9a-zA-Z]*$/) {
print ("$varname is a legal array variable/n");
} elsif ($varname =~ /^[A-Za-z][_0-9a-zA-Z]*$/) {
print ("$varname is a legal file variable/n");
} else {
print ("I dont understand what $varname is./n");
}
3/b在单词边界匹配://bdef/匹配defdefghi等以def打头的单词,但不匹配abcdef/def/b/匹配defabcdef等以def结尾的单词,但不匹配defghi//bdef/b/只匹配字符串def。注意://bdef/可匹配$defghi,因为$并不被看作是单词的部分。
4/B在单词内部匹配://Bdef/匹配abcdef等,但不匹配def/def/B/匹配defghi等;//Bdef/B/匹配cdefgabcdefghi等,但不匹配def,defghi,abcdef
7、模式中的变量替换
将句子分成单词:
$pattern = "[//t ]+";
@words = split(/$pattern/, $line);
8、字符范围转义
 
 
E 转义字符描述范围
/d 任意数字 [0-9]
/D 除数字外的任意字符 [^0-9]
/w 任意单词字符 [_0-9a-zA-Z]
/W 任意非单词字符 [^_0-9a-zA-Z]
/s 空白 [ /r/t/n/f]
/S 非空白 [^ /r/t/n/f]
 
例:/[/da-z]/匹配任意数字或小写字母。
9、匹配任意字符
字符"."匹配除换行外的所有字符,通常与*合用。
10、匹配指定数目的字符
字符对{}指定所匹配字符的出现次数。如:/de{1,3}f/匹配def,deefdeeef/de{3}f/匹配deeef/de{3,}f/匹配不少于3edf之间;/de{0,3}f/匹配不多于3edf之间。
11、指定选项
字符"|"指定两个或多个选择来匹配模式。如:/def|ghi/匹配defghi
例:检验数字表示合法性
if ($number =~ /^-?/d+$|^-?0[xX][/da-fa-F]+$/) {
print ("$number is a legal integer./n");
} else {
print ("$number is not a legal integer./n");
}
其中 ^-?/d+$ 匹配十进制数字,^-?0[xX][/da-fa-F]+$ 匹配十六进制数字。
12、模式的部分重用
当模式中匹配相同的部分出现多次时,可用括号括起来,用/n来多次引用,以简化表达式:
//d{2}([/W])/d{2}/1/d{2}/ 匹配:
12-05-92
26.11.87
07 04 92
注意://d{2}([/W])/d{2}/1/d{2}/ 不同于/(/d{2})([/W])/1/2/1/ ,后者只匹配形如17-17-17的字符串,而不匹配17-05-91等。
13、转义和特定字符的执行次序
象操作符一样,转义和特定字符也有执行次序:
 
 
特殊字符描述
() 模式内存
+ * ? {} 出现次数
^ $ /b /B
| 选项
 
14、指定模式定界符
缺省的,模式定界符为反斜线/,但其可用字母m自行指定,如:
m!/u/jqpublic/perl/prog1! 等价于///u//jqpublic//perl//prog1/
注:当用字母作为定界符时,不做变量替换;当用特殊字符作为定界符时,其转义功能或特殊功能即不能使用。
15、模式次序变量
在模式匹配后调用重用部分的结果可用变量$n,全部的结果用变量$&
$string = "This string contains the number 25.11.";
$string =~ /-?(/d+)/.?(/d+)/; # 匹配结果为25.11
$integerpart = $1; # now $integerpart = 25
$decimalpart = $2; # now $decimalpart = 11
$totalpart = $&; # now totalpart = 25.11
四、模式匹配选项
 
 
选项描述
g 匹配所有可能的模式
i 忽略大小写
m 将串视为多行
o 只赋值一次
s 将串视为单行
x 忽略模式中的空白
 
1、匹配所有可能的模式(g选项)
@matches = "balata" =~ /.a/g; # now @matches = ("ba", "la", "ta")
匹配的循环:
while ("balata" =~ /.a/g) {
$match = $&;
print ("$match/n");
}
结果为:
ba
la
ta
当使用了选项g时,可用函数pos来控制下次匹配的偏移:
$offset = pos($string);
pos($string) = $newoffset;
2、忽略大小写(i选项)
/de/i 匹配de,dE,DeDE
3、将字符串看作多行(m选项)
在此情况下,^符号匹配字符串的起始或新的一行的起始;$符号匹配任意行的末尾。
4、只执行一次变量替换例
$var = 1;
$line = ;
while ($var < 10) {
$result = $line =~ /$var/o;
$line = ;
$var++;
}
每次均匹配/1/
5、将字符串看作单行例
/a.*bc/s匹配字符串axxxxx /nxxxxbc,但/a.*bc/则不匹配该字符串。
6、在模式中忽略空格
//d{2} ([/W]) /d{2} /1 /d{2}/x等价于//d{2}([/W])/d{2}/1/d{2}/
五、替换操作符
语法为s/pattern/replacement/,其效果为将字符串中与pattern匹配的部分换成replacement。如:
$string = "abc123def";
$string =~ s/123/456/; # now $string = "abc456def";
在替换部分可使用模式次序变量$n,如s/(/d+)/[$1]/,但在替换部分不支持模式的特殊字符,如{},*,+等,如s/abc/[def]/将把abc替换为[def]
替换操作符的选项如下表:
 
 
选项描述
g 改变模式中的所有匹配
i 忽略模式中的大小写
e 替换字符串作为表达式
m 将待匹配串视为多行
o 仅赋值一次
s 将待匹配串视为单行
x 忽略模式中的空白
 
注:e选项把替换部分的字符串看作表达式,在替换之前先计算其值,如:
$string = "0abc1";
$string =~ s/[a-zA-Z]+/$& x 2/e; # now $string = "0abcabc1"
六、翻译操作符
这是另一种替换方式,语法如:tr/string1/string2/。同样,string2为替换部分,但其效果是把string1中的第一个字符替换为string2中的第一个字符,把string1中的第二个字符替换为string2中的第二个字符,依此类推。如:
$string = "abcdefghicba";
$string =~ tr/abc/def/; # now string = "defdefghifed"
string1string2长时,其多余字符替换为string2的最后一个字符;当string1中同一个字符出现多次时,将使用第一个替换字符。
翻译操作符的选项如下:
 
 
选项描述
c 翻译所有未指定字符
d 删除所有指定字符
s 把多个相同的输出字符缩成一个
 
$string =~ tr//d/ /c;把所有非数字字符替换为空格。$string =~ tr//t //d;删除tab和空格; $string =~ tr/0-9/ /cs;把数字间的其它字符替换为一个空格。
 
七、扩展模式匹配
PERL支持PERL4和标准UNIX模式匹配操作所没有的一些模式匹配能力。其语法为:(?pattern),其中c是一个字符,pattern是起作用的模式或子模式。
1、不存贮括号内的匹配内容
PERL的模式中,括号内的子模式将存贮在内存中,此功能即取消存贮该括号内的匹配内容,如/(?:a|b|c)(d|e)f/1/中的/1表示已匹配的de,而不是abc
2、内嵌模式选项
通常模式选项置于其后,有四个选项:imsx可以内嵌使用,语法为:/(?option)pattern/,等价于/pattern/option
3、肯定的和否定的预见匹配
肯定的预见匹配语法为/pattern(?=string)/,其意义为匹配后面为string的模式,相反的,(?!string)意义为匹配后面非string的模式,如:
$string = "25abc8";
$string =~ /abc(?=[0-9])/;
$matched = $&; # $&为已匹配的模式,此处为abc,而不是abc8
4、模式注释
PERL5中可以在模式中用?#来加注释,如:
if ($string =~ /(?i)[a-z]{2,3}(?# match two or three alphabetic characters)/ {
...
}
 
 
 
正则模式修正符
 
 
    
    
模式修正符
模式修正符 -- 解说正则表达式模式中使用的修正符
说明
下面列出了当前在 PCRE 中可能使用的修正符。括号中是这些修正符的内部 PCRE 名。
 
 
 
i (PCRE_CASELESS)
如果设定此修正符,模式中的字符将同时匹配大小写字母。
 
m (PCRE_MULTILINE)
默认情况下,PCRE 将目标字符串作为单一的一“行”字符所组成的(甚至其中包含有换行符也是如此)。“行起始”元字符(^)仅仅匹配字符串的起始,“行结束”元字符(?$)仅仅匹配字符串的结束,或者最后一个字符是换行符时其前面(除非设定了 D 修正符)。这和 Perl 是一样的。
 
当设定了此修正符,“行起始”和“行结束”除了匹配整个字符串开头和结束外,还分别匹配其中的换行符的之后和之前。这和 Perl /m 修正符是等效的。如果目标字符串中没有“/n”字符或者模式中没有 ^ ?$,则设定此修正符没有任何效果。
 
s (PCRE_DOTALL)
如果设定了此修正符,模式中的圆点元字符(.)匹配所有的字符,包括换行符。没有此设定的话,则不包括换行符。这和 Perl /s 修正符是等效的。排除字符类例如 [^a] 总是匹配换行符的,无论是否设定了此修正符。
 
x (PCRE_EXTENDED)
如果设定了此修正符,模式中的空白字符除了被转义的或在字符类中的以外完全被忽略,在未转义的字符类之外的 # 以及下一个换行符之间的所有字符,包括两头,也都被忽略。这和 Perl /x 修正符是等效的,使得可以在复杂的模式中加入注释。然而注意,这仅适用于数据字符。空白字符可能永远不会出现于模式中的特殊字符序列,例如引入条件子模式的序列 (?( 中间。
 
e
如果设定了此修正符,preg_replace() 在替换字符串中对逆向引用作正常的替换,将其作为 PHP 代码求值,并用其结果来替换所搜索的字符串。
 
只有 preg_replace() 使用此修正符,其它 PCRE 函数将忽略之。
 
: 本修正符在 PHP3 中不可用。
 
 
A (PCRE_ANCHORED)
如果设定了此修正符,模式被强制为“anchored”,即强制仅从目标字符串的开头开始匹配。此效果也可以通过适当的模式本身来实现(在 Perl 中实现的唯一方法)。
 
D (PCRE_DOLLAR_ENDONLY)
如果设定了此修正符,模式中的美元元字符仅匹配目标字符串的结尾。没有此选项时,如果最后一个字符是换行符的话,美元符号也会匹配此字符之前(但不会匹配任何其它换行符之前)。如果设定了 m 修正符则忽略此选项。Perl 中没有与其等价的修正符。
 
S
当一个模式将被使用若干次时,为加速匹配起见值得先对其进行分析。如果设定了此修正符则会进行额外的分析。目前,分析一个模式仅对没有单一固定起始字符的 non-anchored 模式有用。
 
U (PCRE_UNGREEDY)
本修正符反转了匹配数量的值使其不是默认的重复,而变成在后面跟上“?”才变得重复。这和 Perl 不兼容。也可以通过在模式之中设定 (?U) 修正符来启用此选项。
 
X (PCRE_EXTRA)
此修正符启用了一个 PCRE 中与 Perl 不兼容的额外功能。模式中的任何反斜线后面跟上一个没有特殊意义的字母导致一个错误,从而保留此组合以备将来扩充。默认情况下,和 Perl 一样,一个反斜线后面跟一个没有特殊意义的字母被当成该字母本身。当前没有其它特性受此修正符控制。
 
u (PCRE_UTF8)
此修正符启用了一个 PCRE 中与 Perl 不兼容的额外功能。模式字符串被当成 UTF-8。本修正符在 Unix 下自 PHP 4.1.0 起可用,在 win32 下自 PHP 4.2.3 起可用。`
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值