2014-07-08 54 views
0

我想寫一個方法來提取Perl中前兩部分的windows路徑。Perl正則表達式提取windows路徑的前兩部分

例如, 'd:\ git_root_tfs \工作站\項目\相互作用\工具\服務器的規則檢查工具'

提取物爲: 'd:\ git_root_tfs \工作站'

sub Split_Location_as_VMPath { 
    my $location = shift; 
    # ^([d-z]:\\.+?\\.+?)\\ 
    # ^(?:\\.*\\.*)\\ 
    if($location ~~ m/^(?:\\.*\\.*)\\/){ # the path drive start from D to E; 
     # print "VMPath=$1\n";   
     # push @$vmPathList, $1; 
     return Convert_to_Lowercase($1); 
    } 
    return "Invalid Path $location"; 
} 

如何編寫正則表達式?

測試用例:

{ 
    my $item = Split_Location_as_VMPath('D:\VM\ia7-BGCDev8.1\test.vhd'); 
    my $expected = Convert_to_Lowercase('D:\VM\ia7-BGCDev8.1'); 
    ok($item eq $expected, "Test Split_Location_as_VMPath=$item"); 

    $item = Split_Location_as_VMPath('E:\Hyper-V-2\ia-int-7.1Beta\test.vhd'); 
    $expected = Convert_to_Lowercase('E:\Hyper-V-2\ia-int-7.1Beta'); 
    ok($item eq $expected, "Test Split_Location_as_VMPath=$item"); 

    $item = Split_Location_as_VMPath('D:\VM\ia7-int-7.1\test.vhd'); 
    $expected = Convert_to_Lowercase('D:\VM\ia7-int-7.1'); 
    ok($item eq $expected, "Test Split_Location_as_VMPath=$item"); 

    $item = Split_Location_as_VMPath('D:\VM\ia7-int-8.1B153\test.vhd'); 
    $expected = Convert_to_Lowercase('D:\VM\ia7-int-8.1B153'); 
    ok($item eq $expected, "Test Split_Location_as_VMPath=$item"); 

    $item = Split_Location_as_VMPath('D:\Hyper-v\IA5-SDE-WIN2K3(Feng Tong)\test.vhd'); 
    $expected = Convert_to_Lowercase('D:\Hyper-v\IA5-SDE-WIN2K3(Feng Tong)'); 
    ok($item eq $expected, "Test Split_Location_as_VMPath=$item"); 

    $item = Split_Location_as_VMPath('D:\git_root_tfs\WorkStation\Projects\InterACT\Tools\server-rule-checker'); 
    $expected = Convert_to_Lowercase('D:\git_root_tfs\WorkStation'); 
    ok($item eq $expected, "Test Split_Location_as_VMPath=$item"); 
} 

回答

0

正確正則表達式是^([d-Z]:\ + \ +??)\。

sub Split_Location_as_VMPath { 
    my $location = shift; 
    # ^([d-z]:\\.+?\\.+?)\\ 
    # ^(?:\\.*\\.*)\\ 
    if($location ~~ m/^([D-Z]:\\.+?\\.+?)\\/){ # the path drive start from D to E; 
     # print "VMPath=$1\n";   
     # push @$vmPathList, $1; 
     return Convert_to_Lowercase($1); 
    } 
    return "Invalid Path $location"; 
} 
1

不要使用正則表達式進行文件處理。

改爲使用像File::SpecPath::Tiny這樣的模塊。

use strict; 
use warnings; 

use File::Spec; 

while (<DATA>) { 
    my ($vol, $dir, $file) = File::Spec->splitpath($_); 
    my @dirs = File::Spec->splitdir($dir); 
    @dirs = @dirs[0..2] if @dirs > 3; 
    $dir = File::Spec->catdir(@dirs); 
    my $path = File::Spec->catpath($vol, $dir); 

    print "$path\n"; 
} 

__DATA__ 
D:\VM\ia7-BGCDev8.1\test.vhd 
E:\Hyper-V-2\ia-int-7.1Beta\test.vhd 
D:\VM\ia7-int-7.1\test.vhd 
D:\VM\ia7-int-8.1B153\test.vhd 
D:\Hyper-v\IA5-SDE-WIN2K3(Feng Tong)\test.vhd 
D:\git_root_tfs\WorkStation\Projects\InterACT\Tools\server-rule-checker 

輸出:

D:\VM\ia7-BGCDev8.1 
E:\Hyper-V-2\ia-int-7.1Beta 
D:\VM\ia7-int-7.1 
D:\VM\ia7-int-8.1B153 
D:\Hyper-v\IA5-SDE-WIN2K3(Feng Tong) 
D:\git_root_tfs\WorkStation 
0

在這種情況下使用正則表達式是學生一個有趣的功課。在校外,您應該使用專門用於此任務的標準模塊:

use File::Spec; 
sub Split_Location_as_VMPath { 
    my $location = shift; 
    my ($volume, $directories, $file) = File::Spec->splitpath($location); 
    my @dirs = File::Spec->splitdir($directories); 
    return "Invalid Path $location" unless @dirs > 2; 
    return lc File::Spec->catpath($volume, File::Spec->catdir(@dirs[0..2]));  
}