在Perl中,如何验证只有八位数字和扩展名的文件名?

在Perl中,如何验证只有八位数字和扩展名的文件名?,perl,validation,Perl,Validation,Perl(没有加载模块并且-Tw&strict) 我在这里找到了很多关于正则表达式和模式匹配的信息,但并不完全是我需要的。 我想知道这是否是验证一些东西的正确方法。 很抱歉初学者在这里尝试。我对这件事很陌生 my $this = "12345678"; if ($this != m/\b[0-9]{8}\b/x) { print "$this is bad"; } my $that = "12345678.gif"; if ($that != m/\b[0-9]{8}\.gif\b/x)

Perl(没有加载模块并且-Tw&strict) 我在这里找到了很多关于正则表达式和模式匹配的信息,但并不完全是我需要的。 我想知道这是否是验证一些东西的正确方法。 很抱歉初学者在这里尝试。我对这件事很陌生

my $this = "12345678";

if ($this != m/\b[0-9]{8}\b/x) { print "$this is bad"; }

my $that = "12345678.gif";

if ($that != m/\b[0-9]{8}\.gif\b/x) { print "$that is bad"; }

or

if ($that != m/\b[0-9]{8}\.(jpe?g|gif|png)\b/x) { print "$that is bad"; }


my ($ext) = $that =~ m/\.([^\.]+)$/x;

# verify extension
if  ($ext != m/\.(jpe?g|png|gif)$/x ){ print "$ext is bad"; }

# for content type
if ($ext eq "jpg") {$ext = "jpeg";} 
我之所以使用/x,是因为perl::critic指出我需要它。使用/x传递,因此

\d不是一个选项,应该避免我在这里读到的内容

文件名“that”必须是8位数字+图像类型。另一组数字“this”实际上是一个文件夹名。这为图像服务脚本提供了一点错误检查。根htaccess将对特定文件夹中的图像的调用发送到所述脚本。我通过路径信息获取目录和图像名称


我感谢过去和现在的所有建议。。。我学到了很多。

你上面的大部分看起来都不错。有几点:

  • 如果($ext!=m/pattern/)
    是错误的,
    =运算符应为
    ~
  • \如果您正在解析文件名或其他不太可能是unicode的东西,那么d就可以了
  • 除非您真的需要/x,否则不要使用它(您不会为了可读性而将regexp拆分为多行)。因此,除非您需要,否则请避免使用任何旗帜
  • (jpe?g | gif | png)
    可以修改为
    (?:jpe?g | gif | png)
    以禁用对该括号集的捕获(效率的提高在大多数情况下是名义上的,但有时会产生影响,例如在快速循环中,因此我养成了不捕获的习惯,除非我需要)
  • 你不需要在字符类中转义
    ,也就是说,
    [^\.]
    可以是
    [^.]
    (我相信你需要转义的唯一字符是]本身,但不要把这当作福音):)
  • 它是“Perl”,而不是“Perl”:

上面的大部分内容看起来都不错。有几点:

  • 如果($ext!=m/pattern/)
    是错误的,
    =运算符应为
    ~
  • \如果您正在解析文件名或其他不太可能是unicode的东西,那么d就可以了
  • 除非您真的需要/x,否则不要使用它(您不会为了可读性而将regexp拆分为多行)。因此,除非您需要,否则请避免使用任何旗帜
  • (jpe?g | gif | png)
    可以修改为
    (?:jpe?g | gif | png)
    以禁用对该括号集的捕获(效率的提高在大多数情况下是名义上的,但有时会产生影响,例如在快速循环中,因此我养成了不捕获的习惯,除非我需要)
  • 你不需要在字符类中转义
    ,也就是说,
    [^\.]
    可以是
    [^.]
    (我相信你需要转义的唯一字符是]本身,但不要把这当作福音):)
  • 它是“Perl”,而不是“Perl”:

如果您在污染检查下运行,这不是执行此操作的方法。您需要匹配所需的模式,然后记住在内存变量中清除污染:

my $this = ...;

my $regex = qr/
          ^             # beginning of string
          (             # start of $1
            [0-9]{8}
            \.
            (gif|jpg)   # extension in $2
          )
          \z            #end of string
          /x;

my( $cleansed, $extension ) = do { 
    if( $this =~ m/$regex/ ) { ( $1, $2 ) }
    else                  { die "Bad filename!" }
    };
我不知道为什么在正则表达式的开头有一个
\b
。它可能并不像你想象的那样。如果希望文件名仅为数字,请改用字符串锚点的开头。这样,数字之前就不会出现任何东西。类似地,字符串结束锚点
\z
表示在扩展之后不能出现任何内容

如果然后需要将扩展与HTTP响应的内容类型相匹配(我猜您正在这样做),则可以使用哈希来生成映射:

 my %types = (
      jpg => jpeg,
      gif => gif,
      ...
      );
现在您有了散列,可以将其用作另一个验证级别:

 unless( exists $types{$extension} ) { die "Unsupported type!" }

如果你是在污染检查下运行的,这不是一种方法。您需要匹配所需的模式,然后记住在内存变量中清除污染:

my $this = ...;

my $regex = qr/
          ^             # beginning of string
          (             # start of $1
            [0-9]{8}
            \.
            (gif|jpg)   # extension in $2
          )
          \z            #end of string
          /x;

my( $cleansed, $extension ) = do { 
    if( $this =~ m/$regex/ ) { ( $1, $2 ) }
    else                  { die "Bad filename!" }
    };
我不知道为什么在正则表达式的开头有一个
\b
。它可能并不像你想象的那样。如果希望文件名仅为数字,请改用字符串锚点的开头。这样,数字之前就不会出现任何东西。类似地,字符串结束锚点
\z
表示在扩展之后不能出现任何内容

如果然后需要将扩展与HTTP响应的内容类型相匹配(我猜您正在这样做),则可以使用哈希来生成映射:

 my %types = (
      jpg => jpeg,
      gif => gif,
      ...
      );
现在您有了散列,可以将其用作另一个验证级别:

 unless( exists $types{$extension} ) { die "Unsupported type!" }

您需要使用
=~
~而不是
==
=用于正则表达式匹配。在删除冗余代码并进行优化之后,我也会这样写

my $that = "12345678.gif";    
if ($that =~ m/\b[0-9]{8}\.(jpe?g|gif|png)\b/x)
{
    my $ext = $1; 
    if ($ext eq "jpg") {$ext = "jpeg";}
}
else
{
    print "$that is bad";
}

您需要使用
=~
~而不是
==
=用于正则表达式匹配。在删除冗余代码并进行优化之后,我也会这样写

my $that = "12345678.gif";    
if ($that =~ m/\b[0-9]{8}\.(jpe?g|gif|png)\b/x)
{
    my $ext = $1; 
    if ($ext eq "jpg") {$ext = "jpeg";}
}
else
{
    print "$that is bad";
}

这些书面陈述仅供我在这里提问时参考。这些错误将被发送到一个错误子系统。另外,您能说一下您试图施加的文件名限制吗?用散文形式解释你的目标几乎总是比从代码中弄清楚要好。@brian:我的理解是,
\d
的问题是匹配太多(它会得到你不想要的奇数),而不是太少。(见Chas.我一直在听…@brian文件名必须是8位数+图像类型。另一组数字实际上是文件夹名。这是给我的朋友们的图像服务脚本,你在另一个问题上帮助我。我通过路径信息获取目录和图像名称。我还尝试了CGI:Pathinfo,这很不错。你的知识真是惊人,就像这里的其他人一样。你下面接受的答案向我解释了这么多,并解决了我一直在努力解决的其他问题。谢谢你的帮助。@Jim_Bo:谢谢你的澄清。你也可以在原来的问题中添加这些内容,因为