如何使这款REGEX清洁?

时间:2011-01-12 20:51:41

标签: regex perl

我有这个正则表达式,我将OS名称与VMX文件中的一行进行比较。它最初是单独的elsif声明,但我最终制作了一个if声明。无论如何,这是代码;我试图找到一种方法来使代码更清洁,但它将每个匹配放在一个单独的行上;它不再有效。

elsif ($vmx_file =~ m/guestOSAltName\s+=\s"Microsoft\sWindows\sServer\s2003,Web\sEdition"|"Microsoft\sWindows\sSmall\sBusiness\sServer\s2003"|"Microsoft\sWindows\s2000\sAdvanced\sServer"|"Microsoft\sWindows\s2000\sServer"|"Microsoft\sWindows\s2000\sProfessional"|"Microsoft\sWindows\s98"|"Microsoft\sWindows\s95"|"Microsoft\sWindows\sNT\s4"/) {
            $virtual_machines{$vm}{"Architecture"} = "32-bit";

根据建议更新了代码,

elsif ($vmx_file =~ m/guestOSAltName\s+=\s"Microsoft\sWindows\sServer\s2003,Web\sEdition|Small\sBusiness\sServer\s2003|"2000\sAdvanced\sServer|2000\sServer|2000\sProfessional|98|95|NT\s4/) {
            $virtual_machines{$vm}{"Architecture"} = "32-bit";

5 个答案:

答案 0 :(得分:8)

你可以使用/x修饰符让你的正则表达式更漂亮,如果不是更干净的话。

$vmx_file =~ m/guestOSAltName\s+=
    \s("Microsoft\sWindows\sServer\s2003,Web\sEdition"
     | "Microsoft\sWindows\sSmall\sBusiness\sServer\s2003"
     | "Microsoft\sWindows\s2000\sAdvanced\sServer"
     | "Microsoft\sWindows\s2000\sServer"
     | "Microsoft\sWindows\s2000\sProfessional"
     | "Microsoft\sWindows\s98"
     | "Microsoft\sWindows\s95"
     | "Microsoft\sWindows\sNT\s4")/x

当你这样看时,Robokop和Konstantin Gredeskoul建议的改进成为了  显而易见的:

$vmx_file =~ m/guestOSAltName\s+=
    \s"Microsoft\sWindows\s
     (     Server\s2003,Web\sEdition
         | Small\sBusiness\sServer\s2003
         | 2000\s( (Advanced\s)?Server | Professional )
         | 9[85]
         | NT\s4
     )
       "/x

答案 1 :(得分:5)

出于效率和清晰度原因,您可能根本不需要正则表达式。一种选择是捕获if块之外的字符串并通过散列键进行匹配:

#this could be offloaded to a constants file or some such
%architecture_by_os = (
    "Microsoft Windows Server 2003,Web Edition" => "32-bit",
    "Microsoft Windows Small Business Server 2003" => "32-bit",
    #etc.
)

$vmx_file =~ m/guestOSAltName\s+=\s(.*)/;
$virtual_machine{$vm}{Architecture} = $architecture_by_os{$1};

答案 2 :(得分:4)

您可以先使用Microsoft Windows匹配,然后完成其他操作,例如:

Microsoft\sWindows\s(Server\s2003,Web\sEdition|Small\SBussines...)

答案 3 :(得分:2)

您可以在模式中使用插值使其更具可读性:

my $names = join '|', @names;
if ($vmx_file =~ m/guestOSAltName\s+=\s(?:$names)) {
    $virtual_machines{$vm}{Architecture} = "32-bit";
}

答案 4 :(得分:1)

您可以使用括号对正则表达式中的类似项目进行分组,这样您就不必每次都重复“Microsoft \ sWindows”。你还应该使用?指示可选或可能缺少的项目,例如(\ sWeb \ sEdition)?。

(换行符是为了清晰起见)

m/guestOSAltName\s+=\s"Microsoft\sWindows\s?(Server\s2003(\sWeb\sEdition)?|
Small\sBusiness\sServer\s2003|
2000\sAdvanced\sServer|
2000\sServer|
2000\sProfessional
98|
NT\s4)"/

希望这有帮助。