正则表达式匹配整个.csv文件

时间:2016-06-24 09:10:08

标签: regex perl csv

早上好!

我正在努力解决问题,我从没想过会是一个问题。我有一个带有分隔符; .csv 文件,我想检查一下它的语法。它看起来像这样:

wellenname;tag
Welle A;01/02/2016
Welle B3;14/11/2016
server;welle
server5name032;Welle B3 Rand
server3name01;Welle A
server2name;Welle B3

所以我有一个漂亮的格式化 .csv 文件,我可以使用正则表达式进行处理。因此我为正则表达式构造了四个案例:

  1. wellenname;标签\ n
  2. (Welle [A-Z] + [0-9] *; \ d {2} / \ d {2} / \ d {4} \ n)+
  3. 服务器;韦勒\ n
  4. (\ S *; Welle [a-z,A-Z,0-9] +(Rand)(\ n))+
  5. 这个名为 The Regex Coach 的工具非常漂亮,它基本上试图匹配正则表达式和字符串并输出它所处的位置。

    然后我把它放在Perl中。读取文件并检查语法:

    use strict;
    use warnings;
    use Data::Dumper;
    my $filename = 'theFile.csv';
    
    my $content;
    
    open(my $fh, '<', $filename) or die "Could not open file $filename $!";
    $content = join('',<$fh>);
    
    if ($content =~ /wellenname;tag\n(Welle [A-Z]+[0-9]*;\d{2}\/\d{2}\/\d{4}\n)+server;welle\n(\S*;Welle [a-z,A-Z,0-9]+( Rand)*(\n)*)+/) { 
      print "Syntax seems to be valid!";
    
    }else{
      print "You have syntax errors!";
    }
    

    我逐行浏览了文件,但即使每个部分只插入一个条目也失败了。 (或更好:它跳转到 else 并打印字符串)

    我忘记了吗?或者我的思想中是否存在市长错误? 如果有人能给我一个提示,我会很高兴的!

1 个答案:

答案 0 :(得分:2)

嗯,这实际上有效:

use strict;
use warnings;
use Data::Dumper;

my $content = join('',<DATA>);

if ($content =~ /wellenname;tag\n(Welle [A-Z]+[0-9]*;\d{2}\/\d{2}\/\d{4}\n)+server;welle\n(\S*;Welle [a-z,A-Z,0-9]+( Rand)*(\n)*)+/) {
  print "Syntax seems to be valid!";
} else {
  print "You have syntax errors!";
}

__DATA__
wellenname;tag
Welle A;01/02/2016
Welle B3;14/11/2016
server;welle
server5name032;Welle B3 Rand
server3name01;Welle A
server2name;Welle B3

您的文件可能存在问题。当它是Windows生成的文件时,您可能需要搜索 \ r \ n 而不是 \ n

但你的正则表达式仍然不完美。

首先,分别在正则表达式的开头和结尾处错过^$。现在它可以将CSV与实际CSV之前和之后的额外符号相匹配。其次,[]中不需要逗号,因此[a-z,A-Z,0-9]应为[a-zA-Z0-9](或者它与,以及您指定的其他符号相匹配)。此外,您应该考虑使用/x开关(以使您的正则表达式更具可读性)并使用m{...}而不是/.../来避免在正则表达式中转义/

所以,我的最终版本是:

use strict;
use warnings;

my $content = join('',<DATA>);

if (
    $content =~ m{
        ^
        wellenname;tag\n
        (Welle[ ][A-Z]+[0-9]*;\d{2}/\d{2}/\d{4}\n)+
        server;welle\n
        (\S*;Welle[ ][a-z,A-Z,0-9]+([ ]Rand)*(\n)*)+
        $
    }x
) {
  print 'Syntax seems to be valid!';
}
else {
  print 'You have syntax errors!';
}

__DATA__
wellenname;tag
Welle A;01/02/2016
Welle B3;14/11/2016
server;welle
server5name032;Welle B3 Rand
server3name01;Welle A
server2name;Welle B3

请注意,我在使用[ ]时使用/x来匹配空格。我还使用'...'代替"...",因为我们不需要在该字符串中启用插值。