【问题标题】:Perl: Matching a file with a format given by another filePerl:将文件与另一个文件给定的格式匹配
【发布时间】:2012-03-18 16:54:28
【问题描述】:

假设我有 2 个格式如下的文件。

文件1:

username <username>
password <password1>
password <password2>
hello world

文件2:

username hello
password test
password testing
hello world
good luck

我希望能够检查 File2 是否遵循与 File1 相同的格式。这意味着如果一个文件具有以下格式,将无法通过我的测试。

坏文件:

username hello
password test
hello world

必须有 2 行以“密码”开头。目前,我的程序能够检查是否有以“用户名”和“密码”开头的行。我似乎无法检查 File1 是否具有与“密码”相同的起始词的重复行,它还应该检查 File2 是否应具有相同数量的具有相同起始词的行. IE。当我运行 File1 和 BadFile 时,我的程序会生成一个 pass 来测试 BadFile 是否遵循 File1 的格式。

我不需要在关键字之后存储东西(即“hello”、“test”、“testing”在这种情况下),但我应该能够区分有 2 行以“password”开头我去检查。

还有一些行没有“<...>”。基本上,File1 中的任何内容都必须在 FileN 中找到,FileN 才能通过。

知道我应该使用什么数据结构来实现这一目标吗?我正在考虑数组的散列,但对于我和这种情况来说它似乎太复杂了。

【问题讨论】:

    标签: arrays string perl file hash


    【解决方案1】:
    my $template_qfn = ...;
    my $file_qfn     = ...;
    
    my $template = do {
       open(my $fh, '<', $template_qfn) or die $!;
       local $/;
       <$fh>
    };
    
    my $template_pat = quotemeta($template);
    $template_pat =~ s/\\<[^<>\n]*\\>/[^\n]+/g;
    my $template_re = qr/^$template_pat\z/;
    
    my $file = do {
       open(my $fh, '<', $file_qfn) or die $!;
       local $/;
       <$fh>
    };
    
    die("File \"$file_qfn\" doesn't match template \"$template_qfn\"\n")
       if $file !~ $template_re;
    

    【讨论】:

    • 我没有“<...>”的“hello world”这样的情况呢?
    • 它已经检查过了,就像你问的那样。
    • 但是,如果 File2 中有额外的一行(在本例中为“good lucky”),测试应该仍然通过并且不会失败。这是因为必须在 FileN 中找到 File1 中的任何内容,以便 FileN 传递。但并非 FileN 中的所有东西都必须在 File1 中找到。如果 File1 和 FileN 的顺序不同怎么办?
    • @Sakura,这与您的规范直接矛盾。 (“必须在 FileN 中找到 File1 中的任何内容,以便 FileN 通过。”和“它还应该检查 File2 是否应该具有相同数量的行数和相同的起始词。”)如果您希望我们忽略有些行,你需要说出你想忽略哪些行。
    【解决方案2】:

    这是一段可能对您有所帮助的代码(通过打开文件替换 DATA):

    use strict;
    my @tokens = qw/username password password/;
    my $current = 0;
    my $line_number = 1;
    
    while( my $line = <DATA> ) {
        my $expected = $tokens[$current];
        if( $line !~ m!^$expected ! ) {
            die "Invalid format: expected '$expected' at data file line number: $line_number; line: $line"
        }
        $current = ++$current % scalar(@tokens);
        $line_number++;
    }
    
    die "Invalid format; sequence incomplete" if $current != 0;
    print "Ok!\n";
    
    __DATA__
    username hello
    password test
    password testing
    

    【讨论】:

    • 我没有“<...>”的“hello world”这样的情况呢?
    猜你喜欢
    • 2015-08-07
    • 2011-06-03
    • 1970-01-01
    • 2019-11-19
    • 2013-03-27
    • 2013-06-17
    • 1970-01-01
    • 2013-05-29
    • 2013-08-29
    相关资源
    最近更新 更多