Perl в PHP с s ///; - PullRequest
       54

Perl в PHP с s ///;

0 голосов
/ 03 декабря 2009

В Perl я могу сделать: 1 while $var =~ s/a/b/;, и он заменит все a на b. Во многих случаях я использовал бы его больше как 1 while $var =~ s/^"(.*)"$/$1/;, чтобы удалить все пары двойных кавычек вокруг строки.

Есть ли способ сделать что-то похожее на это в PHP, без необходимости

while (preg_match('/^"(.*)"$/', $var)) {
    $var = preg_replace('/^"(.*)"$/', '$1', $var, 1);
}

Потому что, очевидно,

while ($var = preg_replace('/^"(.*)"$/', '$1', $var, 1)) { 1; }

не работает.

РЕДАКТИРОВАТЬ: Конкретная ситуация, в которой я работаю, включает замену значений в строке на значения из ассоциативного массива:

$text = "This is [site_name], home of the [people_type]".
$array = ('site_name' => 'StackOverflow.com', 'people_type' => 'crazy coders');

где я буду заниматься:

while (preg_match('/\[.*?\]/', $text)) {
    $text = preg_replace('/\[(.*?)\]/', '$array[\'$1\']', $text, 1);
}

с предполагаемым выводом «Это StackOverflow.com, дом сумасшедших программистов»

Ответы [ 5 ]

1 голос
/ 04 декабря 2009

Во всех случаях вы можете избавиться от цикла, например, используя опцию /g global replace или переписав регулярное выражение:

$var =~ s/a/b/g;
$var =~ s/^("+)(.*)\1$/$2/;

Те же шаблоны должны работать в PHP. Вы также можете избавиться от аргумента $limit для preg_replace:

$text = preg_replace('/\[(.*?)\]/e', '$array[\'$1\']', $text);

Регулярные выражения могут обрабатывать свои собственные циклы. Цикл за пределами RE неэффективен, поскольку RE должен обрабатывать текст, который он уже обработал в предыдущих итерациях.

1 голос
/ 04 декабря 2009
preg_replace('#\[(.*?)\]#e', "\$array['$1']", $text);
0 голосов
/ 03 декабря 2009

Может ли что-то подобное работать?

$var = preg_replace('/^("+)(.*)\1$', '$2', $var, 1);
0 голосов
/ 03 декабря 2009

Использование do-while :

do {
  $var = preg_replace('/^"(.*)"$/', "$1", $var, 1, $count);
} while ($count == 1);

Требуется не менее php-5.1.0 из-за использования $count.

Вы также можете написать

do {
  $last = $var;
  $var = preg_replace('/^"(.*)"$/', "$1", $var);
} while ($last != $var);
0 голосов
/ 03 декабря 2009

Как выглядят ваши входные данные?

Потому что вы проверяете двойные кавычки только в начале и в конце строки. Если это точно, то вам вообще не нужно фиксировать обратную ссылку. Кроме того, это сделало бы отправку 1 в качестве 4-го параметра совершенно ненужным.

$var = '"foo"';

// This works
echo preg_replace( '/^"(.*)"$/', '$1', $var );

// So does this
echo preg_replace( '/^"|"$/', '', $var );

Но если ваши входные данные выглядят иначе, это изменит мой ответ.

EDIT

Вот мое мнение о ваших фактических данных

class VariableExpander
{
  protected $source;

  public function __construct( array $source )
  {
    $this->setSource( $source );
  }

  public function setSource( array $source )
  {
    $this->source = $source;
  }

  public function parse( $input )
  {
    return preg_replace_callback( '/\[([a-z_]+)\]/i', array( $this, 'expand' ), $input );
  }

  protected function expand( $matches )
  {
    return isset( $this->source[$matches[1]] )
      ? $this->source[$matches[1]]
      : '';
  }
}

$text = "This is [site_name], home of the [people_type]";
$data = array(
    'site_name'   => 'StackOverflow.com'
  , 'people_type' => 'crazy coders'
);

$ve = new VariableExpander( $data );
echo $ve->parse( $text );

Класс предназначен только для инкапсуляции - вы можете сделать это структурированным способом, если хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...