perl regex - 多模式匹配,可选匹配

时间:2010-12-11 01:26:30

标签: regex perl pattern-matching

我坚持这个正则表达式。它匹配我的3个文件名中的2个。如果可能,需要帮助获得所有三个。 我还想在扩展名abc|def|ghi之前将这些值之一ucsb|tech以及.edu | .net区域设置名称提取到变量中。

如果可能的话,我想一次性完成这项工作。感谢。

/home/test/abc/.last_run_dir
/home/test/def/.last_file_sent.mail@wolverine.ucsb.edu
/home/test/ghi/.last_file_sent.dp3.tech.net

它没有拿到第一行:

/home/test/abc/.last_run_dir

正则表达式:

$line =~ m#home/test/(\w{3}).*[.](\w+)[.].*#

代码:

my $file = 'Index.lst';
open my $FILE, '<', $file or die "unable to open '$file' for reading: $!";
while (my $line = <$FILE>) {
    chomp($line);
    if ($line =~ m#home/test/(\w{3}).*[.](\w+)[.].*#) {
        open my $file2, '<', $line or die "unable to open '$file' for reading: $!";
        while(my $line2 = <$file2>) {
        print "$line2";
        }
        close $file2;
    }
} #end while
close $FILE;

另外,如何打印出我可能的比赛?如果它们是可选的?

3 个答案:

答案 0 :(得分:4)

您可以执行以下操作:

#!/usr/bin/perl
use strict;
use warnings;

while(my $line=<DATA>) {
    chomp($line);
    if ($line =~ m#home/test/(\w{3})/\.(\w+)(?:.*\.(\w+)\.[^.]+)?|$#) {
        print "$line\n";
        print "1=$1\t2=$2\t3=$3\n";
    }
}

__DATA__
/home/test/abc/.last_run_dir
/home/test/def/.last_file_sent.mail@wolverine.ucsb.edu
/home/test/ghi/.last_file_sent.dp3.tech.net

输出:

/home/test/abc/.last_run_dir
1=abc   2=last_run_dir  3=
/home/test/def/.last_file_sent.mail@wolverine.ucsb.edu
1=def   2=last_file_sent    3=ucsb
/home/test/ghi/.last_file_sent.dp3.tech.net
1=ghi   2=last_file_sent    3=tech

答案 1 :(得分:3)

w {3} 之后你的正则表达式部分强制寻找下一个点字点:

[.](\w+)[.].*

一个简单的解决方法是使其成为可选项。但是当你这样做时,你可能需要先锁定它。*:指定它可以是任何字符串,但不是一个句点。 (一般来说,这是一个很好的做法,顺便说一句。)

$line =~ m#home/test/(\w{3})[^.]*([.](\w+)[.].*)?#
编辑:我看到我的解决方案可能需要一些测试来检查正确位置的时段,fyi。

答案 2 :(得分:-1)

你的正则表达式需要两个“。”实例。匹配。如果第二个是可选的,请使用[。]?

$line =~ m#home/test/(\w{3}).*[.](\w+)[.]?.*#;
相关问题