mod_rewrite. Преобразование динамических URL в статические


Создание с помощью mod_rewrite ссылок "понятных" для поисковиков.

Введение

Один из наиболее частых вопросов, задаваемых на форумах об Apache, звучит так: "Как мне с помощью mod_rewrite преобразовать динамические URL в статические?" Эта статья собирается ответить на этот вопрос, а также прояснить некоторые заблуждения, связанные с этим вопросом.

Mod_rewrite не может изменить URL в браузере пользователя


Первое заблуждение: mod_rewrite нельзя использовать для изменения URL, который видит посетитель в адресной строке своего браузера, за исключением возможности использования внешнего редиректа. Но внешний редирект "оголит" динамический URL поисковику, тем самым полностью нарушит нашу цель. Наша цель в том, чтобы сделать статические URL с помощью внутренних преобразований на сервере, не используя внешнего редиректа клиента.
Также важно понимать, что mod_rewrite работает с URL после того, как сервер получил HTTP запрос и до того, как выполнится скрипт или обработается контент. Таким образом, mod_rewrite может менять путь файла на сервере и переменные, связанные с запрошенным URL, но не может изменить контент, отсылаемый сервером.

Как изменить динамический URL на статический

Вот алгоритм, который надо выполнить для создания статических URL на динамическом сайте:
  • Преобразовать все ссылки на всех страницах сайта в статический формат. Обычно это делается путем изменения базы данных или скрипта, который генерирует данные страницы. В некоторых случаях с этой задачей быстро справляется функция PHP - preg_replace().
  • Добавить в файл httpd.conf или .htaccess правила mod_rewrite для внутреннего преобразования статических URL, которые были запрошены клиентом, в динамический вид, необходимый для вызова скрипта генерации контента.
  • Добавить дополнительный код mod_rewrite для прямых запросов клиента на динамический URL и перенаправлять их (внешним редиректом) на соответствующий статический URL. Для этого используется 301 редирект (”Постоянно перемещен”), который уведомляет поисковики, что вместо старых динамических URL нужно использовать новые статические. Также внешний редирект перенаправляет посетителей, которые пришли на ваш сайт, используя старую динамическую ссылку из своих закладок.
Рассматривая вышесказанное, можно догадаться, что оба формата: и динамический, и статический URL должны содержать в себе всю информацию, необходимую для преобразования в другой формат. И запомните, что осторожный выбор "дизайна" статических URL в будущем может уберечь вас от многих проблем, а также уменьшить количество циклов процессора, которое может сильно вырасти при неумелой реализации такого преобразования.

Важное предупреждение

В цели этой статьи не входит объяснение принципов работы регулярных выражений и модуля mod_rewrite. Документация по mod_rewrite и множество других мануалов легко доступны для всех желающих.
А попытка же использовать mod_rewrite без полного ознакомления с этой документацией - первый шаг (а часто и последний) к серьезным проблемам. Запомните, что mod_rewrite влияет на конфигурацию вашего сервера и достаточно одной опечатки или логической ошибки, чтобы сделать ваш сайт недоступным для посетителей или быстро понизить ваши рейтинги в поисковых сервисах. А если ваш заработок зависит от сайта, то вам тем более необходимо внимательно изучить всю документацию.
Подробно о регулярных выражения можно прочитать в книге "Освой самостоятельно регулярные выражения", которую можно преобрести в Bolero или в Озоне
Ниже приведен пример, который можно использовать в качестве основы при построении собственного решения.

Рабочий пример

Старый динамический формат URL: index\.php?product=widget&color=blue&size=small&texture=fuzzy&maker=widgetco
Новый статический формат URL: /product/widget/blue/small/fuzzy/widgetco
Код mod_rewrite, используемый в .htaccess:
# Запуск mod_rewrite
Options +FollowSymLinks
RewriteEngine on
#
# Внутренние преобразования статических URL в динамические
RewriteRule ^product/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/?$
/index.php?product=$1&color=$2&size=$3&texture=$4&maker=$5 [L]
#
# Внешний редирект клиента со старых динамических URL на новые статические
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\
/index\.php\?product=([^&]+)&color=([^&]+)&size=([^&]+)&texture=([^&]+)&maker=([^\ ]+)\ HTTP/
RewriteRule ^index\.php$ http://example.com/product/%1/%2/%3/%4/%5? [R=301,L]
Заметьте, что слово "product" всегда присутствует и в статическом, и в динамическом формате. В этом случае mod_rewrite проще определить запросы, где необходимо применять приведенные выше правила. Другие методы, такие как проверка на существование файла, также можно использовать, но они менее эффективны и более подвержены ошибкам сравнения.

Различия между использованием .htaccess и httpd.conf

Если вы будете использовать правила mod_rewrite в контейнере <directory> конфигурационного файла httpd.conf, то вам потребуется добавить в регулярные выражения обеих директив RewriteRule слеш (/). Например, придеться изменить "RewriteRule ^index\.php$" на "RewriteRule ^/index\.php$". Также запомните, что вам надо перезапустить сервер, чтобы внесенные изменения в файле конфигурации начали действовать.

Как это работает

  • Посетитель использует браузер для просмотра одной из ваших страниц
  • Посетитель кликает по ссылке <a href="/product/gizmo/red/tiny/furry/gizmocorp">Tiny red furry gizmos by GizmoCorp!</a>
  • С вашего сервера браузер запрашивает виртуальный файл http://example.com/product/gizmo/red/tiny/furry/gizmocorp
  • Вызывается mod_rewrite и первое правило переформировывает запрос в /index\.php?product=gizmo&color=red&size=tiny&texture=furry&maker=gizmocorp, вызывая скрипт
  • Ваш скрипт генерирует запрошенную страницу, и сервер отсылает ее обратно браузеру клиента
  • Посетитель кликает на другую ссылку и процесс повторяется
Теперь давайте посмотрим, как паук поисковика посетит ваш сайт, используя старый динамический URL:
  • Паук запрашивает с вашего сервера: http://example.com/index\.php?product=wodget&color=green&size=large&texture=smooth&maker=wodgetsinc
  • Вызывается mod_rewrite и второе правило генерирует 301 редирект, информирующий паука, что запрошенная страница была перенесена на URL: http://example.com/product/wodget/green/large/smooth/wodgetsinc
  • Паук отправляет запрос в свою базу адресов, чтобы изменить в ней старый динамический URL на новый, полученный из редиректа.
  • Паук вновь запрашивает страницу, которую он искал, но на этот раз, используя новый статический URL: http://example.com/product/wodget/green/large/smooth/wodgetsinc
  • Вызывается mod_rewrite и первое правило переформировывает запрос в /index\.php?product=wodget&color=green&size=large&texture=smooth&maker=wodgetsinc, вызывая скрипт
  • Ваш скрипт сгенерирует запрошенную страницу, и сервер вернет ее обратно поисковому пауку для последующего парсинга и построения поискового индекса
  • Теперь паук будет обрабатывать страницы, содержащие новые статические ссылки и все запросы на старые динамические URL будут перенаправлены на новые статические URL, а новые URL в результатах поиска со временем заменят старые.

Размещение правил mod_rewrite

Чтобы приведенный код работал надлежащим образом, он должен быть размещен в файле .htaccess в том же каталоге, где и /index.php. Также он может быть помещен в контейнер <directory> в файле httpd.conf, который ссылается на этот каталог.

Регулярные выражения

Тут я приведу только одно замечание по поводу регулярных выражений, использованных выше. Я избегаю использования очень простых и популярных, но очень неэффективных конструкций "(.*)/(.*)". Ибо использование множества конструкций ".*" в регулярных выражениях очень неэффективно.
Причины этому две. Первое - ".*" означает "подставить любое число любых символов". И второе - конструкция ".*" очень "прожорливая", что означает, что в шаблон подставится максимально возможное количество символов. А это в свою очередь означает, что, перед тем как запрошенный URL совпадет или не совпадет с регулярным выражением, произойдет множество подстановок, количество которых равно (количеству символов между "/" и концом запрашиваемого URL минус 2) умноженное на (количество "(.*)" минус один). Легко сделать регулярное выражение со множеством "(.*)", разбор которого потребует десятки или даже сотни проходов.
Давайте взглянем на короткий пример. Обратная связь $1 содержит символы, подставляемые в первую "(.*)", а $2 - символы, подставляемые во вторую:
Запрошенный URL: http://example.com/abc/def
Локальный путь: abc/def
Шаблон правила: ^(.*)/(.*)$
№ прохода Значение $1 Значение $2 Результат
1 … abc/def . - …… не совпадает
2 … abc/de . f …… не совпадает
3 … abc/d .. ef ….. не совпадает
4 … abc/ … def …. не совпадает
5 … abc …. def …. совпадает
Я осмелюсь предположить, что множество сайтов проводят каждый год обновление серверов, но эту ошибку оставляют.
Вместо этой конструкции я использую "([^/]+)", "([^&]+)" и "([^\ ]+)". В грубом переводе они соответственно означают "подставить один или несколько символов не равных слешу", "подставить один или несколько символов не равных &" и "подставить один или несколько символов не равных пробелу". Разница заключается в том, что каждая из этих конструкций будет "потреблять" один или более символов из запрошенного URL, увеличивая количество на один, тем самым, позволяя парсеру регулярных выражений проверить запрошенный URL за один проход слева-направо.

Частые проблемы

Самой частой проблемой, встречающейся при реализации преобразований URL из динамических в статические - это когда "ломаются" относительные ссылки внутри вашей страницы (на изображения, на CSS файлы и внешние JavaScript). Проблема в том, что клиент (например браузер) сам обрабатывает относительные ссылки. Например, если вы обрабатываете URL product/widget/blue/fuzzy/widgetco, то браузер увидит страницу "widgetco" и будет обрабатывать относительные ссылки этой страницы относительно "виртуального" каталога /product/widget/blue/fuzzy/. Есть два простых решения этой проблемы. Первое - это использовать серверо-относительные ссылки (или абсолютные ссылки), или использовать дополнительные mod_rewrite правила для преобразования URL картинок, CSS файлов и т.п. Вот пример использования серверно-относительной ссылки <img src="/logo.gif">, которая заменяет странично-относительную ссылку <img src="logo.gif">.

Проблемы при тестировании

Как для .htaccess, так и для httpd.conf перед тестированием любых изменений не забывайте очищать кеш браузера. Иначе ваш браузер обработает одну из ранее запрошенных страниц из кеша. Понятно, что в этом случае, новый код не выполнится.

Сперва прочитайте, затем пишите и тестируйте

Я надеюсь, что эта статья будет полезной. Если после чтения документации о mod_rewrite и регулярных выражений у вас все еще остались проблемы, то спокойно задавайте вопросы на форуме Apache.
Источник: WebmasterWorld Forum
Автор: jdMorgan
Перевод: ApacheDev.ru

These icons link to social bookmarking sites where readers can share and discover new web pages.
  • News2.ru
  • NewsLand.ru
  • del.icio.us
  • BobrDobr.ru
  • Ma.gnolia
  • Digg
  • Reddit
  • Technorati
  • Slashdot
  • Netscape
  • DZone
  • ThisNext
  • Furl
  • YahooMyWeb
Опубликовано в: Модули Apache Июль 31, 2006

52 Комментариев »

  1. А есть ли подобные правила для IIS?

    Комментарий от joomlance — Октябрь 27, 2006 @ 9:51 am

  2. поиск всем поможет

    Комментарий от -=hades=- — Ноябрь 6, 2006 @ 12:43 pm

  3. Здравствуйте!
    Обращение к автору - ваш пример преобразования ссылок не работает. Никаких ошибок. С чем это может быть связано?

    Комментарий от Alex — Ноябрь 28, 2006 @ 12:00 am

  4. Насчет того что ломаются относительные ссылки.
    Часто оптимальное решение - вписать в всех страниц (обычно для этого достаточно одного исправления в движке) тег .

    Комментарий от Леха — Ноябрь 30, 2006 @ 12:57 pm

  5. Движок вырезал тег.
    В <head> страниц вписать <base href=”http://site.com/”>.

    Комментарий от Леха — Ноябрь 30, 2006 @ 12:59 pm

  6. Не совсем в тему:
    В корне сайта лежит htaccess.
    D:/www/.htaccess

    RewriteEngine on
    Options +FollowSymLinks
    RewriteCond %{HTTP_HOST} ^xxx\.com$
    RewriteRule (.*) http://www.xxx.com/$1 [L,R=301,QSA]
    ...

    В папке сайта mod лежит htaccess.
    D:/www/mod/.htaccess

    RewriteEngine on
    RewriteOptions inherit
    Options +FollowSymLinks
    ...

    В папке сайта nomod нет htaccess.
    http://xxx.com
    -> http://www.xxx.com/
    good
    http://xxx.com/nomod
    -> http://www.xxx.com/nomod/
    good
    http://xxx.com/mod/25
    -> http://www.xxx.com/25
    bad
    Дело в том, что apache не вставляет вот сюда так называемый “rewritebase”:
    RewriteRule (.*) http://www.xxx.com/_$1
    Что делать?
    Заранее спасибо.

    Комментарий от Андрей Анатольевич — Декабрь 26, 2006 @ 1:39 pm

  7. Спасибо большое! Пригодилось!

    Комментарий от Секс порно — Январь 29, 2007 @ 1:56 am

  8. Класс! Все работает превосходно! Давно искал подобную статью.

    Комментарий от Илья — Февраль 26, 2007 @ 4:46 pm

  9. Спасибо. Классная статья. А как проверить, что внешний редирект клиента со старых динамических URL на новые статические я написал правильно? Ведь если я введу динамический URL в адресную строку браузера, то откроется нужная страница.
    Системы Управления Содержанием - CMS

    Комментарий от xiva — Апрель 29, 2007 @ 5:13 pm

  10. Не работает правило.
    RewriteEngine On
    RewriteRule ^([A-Za-z]+)/([A-Za-z0-9]+)/([A-Za-z0-9.]+)$ /cgi-bin/gf.cgi?key=$1&type=$2&by=$3
    чтобы строка вида
    http://domain/cgi-bin/gf.cgi?key=3490&type=id&by=firm
    преобразовалось в вида
    http://domain/3490/id/firm

    Комментарий от Владимир — Июль 6, 2007 @ 6:35 pm

  11. Пример не работает. Сервер выдает внутреннюю ошибку

    Комментарий от Anonymous — Август 22, 2007 @ 8:41 pm

  12. http://www.o-art.ru/

    Комментарий от оксана — Сентябрь 5, 2007 @ 8:20 am

  13. работает

    Комментарий от Democ — Октябрь 5, 2007 @ 7:41 pm

  14. Все там работает, просто нужно RewriteRule и RewriteCond писать в одну строчку.

    Комментарий от Ярославцев — Октябрь 22, 2007 @ 8:41 pm

  15. Спасибо, хорошая статья. Хотелось бы добавить насчет Options +FollowSymLinks
    Если в httpd.conf директива уже прописана, то в .htaccess ее дублировать ненадо. Кроме того, может получиться ошибка 500.

    Комментарий от монтаж систем отопления — Ноябрь 14, 2007 @ 3:45 pm

  16. Спасибо, отличная статья. Есть один вопрос:
    В папке folder лежит файл .htaccess со след. правилом
    RewriteBase /folder/
    RewriteRule (.*) form.php?q=$1 [L,QSA]
    При обращении к URL:
    www.xxx.ru/folder/
    В form.php передается параметр q=/folder/
    При обращении к URL
    www.xxx.ru/folder (без слэша)
    URL преобразуется в
    www.xxx.ru/folder/?q=C:/Apache2/htdocs/folder
    т.е. п параметр передается путь к папке на сервере.
    В чем дело во втором случае? Откуда берется этот параметр?

    Комментарий от Сергей — Ноябрь 25, 2007 @ 1:48 am

  17. Полезная статейка, надо бы разобраться в этой теме.
    Кстати, по поваду заблуждений. Вот тут сравниваются форматы графических файлов gif jpg png. Весьма интересно описано:)

    Комментарий от Vovovich — Ноябрь 28, 2007 @ 2:57 pm

  18. Спасибо, полезная статья! Кратко и понятно написано, адекватные примеры.
    C успехом применил вышеизложенное для сайта неправильных глаголов * thumb up *

    Комментарий от mishel — Ноябрь 29, 2007 @ 1:43 pm

  19. Давно пытался осмыслить, как все это работает, а тут более менее понятно все рассказано. Спасибо! Пойду пытать нововведение на свой сайт..

    Комментарий от Alex446 — Январь 26, 2008 @ 4:58 pm

  20. Ну, вот!!! хоть что-то вразумительное о СУТИ этого зверя! спасибо огромное

    Комментарий от org — Март 17, 2008 @ 10:52 am

  21. У меня ни в какую не хочет работать. Двиг Вордпресс, апач 2.0. mod_rewrite загружен, htaccess прописан

    Комментарий от Sergeshk — Март 20, 2008 @ 1:10 am

  22. Наконец, что-то хорошее было мной найдено, спасибо!

    Комментарий от de — Апрель 26, 2008 @ 10:50 pm

  23. Статья хорошая, новичкам сразу все должно стать понятно :) Но вот если бы разжевали правила COND - цены б ей не было :D
    Спасибо за статью, ткнул в нее носом одного тру-кодера )))

    Комментарий от MultiEngine — Июнь 8, 2008 @ 4:58 am

  24. Здравтвуйте!
    Спасибо автору за эту статью.
    Очень хорошая и понятная статья. Это единственное, что я мог найти в интернете хорошего на эту тему.
    Но у меня есть один вопрос к автору.
    Я планирую перевести сайт на статические URL используя .htaccess
    Протестировал внутренние преобразования статических URL в динамические, как советовал автор. Все прекрасно работает.
    Но пока не хочу использовать редирект 301, в силу невозможности корректного тестирования и вероятности ошибки, которая может привести к исключению страницы из индекса. Скажите пожалуйста, что будет, если не использовать 301 редирект? Как поведет себя поисковый робот в этом случае?
    Мне кажется, если не использовать этот редирект, поисковый робот, при обходе страниц по старым, динамическим ссылкам, найдет эти страницы и оставит их у себя в базе данных. Но, так как, внутренние ссылки были преобразованы к статическому формату, он найдет их и будет воспринимать как новые. Поэтому он просто должен добавить их в базу данных.
    Это мое мнение, но возможно я не прав. Подскажите пожалуйста.
    Заранее благодарен за совет.

    Комментарий от Андрей — Июнь 10, 2008 @ 2:11 pm

  25. нихрена не работает :(

    Комментарий от kay — Июнь 19, 2008 @ 8:30 pm

  26. Все давно работает :)

    Комментарий от zds — Июль 7, 2008 @ 4:04 am

  27. не могу настроить на апач 2 mod_rewrite … устал уже настраивать!

    Комментарий от regtool — Июль 11, 2008 @ 5:42 am

  28. Очень полезная статья, спасибо

    Комментарий от Евгений — Август 7, 2008 @ 4:30 am

  29. а что делать если при использовании
    Options +FollowSymLinks
    вылетает 500 ошибка, т е сайт становится уже совсем не доступным, но закомментировав эту строку все работает, кроме чистых ссылок… что делать, не подскажите ?

    Комментарий от akr0 — Август 14, 2008 @ 11:05 pm

  30. Спасибо! Все работает!!!

    Комментарий от RUSty — Август 27, 2008 @ 4:20 pm

  31. Мне оч понравилась статейка!!! РЕСПЕКТ АВТОРУ!!
    ____________________
    http://www.alt-e.ru/

    Комментарий от андрюха — Сентябрь 4, 2008 @ 7:40 pm

  32. Ничего не получается.
    Например исходный URL all.php?act=articles&subact=articles_plis
    # Внутренние преобразования статических URL в динамические написанные в одну строку
    RewriteRule ^act/([^/]+)/([^/]+)/?$/all.php?act=$1&subact=$2 [L]
    При наборе в броузере http://acvarif.info/act/articles/articles_plis выскакивает ошибка 404
    Что не так? Может кто подскажет

    Комментарий от Yuy — Сентябрь 14, 2008 @ 10:34 pm

  33. Ещё бы то же самое для произвольного количества переменных.
    Адреса своего сайта СМС-Дневник вида mgushka.ru/saratov/shkola13/9/a привожу к виду mgushka.ru?url[]=saratov&url[]=shkola13&url[]=9&url[]=a
    Чтобы и школа и параллель и класс имели свою страничку.
    Кроме кучи пар условие-правило (один слеш - первое правило, два слеша - второе правило, etc) ничего придумать не могу.

    Комментарий от Александр — Сентябрь 19, 2008 @ 3:25 pm

  34. Еще примеры использования mod_rewrite
    http://beget.ru/art10.html

    Комментарий от Alexey — Сентябрь 23, 2008 @ 10:41 am

  35. кстати, когда сталкиваешься с такой услугой, как регистрация сайта, этим модулем надо обязательно пользоваться !!!
    Так поисковики намного лучше индексируют сайт …

    Комментарий от seo — Ноябрь 3, 2008 @ 7:49 pm

  36. Правильно mod_rewrite реализован не везде правильно, аот например на сайте Краски Ярославля они реализованы правильно - рекомендую всем новичкам !

    Комментарий от краска — Ноябрь 3, 2008 @ 7:51 pm

  37. Посмотрите, как я реализовал модуль в своем блоге Кулинарные рецепты
    Если недочеты …

    Комментарий от Алкоголь — Ноябрь 3, 2008 @ 7:53 pm

  38. 2Yuy (пост №32), для твоих целей можно так сделать:
    ######
    RewriteEngine on
    RewriteBase /
    RewriteRule ^act/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)?$ all.php?act=$1&subact=$2 [NC,L]
    ######
    Должно работать.
    Я вобще с mod_rewrite разобрался с этого примера использования mod_rewrite. просто и понятно, автору респект. Для моих целей пока вполне хватает..

    Комментарий от Иван — Ноябрь 15, 2008 @ 4:05 pm

  39. Приветствуем Вас в нашем салоне здоровья!
    Кому из нас приятны визиты к врачу? Обследование, анализы и утомительное лечение - занятие не из приятных. Не удивительно, что зачастую мы идем на обследование и лечение, когда это становится жизненно необходимым

    Комментарий от Inga — Ноябрь 28, 2008 @ 3:32 pm

  40. А можно ли сдалать так: site.ru/page/ обрабатывается скриптом site.ru/index.php?p=page, а site.ru/page/?print=1 - скриптом site.ru/index.php?p=page&print=1 У меня не получилось…

    Комментарий от kimo — Декабрь 4, 2008 @ 12:24 pm

  41. Спасибо за статью. На ее базе справился с задачей перевода сайта на статические ссылки и даже написал кое- что про mod_rewrite на дополнительных доменах.

    Комментарий от Yury — Декабрь 14, 2008 @ 12:48 am

  42. Всё работает, спасибо! С наступающим Новым Годом, друзья!

    Комментарий от погодомерка — Декабрь 21, 2008 @ 8:39 am

  43. А я в блоге Гугла читал, что не стоит преобразовывать динамические УРЛы в статические.

    Комментарий от гипноз — Декабрь 22, 2008 @ 5:11 pm

  44. Полезная статья!

    Комментарий от Фотокритик — Декабрь 24, 2008 @ 10:00 am

  45. а можно ли при помощи регулярных выражений сделать исключение. То есть срабатывание в случае определённого слова в урле?

    Комментарий от gexly — Январь 12, 2009 @ 4:45 am

  46. Узнала немало нового - спасибо за детальное разъяснение!

    Комментарий от Eva — Февраль 6, 2009 @ 9:17 am

  47. Спасибо! Данная статья помогла решить проблему “исчезновения” картинок при использовании mod_rewrite в .htaccess. Теперь можно уверенно переводить сайт на php, сохранив при этом статический вид сайта. :) Автору респект и особое спасибо!!!

    Комментарий от Константин — Февраль 9, 2009 @ 3:41 pm

  48. Отлично помогло!!!

    Комментарий от gorchakov_gg — Март 2, 2009 @ 8:18 pm

  49. Хотелось бы посоветоваться по поводу линков такого вида
    http://site.ru/index.php?go=News&in=view&id=1
    как тут быть? До каталога News - все работает - дальше нет… В htaccess писано:
    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^([^/]*)(/?)$ index.php?go=$1 [L,QSA]
    Если не сложно посоветуйте че-нить(((

    Комментарий от Михаил — Март 8, 2009 @ 11:36 am

  50. to: Михаил
    /2007/02/27/generator-staticheskih-url/

    Комментарий от ALEXEY_adult — Март 11, 2009 @ 7:05 am

  51. Хорошая статья все подробно расписано, правда не приведено примеров сложных регулярок.

    Комментарий от MoneyCraft — Апрель 12, 2009 @ 6:15 pm

  52. Спасибо, очень помогло!

    Комментарий от Теодор — Апрель 15, 2009 @ 3:58 pm

Оставить комментарий

You must be logged in to post a comment.

Работает на WordPress