Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Замена символов в URL

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Описание: с помощью регулярных выражений изменить URL
moroz11
Отправлено: 01 Ноября, 2014 - 13:50:14
Post Id


Новичок


Покинул форум
Сообщений всего: 7
Дата рег-ции: Март 2014  


Помог: 0 раз(а)




Получаю текущий URL:
$redi = substr(sefRelToAbs($_SERVER['REQUEST_URI']));

Он получается типа такой:
$redi = 'http://test.com/monitor/sadasdasd-23-0-67';

Нужно заменять символы в полученном URL после последнего тире на переменную.

Т.е. получить что-то наподобие
$redi = 'http://test.com/monitor/sadasdasd-23-0-$zamena';
где $zamena - переменная описанная отдельно.
 
 Top
jehaby
Отправлено: 05 Ноября, 2014 - 18:59:06
Post Id


Новичок


Покинул форум
Сообщений всего: 11
Дата рег-ции: Окт. 2014  


Помог: 0 раз(а)




Некропост, ну да ладно:

$res = preg_replace('/([^-]*)$/', $sub, $redi);
 
 Top
dcc0
Отправлено: 05 Ноября, 2014 - 23:28:51
Post Id


Участник


Покинул форум
Сообщений всего: 1043
Дата рег-ции: Июль 2014  


Помог: 10 раз(а)




Думаю "-" надо экранировать.


-----
Март 2021. Бросил программирование
 
 Top
jehaby
Отправлено: 06 Ноября, 2014 - 21:46:13
Post Id


Новичок


Покинул форум
Сообщений всего: 11
Дата рег-ции: Окт. 2014  


Помог: 0 раз(а)




Хм, тестил тут: http://regex101[dot]com/ , работало нормально.

Когда сейчас попробовал на PHP потестить, появился забавный баг, что с экранированием, что без:
CODE (htmlphp):
скопировать код в буфер обмена
  1.  
  2. urf@urf-pc ~/trash $ php t2.php
  3. $redi ==  http://test.com/monitor/sadasdasd-23-0-
  4. $res == http://test.com/monitor/sadasdasd-23-0-42
  5. urf@urf-pc ~/trash $ php t2.php
  6. $redi ==  http://test.com/monitor/sadasdasd-23-0-33
  7. $res == http://test.com/monitor/sadasdasd-23-0-4242
  8. urf@urf-pc ~/trash $ php t2.php
  9. $redi ==  http://test.com/monitor/sadasdasd-23-0-7
  10. $res == http://test.com/monitor/sadasdasd-23-0-4242
  11. urf@urf-pc ~/trash $ php t2.php
  12. $redi ==  http://test.com/monitor/sadasdasd-23-0-345345435
  13. $res == http://test.com/monitor/sadasdasd-23-0-4242


Появляется на разных версиях PHP. Буду признателен, если кто объяснит в чем тут дело. Проблема вроде как решается изменением * на +.
 
 Top
Мелкий Супермодератор
Отправлено: 07 Ноября, 2014 - 10:06:35
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




jehaby, напишите листинг t2.php Я не очень понимаю, что есть что.


-----
PostgreSQL DBA
 
 Top
jehaby
Отправлено: 07 Ноября, 2014 - 17:10:26
Post Id


Новичок


Покинул форум
Сообщений всего: 11
Дата рег-ции: Окт. 2014  


Помог: 0 раз(а)




PHP:
скопировать код в буфер обмена
  1. <?PHP
  2.  
  3. $redi = 'http://test.com/monitor/sadasdasd-23-0-345345435';
  4.  
  5. $sub = 42;
  6.  
  7. $res = preg_replace('/([^-]*)$/', $sub, $redi);
  8.  
  9. echo '$redi ==  ' . $redi . "\n";
  10. echo '$res == ' . $res . "\n";


Значение переменной $redi подставлял разное, видно в выводе из моего прошлого сообщения.
Пробовал на разных версиях PHP, и в консоли, и в браузере -- везде одно и то же.
 
 Top
Мелкий Супермодератор
Отправлено: 07 Ноября, 2014 - 19:28:42
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Проблема решается позитивной ретроспективной проверкой. Утверждением, что перед совпадением должен быть символ "-"

Суть ошибки:
Машина регулярных выражений штука довольно тупая, она стартует с первого символа исходной строки, примеряет регулярное выражение. Если совпало - отлично, делает что надо. Если не совпало, перемещается на следующий символ и опять проверяет. И так, символ за символом движется к концу строки. (это общий алгоритм, ради производительности добавляются оптимизации, анализирующие регулярку и исключающие части стрики, точно не попадающие под неё)
До позиции последнего символа - проблем нет, регулярка не совпадает.
Затем:
В позиции -23-0-^345345435 маска [^-] совпадает. * - это ноль или больше совпадений; звёздочка жадная, сразу хапает всего всего и побольше до первого символа, не совпадающего с маской. И это оказывается конец строки - а он нам и нужен, совпадение всего выражения, меняем на 42.
Далее сюрприз: мы находимся в позиции -23-0-345345435^ (аккурат в конце строки). * - это ноль или больше совпадений. Что там дальше? Ага, конец строки, это нас устраивает. Регулярка совпала, меняем (ничего, пустую строку) на 42.


-----
PostgreSQL DBA
 
 Top
MAXUS
Отправлено: 08 Ноября, 2014 - 10:08:33
Post Id


Посетитель


Покинул форум
Сообщений всего: 329
Дата рег-ции: Апр. 2011  


Помог: 7 раз(а)




moroz11 пишет:
Нужно заменять символы в полученном URL после последнего тире на переменную.


PHP:
скопировать код в буфер обмена
  1. $redi = 'http://test.com/monitor/sadasdasd-23-0-345345435';
  2. // $redi = 'http://test.com/monitor/sadasdasd-23-0-';
  3.  
  4. $sub = 42;
  5. $default = 56;
  6.  
  7. $one = explode('-',$redi);
  8. $one[count($one)-1] = ($one[count($one)-1])?$sub:$default;
  9. $one = implode('-',$one);
  10.  
  11. $two = preg_replace('/-[^-]*$/', '-'.$sub, $redi);
  12.  
  13. $three =  substr_replace($redi,$sub,strrpos($redi,'-')+1);
  14.  
  15. echo '$redi ==  ' . $redi . "<br />";
  16. echo '$one == ' . $one . "<br />";
  17. echo '$two == ' . $two . "<br />";
  18. echo '$three == ' . $three . "<br />";


Три способа. Если раскомментировать вторую строку, то будет видно, что даже если в конце после тире пусто, то все равно произойдет замена. В первом способе сделана проверка на наличие символов после последнего тире. Если после тире url обрывается, то будет подставлено 56 (default), если после тире есть символы, то будет подставлено 42(sub).

Смысл в том, что регулярка - не единственный способ для такой простой задачи. И это отнюдь не все варианты, которыми можно представленную задачу выполнить.

(Отредактировано автором: 08 Ноября, 2014 - 10:19:01)

 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Регулярные выражения »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB