Использование preg_replace для замены всех вхождений в php - PullRequest
3 голосов
/ 10 января 2011

Regex - это абсолютно моя слабость, и это полностью меня озадачило. Я создаю довольно базовую функциональность поиска, и мне нужно иметь возможность изменять мой пользовательский ввод на основе следующего шаблона:

Тема:

%22first set%22 %22second set%22-drupal -wordpress

Желаемый вывод:

+"first set" +"second set" -drupal -wordpress

Хотелось бы мне больше помочь, так как обычно я хотел бы хотя бы опубликовать решение, которое у меня есть, но по этому вопросу я в растерянности.

Любая помощь приветствуется. Спасибо.

Ответы [ 3 ]

2 голосов
/ 10 января 2011

Кажется, ваши данные в кодировке URL.Если вы примените urldecode, вы получите

"first set" "second set" -drupal -wordpress

(я полагаю, у вас есть пробел до -drupal).

Теперь вам нужно добавить +.Опять же, я предполагаю, что вы должны добавить те слова перед всеми словами, которые не имеют - и не заключены в кавычки:

$str = '"first set" "second set" -drupal -wordpress foo';
echo preg_replace('#( |^)(?!(?:\w+"|-| ))#','\1+', $str));
// prints +"first set" +"second set" -drupal -wordpress +foo

Обновление: Если вы не можете использовать1017 *, вы можете просто использовать str_replace для замены %22 на ".

1 голос
/ 10 января 2011

Это то, что вы ищете?

<?php
  $input = "%22first set%22 %22second set%22-drupal -wordpress";
  $res = preg_replace( "/\%22(.+?)\%22/","+\"(\\1)\" ", $input);
  print $res;
?>
1 голос
/ 10 января 2011
preg_replace('/%22((?:[^%]|%[^2]|%2[^2])*)%22/', '+"$1"', $str);

Объяснение: $1 является обратной ссылкой, которая ссылается на первый () -секцию в регулярном выражении, в данном случае ((?:[^%]|%[^2]|%2[^2])*)[^%] и чередования (...|...|...) после него предотвращают совпадение %22 из-за жадности.См. http://en.wikipedia.org/wiki/Regular_expression#Lazy_quantification.

Я обнаружил эту технику в примере JavaCC сопоставления блочных комментариев (/* */), и я не могу найти другие веб-страницы, объясняющие это, поэтому вот более чистый пример: Чтобы соответствоватьблок текста между 12345 12345........12345 без 12345 между: /12345([^1]|1[^2]|12[^3]|123[^4]|1234[^5])*12345/

...