我有一个config .ini文件,用户可以使用Perl正则表达式或Ant globbing模式指定文件模式。例如,以下内容将禁止用户创建Windows下不允许的文件:
[BAN Defined using Ant Globbing]
file = **/prn.*
ignorecase = true
[BAN Defined using Regular expressions]
match = /(aux|con|com[0-9]*|lpt[0-9]*|nul|clock$)\.?[a-z]$
ignorecase = true
现在,我必须将glob转换为正则表达式,以便以编程方式处理它。我有一个例程,但它有点复杂。我正在寻找以下其中一项:
例如:
if ($regex =~ /\/(aux|con|com[0-9]*|lpt[0-9]*|nul|clock$)\.?[a-z]$) {
if ($glob ?magic? /**/prn.*/) {
我希望有一些神奇的Perl方式来做到这一点。那么,有一个简单的不容错过的方法:
顺便说一句,这是我的子程序,以防有人感兴趣:sub glob2regex {
my $glob = shift;
my $regex = undef;
my $previousAstrisk = undef;
foreach my $letter (split(//, $glob)) {
#
# ####Check if previous letter was astrisk
#
if ($previousAstrisk) {
if ($letter eq "*") { #Double astrisk
$regex .= ".*";
$previousAstrisk = undef;
next;
} else { #Single astrisk: Write prev match
$regex .= "[^/]*";
$previousAstrisk = undef;
}
}
#
# ####Quote all Regex characters w/ no meaning in glob
#
if ($letter =~ /[\{\}\.\+\(\)\[\]]/) {
$regex .= "\\$letter";
#
# ####Translate "?" to Regular expression equivelent
#
} elsif ($letter eq "?") {
$regex .= ".";
#
# ####Don't know how to handle astrisks until the next line
#
} elsif ($letter eq "*") {
$previousAstrisk = 1;
#
# ####Convert backslashes to forward slashes
#
} elsif ($letter eq '\\') {
$regex .= "/";
#
# ####Just a letter
#
} else {
$regex .= $letter;
}
}
#
# ####Handle if last letter was astrisk
#
if ($previousAstrisk) {
$regex .= "[^/]*";
}
#
# ####Globs are anchored to both beginning and ending
#
$regex = "^$regex\$";
return $regex;
}
答案 0 :(得分:2)
鉴于:
如果您不关心格式检查和某些角落情况,例如' ***',那么您可以使用以下策略,首先将特殊字符转换为自定义设计的转义序列,然后将转义序列转换为最终字符串,可能有效:
my $rgx="^$glob\$";
$rgx=~ s|!|!e|g;
$rgx=~ s|[+]|!p|g;
$rgx=~ s|[*]{2}|!d|g;
$rgx=~ s|[*]|!s|g;
$rgx=~ s|[?]|!q|g;
$rgx=~ s|[.]|\\.|g;
$rgx=~ s|!d|.*|g;
$rgx=~ s|!s|[^/]*|g;
$rgx=~ s|!q|[^/]|g;
$rgx=~ s|!p|\\+|g;
$rgx=~ s|!e|!|g;
if ($path =~ m|$rgx|){
return 1;
}
答案 1 :(得分:1)
显然,从glob中创建正则表达式并没有巧妙的Perl Guru技巧。 Drats。
我能做的最好的事情就是找到像Text::Glob这样的CPAN模块。但是,Text::Glob
没有Ant样式扩展的globbing,所以无论如何我都要修改它。而且,代码并不比我已经拥有的代码简单。
所以,我只是坚持我拥有的东西。
非常感谢。