正则表达式 – 解析mysql:/// sqlite:/// URL
发布时间:2020-12-14 05:58:05 所属栏目:百科 来源:网络整理
导读:我们在一个模块中有这个小正则表达式来解析以下URL: if( my ($conn,$driver,$user,$pass,$host,$port,$dbname,$table_name,$tparam_name,$tparam_value,$conn_param_string) = $url =~ m{^((w*)://(?:(w+)(?::([^/@]*))?@)?(?:([w-.]+)(?::(d+))?
我们在一个模块中有这个小正则表达式来解析以下URL:
if( my ($conn,$driver,$user,$pass,$host,$port,$dbname,$table_name,$tparam_name,$tparam_value,$conn_param_string) = $url =~ m{^((w*)://(?:(w+)(?::([^/@]*))?@)?(?:([w-.]+)(?::(d+))?)?/(w*))(?:/(w+)(?:?(w+)=(w+))?)?((?:;(w+)=(w+))*)$} ) { MySQL的://anonymous@my.self.com:1234 / DBNAME 现在我们要添加sqlite URL的解析,如下所示: sqlite的:/// dbname_which_is_a_file 但它不适用于绝对路径,如:sqlite:/// tmp / dbname_which_is_a_file 这样做的正确方法是什么? 解决方法
正则表达式的问题是,对于长度超过两个元素的路径不起作用.它将它们拆分为db_name和table_name(如果有).此正则表达式也不适用于SQLite特殊文件名,如’:memory'(对于测试非常有用).
为了获得可维护的RE方法,使用它的最佳方法是使用一个调度表,其中包含需要不同解析的主要协议,并为每种不同的方法设置一个子程序.还有一个带有// x的RE,所以它可以有注释并帮助它的可维护性: sub test_re{ my $url =shift; my $x={}; @$x{qw(conn driver user pass host port dbname table_name tparam_name tparam_value conn_param_string)} = $url =~ m{ ^( (w*) :// (?: (w+) # user (?: : ([^/@]*) # password )? @ )? # could not have user,pass (?: ([w-.]+) #host (?: : (d+) # port )? # port optional )? # host and port optional / # become in a third '/' if no user pass host and port (w*) # get the db (only until the first '/' is any). Will not work with full paths for sqlite. ) (?: / # if tables (w+) # get table (?: ? # parameters (w+) = (w+) )? # parameter is conditional but would have always a tablename )? # conditinal table and parameter ( (?: ; (w+) = (w+) )* # rest of parameters if any ) $ }x; return $x; } 但我建议使用URI::Split(比URI更少的代码详细程度),然后根据需要拆分路径. 您可以在此处看到使用RE与URI :: Split的区别: #!/usr/bin/env perl use feature ':5.10'; use strict; use URI::Split qw(uri_join uri_split); use Data::Dumper; my $urls = [qw( mysql://anonymous@my.self.com:1234/dbname mysql://anonymous@my.self.com:1234/dbname/tablename mysql://anonymous@my.self.com:1234/dbname/pathextra/tablename sqlite:///dbname_which_is_a_file sqlite:///tmp/dbname_which_is_a_file sqlite:///tmp/db/dbname_which_is_a_file sqlite:///:dbname_which_is_a_file sqlite:///:memory )]; foreach my $url (@$urls) { print Dumper(test_re($url)); print Dumper(uri_split($url)); } 结果: [...] == testing sqlite:///dbname_which_is_a_file == - RE $VAR1 = { 'pass' => undef,'port' => undef,'dbname' => 'dbname_which_is_a_file','host' => undef,'conn_param_string' => '','conn' => 'sqlite:///dbname_which_is_a_file','tparam_name' => undef,'tparam_value' => undef,'user' => undef,'table_name' => undef,'driver' => 'sqlite' }; - URI::Split $VAR1 = 'sqlite'; $VAR2 = ''; $VAR3 = '/dbname_which_is_a_file'; $VAR4 = undef; $VAR5 = undef; == testing sqlite:///tmp/dbname_which_is_a_file == - RE $VAR1 = { 'pass' => undef,'dbname' => 'tmp','conn' => 'sqlite:///tmp','table_name' => 'dbname_which_is_a_file','driver' => 'sqlite' }; - URI::Split $VAR1 = 'sqlite'; $VAR2 = ''; $VAR3 = '/tmp/dbname_which_is_a_file'; $VAR4 = undef; $VAR5 = undef; == testing sqlite:///tmp/db/dbname_which_is_a_file == - RE $VAR1 = { 'pass' => undef,'dbname' => undef,'conn_param_string' => undef,'conn' => undef,'driver' => undef }; - URI::Split $VAR1 = 'sqlite'; $VAR2 = ''; $VAR3 = '/tmp/db/dbname_which_is_a_file'; $VAR4 = undef; $VAR5 = undef; == testing sqlite:///:memory == - RE $VAR1 = { 'pass' => undef,'driver' => undef }; - URI::Split $VAR1 = 'sqlite'; $VAR2 = ''; $VAR3 = '/:memory'; $VAR4 = undef; $VAR5 = undef; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |