正则表达式中"?"的扩展用法
2010-11-15 20:50
267 查看
又分三小种用法。
第一种 指明非捕捉用的括号
我们已经知道括号可以捕捉匹配上的字符串,并将它们存入变量之中,如果只想用括号将某部分进行分组?考虑这样的正则表达式:只希望其中一部分括号中所匹配的内容被存入内存变量中。在下面的例子中,我们希望“bronto”是可选择的,为了将它变成可选择的,我们需要将它用括号括起来。接着,模式使用了一个模式可以得到“steak”或者“burger”,匹配上的字符串被存入内存变量中。
if(/(bronto)?saurus (steak|burger)/)
{
print “Fred wants a $2/n”;
}
即便“bronto”没有被匹配上,此部分仍然会存入$1。Perl 统计开括号的个数,从而给这些变量命名。我们需要的部分被存入$2。当模式变复杂时,情况就变得非常复杂。
幸运的是,Perl 的正则表达式有一种方法可以使括号只进行分组,而不会引起内存变量的分配。我们将它叫做非捕捉用的括号(non-capturing parentheses),对于它,有一个特殊的写法。我们在开括号后面加上一个问号和冒号,(?:)◆,其作用是告诉Perl 括号只是分组的作用。
◆这是?号在正则表达式中的第四种用法:问号,表示0 或1 的数量词,非贪婪修饰符,现在是开头符
改变上述正则表达式,使之对“bronto”是非捕捉用的括号,我们需要的部分被存入变量$1。
if(/(?:bronto)?saurus (steak|burger)/)
{
print “Fred wants a $1/n”;
}
如果以后需要改变正则表达式,如在brontosaurs burger 上再加入barbecue,我们可以加入“BBQ ”(含有空格),并且使括号是非捕捉用的,那么我们需要的部分所对应的内存变量仍为$1。否则,可能每一次在正则表达式中加入括号时,需要改变内存变量名。
if (/(?:bronto)?saurus (?:BBQ )?(steak|burger)/)
{
print “Fred wants a $1/n”;
}
第二种 内嵌模式选项
/(?option)pattern/; 等价于 /pattern/option; 其中 option 为 i m s x.
第三种 预见匹配
简单说,就是匹配时考虑预见匹配的那一部分,不符合的不能算匹配上,但匹配的结果部分(变量$&)要除去预见匹配部分,又分两种。
1 肯定预见匹配 /pattern(?=string)/;匹配时,要考虑符合string
例如 $string="25abc8"
$string =~/abc(?=[0-9])/
此时 abc8是符合 abc[0-9]模式的,但得到的$&不含8,而是abc.
那为何不去掉预见匹配部分呢?比如
$string="25abc8"
$string=~/abc/
结果 $&也是 abc,而不是abc8
这样也是匹配的,结果似乎也"正确".其实不然,考虑
$string="25abcu"
按先前的模式/abc(?=[0-9])/,是不匹配的,但按后面"简化"后的 /abc/,就匹配了,考虑到这种情况,使用预见匹配效果是不一样的.
2 否定预见匹配 /pattern(?!string)/;匹配时,要考虑不符合string的才行,结果$&仍然只是取patern部分,不包括string
第一种 指明非捕捉用的括号
我们已经知道括号可以捕捉匹配上的字符串,并将它们存入变量之中,如果只想用括号将某部分进行分组?考虑这样的正则表达式:只希望其中一部分括号中所匹配的内容被存入内存变量中。在下面的例子中,我们希望“bronto”是可选择的,为了将它变成可选择的,我们需要将它用括号括起来。接着,模式使用了一个模式可以得到“steak”或者“burger”,匹配上的字符串被存入内存变量中。
if(/(bronto)?saurus (steak|burger)/)
{
print “Fred wants a $2/n”;
}
即便“bronto”没有被匹配上,此部分仍然会存入$1。Perl 统计开括号的个数,从而给这些变量命名。我们需要的部分被存入$2。当模式变复杂时,情况就变得非常复杂。
幸运的是,Perl 的正则表达式有一种方法可以使括号只进行分组,而不会引起内存变量的分配。我们将它叫做非捕捉用的括号(non-capturing parentheses),对于它,有一个特殊的写法。我们在开括号后面加上一个问号和冒号,(?:)◆,其作用是告诉Perl 括号只是分组的作用。
◆这是?号在正则表达式中的第四种用法:问号,表示0 或1 的数量词,非贪婪修饰符,现在是开头符
改变上述正则表达式,使之对“bronto”是非捕捉用的括号,我们需要的部分被存入变量$1。
if(/(?:bronto)?saurus (steak|burger)/)
{
print “Fred wants a $1/n”;
}
如果以后需要改变正则表达式,如在brontosaurs burger 上再加入barbecue,我们可以加入“BBQ ”(含有空格),并且使括号是非捕捉用的,那么我们需要的部分所对应的内存变量仍为$1。否则,可能每一次在正则表达式中加入括号时,需要改变内存变量名。
if (/(?:bronto)?saurus (?:BBQ )?(steak|burger)/)
{
print “Fred wants a $1/n”;
}
第二种 内嵌模式选项
/(?option)pattern/; 等价于 /pattern/option; 其中 option 为 i m s x.
第三种 预见匹配
简单说,就是匹配时考虑预见匹配的那一部分,不符合的不能算匹配上,但匹配的结果部分(变量$&)要除去预见匹配部分,又分两种。
1 肯定预见匹配 /pattern(?=string)/;匹配时,要考虑符合string
例如 $string="25abc8"
$string =~/abc(?=[0-9])/
此时 abc8是符合 abc[0-9]模式的,但得到的$&不含8,而是abc.
那为何不去掉预见匹配部分呢?比如
$string="25abc8"
$string=~/abc/
结果 $&也是 abc,而不是abc8
这样也是匹配的,结果似乎也"正确".其实不然,考虑
$string="25abcu"
按先前的模式/abc(?=[0-9])/,是不匹配的,但按后面"简化"后的 /abc/,就匹配了,考虑到这种情况,使用预见匹配效果是不一样的.
2 否定预见匹配 /pattern(?!string)/;匹配时,要考虑不符合string的才行,结果$&仍然只是取patern部分,不包括string
相关文章推荐
- 通过OpenSSL获取证书扩展属性之二:“密钥用法”和"增强型密钥用法"
- c++11 std::regex 与 boost::regex相比 前者发现不能用"\\xAA"这样的字符在正则表达式中 至少vs2012中是这样
- 验证有效 "日期时间" 的正则表达式(已解决闰二月)
- 关于正则表达式 g,m 参数的总结,为了回答“正则表达式(/[^0-9]/g,'')中的"/g"是什么意思?”
- “正则表达式(/[^0-9]/g,'')中的"/g"是什么意思”
- 关于正则表达式 g,m 参数的总结,为了回答“正则表达式(/[^0-9]/g,'')中的"/g"是什么意思?”
- [Python]解决正则表达式的"贪婪"匹配
- 小心,别让正则表达式规则"[A-z]"钻了孔子 正则表达式规则"[A-z]"与"[A-Za-z]"的差别
- 正则表达式中的"?"
- 关于正则表达式 g,m 参数的总结,为了回答“正则表达式(/[^0-9]/g,'')中的"/g"是什么意思?”
- 日期的正则表达式(能过"2009-9-2“这种格式)
- 通过例子学习正则表达式(二)--检查输入的"钱"
- 用正则表达式将前后空格用空字符串替代:replace(/(^\s*)|(\s*$)/g, "")
- 验证有效 "日期时间" 的正则表达式(已解决闰二月)
- 使用CryptoAPI获取证书扩展属性之二:“密钥用法”和"增强型密钥用法"
- 验证有效 "日期时间" 的正则表达式(已解决闰二月)
- Java 正则表达式 对于 乘号"*" 的处理
- 关于正则表达式 g,m 参数的总结,为了回答“正则表达式(/[^0-9]/g,'')中的"/g"是什么意思?”
- 正则表达式中grep,sed的用法(包括基本的正则表达式和扩展的正则表达式)
- Linux扩展正则表达式及sed生产环境用法