PHP: PCRE: preg_match_all не будет соответствовать экранированному знаку доллара ($) в шаблоне

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
    Проще говоря, используйте одинарные кавычки для регулярных выражений. Это избавит вас от головной боли.
Теги:
pcre

2 ответа

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
    Но я попробовал, и это работает. Вы пробовали мое решение?
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню