Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

Разбор и валидация URL и DSN (Rumata)
Author Message
Rumata
Профессионал



Joined: 17 Aug 2003
Posts: 1850
Карма: 185
   поощрить/наказать


PostPosted: Mon Jan 21, 2008 7:24 pm (написано за 1 минуту 1 секунду)
   Post subject: Разбор и валидация URL и DSN
Reply with quote

DSN (Data Source Name) структурно похож на URL (наиболее полная информация доступна на странице pear.php.net/manual/en/package.database.db.intro-dsn.php).
Мне понадобилось совместить обработку и валидацию этих источников, при чем опционально необходимо разбирать и query string. Хост может быть задан как IP-адрес или имя, допустимо зарезервированное имя localhost.
Полагаю, что подобная работа уже проделана, но искать было лень. Не претендует на универсальность (достаточно вспомнить проблемы валидации email-адресов), но в большинстве случаев работает.
Если модераториат посчитает что не место на складе, можно перенести в более подходящее место.

Кратко.
Структура URL - protocol://user:password@host:port/path?query#fragment
Структура DSN - scheme:subscheme://user:password@host:port/path?query#fragment
Code (perl): скопировать код в буфер обмена
# Tries the first parameter as a DSN or an URL and returns separate parts as hash in success.
# The second parameter defines should we parse a query string into separate parts or return as single string.
#
# @param        string        $dsn
# @param        boolean        $parse_query
# @return        hash
sub parseDSN
{
        my $dsn = shift (www.perldoc.com/perl5.6/pod/func/shift.html);
        my $parse_query = shift (www.perldoc.com/perl5.6/pod/func/shift.html);

        $dsn =~ /
                \s (www.perldoc.com/perl5.6/pod/func/s.html)*
                (?:
                        # scheme:subscheme:\/\/
                        ([a-z]+) : (?: ([a-z]*) : )? \/\/
                )?
                (?:
                        # username:password@
                        ( [^:@]* ) (?: : ([^:@]*) )? @
                )?
                (
                        # hostname|localhost|IP
                        (?: [a-z0-9_-]+ \. )+ [a-z]{2,}
                        |
                        localhost
                        |
                        (?: (?: [01]?\d\d? | 2[0-4]\d | 25[0-5] ) \. ){3}
                        (?: (?: [01]?\d\d? | 2[0-4]\d | 25[0-5] ) )
                )
                (?:
                        # :port
                        : (\d+)
                )?
                (?:
                        # \/path
                        ([^:\?\#]+)
                )?
                (?:
                        # ?query
                        \? ([^\#]+)
                )?
                (?:
                        # #fragment
                        \# ([^\s]+)
                )?
                \s (www.perldoc.com/perl5.6/pod/func/s.html)*
        /ix;

        return (www.perldoc.com/perl5.6/pod/func/return.html) () unless defined (www.perldoc.com/perl5.6/pod/func/defined.html) $5;

        my %result = (
                scheme                => $1 || '',
                subscheme        => $2 || '',
                user                => $3 || '',
                pass                => $4 || '',
                host                => $5,
                port                => $6 || '',
                path                => $7 || '',
                query                => $8 || '',
                fragment        => $9 || '',
        );

        return (www.perldoc.com/perl5.6/pod/func/return.html) %result unless $parse_query;

        my %query = ();
        for my $par (split (www.perldoc.com/perl5.6/pod/func/split.html)('&', $result{query})) {
                next unless ( $par =~ /([^=]+)=(.*)/ );
                $query{$1} = $2;
        }
        $result{query} = \%query;

        return (www.perldoc.com/perl5.6/pod/func/return.html) %result;
}
Back to top
View user's profile Send private message
Rumata
Профессионал



Joined: 17 Aug 2003
Posts: 1850
Карма: 185
   поощрить/наказать


PostPosted: Tue Jan 22, 2008 12:04 pm (спустя 16 часов 39 минут; написано за 6 минут 43 секунды)
   Post subject:
Reply with quote

пример использования
Code (perl): скопировать код в буфер обмена
%ftp = parseDSN('ftp://user:password@localhost/pub/Software');
$dsn = parseDSN('jdbc:solid://localhost:1313');
%url = parseDSN('http://forum.dklab.ru/viewtopic.php?p=148989#148989', 1);
в последнем случае переменная %url будет содержать все элементы URL предыдущего сообщения
Code (perl): скопировать код в буфер обмена
(
  scheme => 'http',
  subscheme => '',
  user => '',
  pass => '',
  host => 'forum.dklab.ru',
  port => '',
  path => '/viewtopic.php',
  query => (
    p => '148989',
  ),
  fragment => '148989',
)
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Page 1 of 1    Email to a Friend.
You cannot post new topics in this forum. You cannot reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML