2015-01-28 1 views
0

Я пытаюсь сопоставить все экземпляры подстроки '$ {foo}' внутри $ content. По какой-то причине я могу сопоставить «{foo}», но не «$ {foo}». Кто-нибудь знает, почему?

$content="aaaa\${foo}bbbb\n"; 
echo $content; // aaaa${foo}bbbb 

// THIS WORKS AS EXPECTED: matches all instances of substring '{foo}' 
$result = preg_match_all("/(\{\w+\})/", $content, $matches); 
if ($result === false) { die("NOT OK!"); } 
echo "NUMBER OF MATCHES: ", $result, "\n"; 
var_dump($matches); 

// THIS DOESN'T WORK AS EXPECTED: doesn't match instances of substring '${foo}' 
$result = preg_match_all("/(\$\{\w+\})/", $content, $matches); 
if ($result === false) { die("NOT OK!"); } 
echo "NUMBER OF MATCHES: ", $result, "\n"; 
var_dump($matches); 

Вот вывод этого кода. Первая часть выходов 1 соответствует, как и ожидалось, в то время как вторая часть выходов 0 матчей, но я ожидал 1 матч:

aaaa${foo}bbbb 
NUMBER OF MATCHES: 1 
array(2) { 
    [0]=> 
    array(1) { 
    [0]=> 
    string(5) "{foo}" 
    } 
    [1]=> 
    array(1) { 
    [0]=> 
    string(5) "{foo}" 
    } 
} 
NUMBER OF MATCHES: 0 
array(2) { 
    [0]=> 
    array(0) { 
    } 
    [1]=> 
    array(0) { 
    } 
} 

спасибо.

+3

При использовании двойной кавычки, чтобы заключить строку шаблона, вы должны спасаясь от '$' знак дважды. Один раз, чтобы предотвратить синтаксический анализатор php, чтобы увидеть '' 'как начало переменной, один раз, чтобы избежать специального символа регулярного выражения' $ '. Если вы хотите избежать этого только один раз, используйте одинарные кавычки. –

+1

просто введите, используйте одинарные кавычки для регулярных выражений. Это избавит вас от головной боли. –

ответ

2

Вам нужно удвоить обратную косую черту (и вам также следует избегать брекетов).

"/(\\$\\{\w+\\})/" 

Это потому, что вам нужно, чтобы избежать обратной косой черты для строки синтаксического анализа, так как \\ будет \ до того PCRE даже получает, чтобы увидеть строку. Без двойного выхода PCRE просто получит $, который, очевидно, попытается совместить конец строки.

+1

В большинстве случаев вам не нужно дважды избегать фигурных скобок. Только тогда, когда он неоднозначен, как '{1,2}' или '{1}' (и должна быть достаточно открывающей скобки). Однако это не ошибка. –

1

Используйте одинарные кавычки, чтобы не было необходимости удваивать знак $. Только специальные символы регулярного выражения должны быть экранированы при использовании в регулярном выражении в одинарных кавычках, кроме обратных косых черт и одинарных кавычек, которые необходимо экранировать в любой строке PHP, заключенной в одинарные кавычки. При использовании регулярных выражений используйте только двойные кавычки, когда вам нужно встроить переменную в ваше регулярное выражение (в этом случае другим экранам может потребоваться экранирование, а также другие ответы).

Отсюда следующие работы:

$content="aaaa\${foo}bbbb\n"; 
echo $content; // aaaa${foo}bbbb 

// THIS WORKS AS EXPECTED: matches all instances of substring '{foo}' 
$result = preg_match_all('/(\{\w+\})/', $content, $matches); 
if ($result === false) { die("NOT OK!"); } 
echo "NUMBER OF MATCHES: ", $result, "\n"; 
var_dump($matches); 

// THIS ALSO WORKS AS EXPECTED: matches all instances of substring '${foo}' 
$result = preg_match_all('/(\$\{\w+\})/', $content, $matches); 
if ($result === false) { die("NOT OK!"); } 
echo "NUMBER OF MATCHES: ", $result, "\n"; 
var_dump($matches); 
+0

Вам все равно нужно дважды уйти от '$'. –

+0

Но я попробовал, и он работает. Вы пробовали мое решение? –

+0

Да, ты прав. PHP странный. –