有关?的文档:在正则表达式中?

时间:2010-09-28 12:31:42

标签: php regex

前一段时间,我在正则表达式中看到过(至少在PHP中),你可以通过预先?:来捕获一个捕获组。

实施例

$str = 'big blue ball';
$regex = '/b(ig|all)/';
preg_match_all($regex, $str, $matches);
var_dump($matches);

...输出

array(2) {
  [0]=>
  array(2) {
    [0]=>
    string(3) "big"
    [1]=>
    string(4) "ball"
  }
  [1]=>
  array(2) {
    [0]=>
    string(2) "ig"
    [1]=>
    string(3) "all"
  }
}

在这个例子中,我不关心括号中匹配的内容,所以我附加了?:'/b(?:ig|all)/')并得到了输出

array(1) {
  [0]=>
  array(2) {
    [0]=>
    string(3) "big"
    [1]=>
    string(4) "ball"
  }
}

这非常有用 - 至少我是这么认为的。有时候你只是不想把你的比赛弄得乱七八糟。

我试图查找文档和官方名称(我称之为非捕获组,但我想我之前已经听过)。

作为符号,谷歌似乎很难。

我还看了一些正则表达式参考指南,没有提及。

?为前缀,并出现在括号内的第一个字符中会让我相信它与前瞻或外观有关。

那么,这些的正确名称是什么,我在哪里可以了解更多?

6 个答案:

答案 0 :(得分:29)

可在官方文档的Subpatterns页面上找到。

  

普通括号实现两个功能的事实并不总是有用的。有时候需要分组子模式而没有捕获要求。如果左括号后跟“?:”,则子模式不执行任何捕获,并且在计算任何后续捕获子模式的数量时不计算。例如,如果字符串“白皇后”与((?:red | white)(king | queen))模式匹配,则捕获的子串是“白皇后”和“女王”,编号为1和2捕获的子串的最大数量为99,捕获和非捕获的所有子模式的最大数量为200.

还可以注意到,您可以使用它为子模式设置选项。例如,如果您只希望子模式不区分大小写,则可以执行以下操作:

(?i:foo)bar

将匹配:

  • foobar的
  • Foobar的
  • foobar的
  • ...等

但不是

  • foobar的
  • foobar的
  • ...等

哦,虽然官方文档实际上没有明确地命名语法,但它确实在稍后将其称为“非捕获子模式”(这完全合理,并且无论如何我都称之为,因为它不是真正的“群体”,而是一个子模式... ...

答案 1 :(得分:7)

(?:)整体代表非捕获组

Regular-expressions.info提到了这种语法:

  

开头圆括号后面的问号和冒号是特殊的语法,您可以使用它来告诉正则表达式引擎这对括号不应该创建反向引用。请注意,问号[...]是正则表达式运算符,它使前一个标记可选。在开始圆括号之后,此运算符不能出现,因为开括号本身不是有效的正则表达式标记。因此,问号作为使标记可选的操作符与作为改变一对圆括号的属性的字符的问号之间没有混淆。冒号表示我们想要做的改变是关闭捕获反向引用。

答案 2 :(得分:3)

这是我发现的:

  

如果您不使用反向引用,   你可以优化这个常规   表达式为Set(?:Value)?该   问号和结肠后的   开口圆支架是特殊的   你可以用来告诉的语法   这双正则表达式引擎   括号不应该创建   反向引用。注意问号   在开放括号之后是无关的   到了问号的最后   正则表达式。这个问号是正则表达式   生成前一个令牌的运算符   可选的。此运算符无法显示   在开圆支架后,   因为一个开口支架本身   不是有效的正则表达式令牌。因此,   这之间没有混淆   问号作为运营商来制作   令牌可选,以及问号   作为改变的角色   一对圆的属性   括号。冒号表明了   我们要做的改变就是关闭   捕获反向引用。

http://www.regular-expressions.info/brackets.html

答案 3 :(得分:3)

这是在php手册中,我相信任何语言的任何其他接近完整的正则表达式部分......

  
    

普通括号实现两个功能的事实并不总是有用的。有时候需要分组子模式而没有捕获要求。如果左括号后跟“?:”,则子模式不执行任何捕获,并且在计算任何后续捕获子模式的数量时不计算。

  

Source

答案 4 :(得分:2)

PHP的preg_match_all使用PCRE(Perl兼容的正则表达式)语法,该语法记录为here。非捕获子模式记录在Subpatterns chapter

  

会让我相信它与前瞻或外观有关。

不,有许多不同的功能由open-bracket-question-mark触发。 Lookahead / lookbehind只是你遇到的第一个。

很麻烦,许多选项必须被压缩到(?,而不是给出更自己的可读语法,但有必要将所有内容都装入以前不是有效表达式的序列中,在旧版的正则表达式中。

答案 5 :(得分:0)

我不知道怎么做?:,但是通过简单的循环很容易:

$regex = '/b(ig|all)/';
$array = array(
    0 => array(0 => 'big', 1 => 'ball'),
    1 => array(0 => 'ig', 1 => 'all')
);
foreach ($array as $key => $row) {
    foreach ($row as $val) {
        if (!preg_match($regex, $val)) {
            unset($array[$key]);
        }
    }
}
print_r($array);