原文符号

因为?在正则表达式中有特殊的含义,所以如果想匹配?本身,则需要转义,\?
有无量词

问号可以表示重复前面内容的0次或一次,也就要么不出现,要么出现一次。
非贪婪匹配
贪婪匹配

在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配

string pattern1 = @"a.*c";   // greedy match
 
 
Regex regex = new Regex(pattern1);
 
 
regex.Match("abcabc"); // return "abcabc"


非贪婪匹配

在满足匹配时,匹配尽可能短的字符串,使用?来表示非贪婪匹配

string pattern1 = @"a.*?c";

// non-greedy match Regex regex = new Regex(pattern1);

regex.Match("abcabc"); // return "abc"


几个常用的非贪婪匹配Pattern
*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复
不捕捉模式

如何关闭圆括号的捕获能力?而只是用它来做分组,方法是在左括号的后边加上:?,这里第一个圆括弧只是用来分组,而不会占用捕获变量,所以$1的内容只能是steak或者burger,而永远不可能是bronto。

while(<>){
    if(/(?:bronto)(steak|burger)/){
        print "Fred wants a $1\n" ;
    }
}

非捕捉用的括号的详细介绍

我们已经知道括号可以捕捉匹配上的字符串,并将它们存入变量之中,如果只想用括号将某部分进行分组?考虑这样的正则表达式:只希望其中一部分括号中所匹配的内容被存入内存变量中。在下面的例子中,我们希望“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”;
}

 预见匹配
   简单说,就是匹配时考虑预见匹配的那一部分,不符合的不能算匹配上,但匹配的结果部分(变量$&)要除去预见匹配部分,又分两种。
 1 肯定预见匹配  /pattern(?=string)/;匹配时,要考虑符合string

遇见功能,"?=",意识说目标串中肯定存在什么,比如:
var str="ab4";
var reg=/ab(?=\d)/g
alert(reg.test(str));//结果为true意思是第三位肯定是数字;

2 否定预见匹配  /pattern(?!string)/;匹配时,要考虑不符合string的才行,结果$&仍然只是取patern部分,不包括string
"?!",意思说目标串中不应该存在什么var str="ab1";
var reg=/ab(?!\d)/g
alert(reg.test(str));//结果为false
意思是目标串中的第三位不应该是数字。