3

我有这个字符串要测试,但无法让它按我的意愿工作:

<?php
$string = '500 or fatal error ?';
$regex = '#(fatal|500)#';
if (preg_match($regex, $string, $return)) {
    // Return 500
    echo $return[1];
}
?>

我希望我的脚本返回致命而不是 500,因为它是我的第一个选择器。是否可以 ?

在此先感谢,并为我糟糕的英语感到抱歉。

PS:也许我的标题不是很清楚,但我不知道如何更好地解释它。如果你找到它,改变它。

4

3 回答 3

2

有两种正则表达式引擎:text-directed enginesregex-directed引擎。

php 是regex-directed引擎,它总是返回最左边的匹配,即使以后可以找到“500”匹配

引擎将从字符串的第一个字符开始。它将在第一个字符处尝试正则表达式的所有可能排列。只有在尝试了所有可能性并发现失败时,引擎才会继续处理文本中的第二个字符。同样,它将以完全相同的顺序尝试所有可能的正则表达式排列。结果是正则表达式导向的引擎将返回最左边的匹配。

你可以在这里找到更多信息

于 2013-03-19T16:58:01.340 回答
2

正如您所设想的那样,这是不可能的,但是不同的实现将使它起作用

$string = '500 or fatal error';
$regexes = array('#\bfatal\b#', '#\b500\b#');

$match = null;
foreach ($regexes as $re)
  if (preg_match($re, $string, $match))
    break;
# $match is null -> not found
于 2013-03-19T17:01:16.587 回答
2

如果你只想使用一个正则表达式,你可以这样做:

$selectors = array( 'fatal', '500'); // Array of selectors (in priority order)

$delimiter = '/';
$regex = $delimiter . '(' . implode('|', array_map( 'preg_quote', $selectors, array_fill( 0, count( $selectors), '/'))) . ')' . $delimiter;
preg_match_all( $regex, $string, $matches);

按照数组的顺序查看我们找到了哪些选择器:

$found_selectors = array_flip( $matches[1]);
foreach( $selectors as $selector) { 
    if( isset( $found_selectors[$selector])) 
        return $selector;
}

请注意,我翻转了$matches[1]数组以在数组中获得恒定的查找时间,而不是执行array_search()/ in_array(),这两者都将执行线性搜索。

您可以从这个演示fatal中看到,给定您的输入字符串,这会产生。

于 2013-03-19T17:10:13.967 回答