Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум Регулярные Выражения

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: preg_replace глобально
 
 автор: Qiao   (28.10.2008 в 08:50)   письмо автору
 
 

preg_replace по умолчанию глобальна, т.е. выполняется по всему тексту (т.е. //g).

Тогда почему код
$text = "444 2332 4324";
echo preg_replace ("|(\d+) (\d+)|", "$1$2", $text);

Выводит "4442332 4324" , т.е. убирается только первый пробел?

Подскажите, пожалуйста, как сделать, чтобы исчезали все пробелы.

  Ответить  
 
 автор: ddhvvn   (28.10.2008 в 10:18)   письмо автору
 
   для: Qiao   (28.10.2008 в 08:50)
 

Вы шутите? Зачем в таком случае "напрягать" рег. выражениями?

<?php
$text 
"444 2332 4324";
echo 
str_replace(' '''$text);
?>

  Ответить  
 
 автор: Qiao   (28.10.2008 в 10:51)   письмо автору
 
   для: ddhvvn   (28.10.2008 в 10:18)
 

В данном случае нужен именно preg_replace, так как наряду с цифрами в строке есть и текст, в котором убирать пробелы не нужно.

Но меня интересует сам принцип - почему preg_replace() в не работает глобально, а делает только первое совпадение?

  Ответить  
 
 автор: ddhvvn   (28.10.2008 в 11:18)   письмо автору
 
   для: Qiao   (28.10.2008 в 10:51)
 

Ну раз так...
<?php
$text 
"111 222 3333 а тут текст с пробелами 444 55";
echo 
preg_replace ("|(\d+) (\d+)|U""$1$2"$text);
?>

  Ответить  
 
 автор: Qiao   (28.10.2008 в 12:30)   письмо автору
 
   для: ddhvvn   (28.10.2008 в 11:18)
 

То есть проблема в "жадности"?
А как тут жадность проявляется.
сначала (111 222) 3333
потом 111 (222 3333) (или (111222 3333))

Вроде всё и без ungreedy должно работать.
Где здесь подвох?

  Ответить  
 
 автор: Trianon   (28.10.2008 в 12:38)   письмо автору
 
   для: Qiao   (28.10.2008 в 12:30)
 

почему Вы решили, что preg_replace будет обрабатывать свой собственный результат?

  Ответить  
 
 автор: ddhvvn   (28.10.2008 в 12:45)   письмо автору
 
   для: Qiao   (28.10.2008 в 12:30)
 

Чтобы самому не выдумывать умные слова, процитирую php.net касаемо "жадности" =)

По умолчанию, все квантификаторы являются "жадными", это означает, что они совпадают максимально возможное количество раз (но не более, чем максимально допустимое количество раз), не приводя к невозможности сопоставления остальных частей шаблона. Классический пример проблем, которые могут возникнуть в связи с такой особенностью квантификаторов - нахождение комментариев в C-программах. Комментарием считается произвольный текст, находящийся внутри символьных комбинаций /* и */ (при этом, символы '/' и '*' также могут быть частью комментария). Попытка найти комментарии при помощи шаблона /\*.*\*/ в строке /* первый комментарий */ не комментарий /* второй комментарий */ закончится неудачей, поскольку указанный шаблон соответствует всей строке целиком (из-за жадности кватификатора '*').
...
В случае, если установлена опция PCRE_UNGREEDY (отсутствующая в Perl), квантификаторы являются не жадными по умолчанию, но могут становиться жадными, если за ними следует символ '?'. Говоря другими словами, знак вопроса инвертирует жадность квантификаторов.

  Ответить  
 
 автор: Trianon   (28.10.2008 в 12:52)   письмо автору
 
   для: ddhvvn   (28.10.2008 в 12:45)
 

да не в жадности дело.
Строка может оказаться и такой: 0 1 2 3 4 5 6 7 8 9
И что тогда?

Здесь нужно применить опережающую/ретроспективную проверку.

  Ответить  
 
 автор: ddhvvn   (28.10.2008 в 14:30)   письмо автору
 
   для: Trianon   (28.10.2008 в 12:52)
 

Хм.. да уж...
Тут я уже не очень "шарю", может что-то вроде этого
<?php
$text 
"0 1 2 3 4 5 6 7 8 9";
echo 
preg_replace ("|(?<=\d) (\d)|""$1$2"$text);
?>

  Ответить  
 
 автор: soap   (28.10.2008 в 11:14)   письмо автору
 
   для: Qiao   (28.10.2008 в 08:50)
 

>Подскажите, пожалуйста, как сделать, чтобы исчезали все пробелы.

$text = "444 2332 4324";
echo preg_replace ("|(\d+) (\d+) (\d+)|", "$1$2$3", $text);

  Ответить  
 
 автор: Qiao   (28.10.2008 в 16:37)   письмо автору
 
   для: soap   (28.10.2008 в 11:14)
 

soap - количество групп может быть любым.

В последнем варианте можно убрать вторую переменную, так как в первых скобках захвата нет:
<?php
$text 
"0 1 2 3 4 5 6 7 8 9";
echo 
preg_replace ("|(?<=\d) (\d)|""$1"$text);
?> 


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

  Ответить  
 
 автор: Trianon   (28.10.2008 в 16:47)   письмо автору
 
   для: Qiao   (28.10.2008 в 16:37)
 

-

  Ответить  
 
 автор: ddhvvn   (28.10.2008 в 16:49)   письмо автору
 
   для: Trianon   (28.10.2008 в 16:47)
 

да, точно, мой косяк! )

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования