2011-01-12 18 views
0

Ich habe diese Regex gemacht, um OS-Namen zu einer Zeile in einer VMX-Datei zu vergleichen. Es begann als separate elsif Statements, aber ich landete in einer einzigen if Statment. Wie auch immer, hier ist der Code; Ich versuche, einen Weg zu finden, den Code sauberer zu machen, aber er setzt jedes Match in eine separate Zeile; es funktioniert nicht mehr.Wie kann ich diesen REGEX sauberer machen?

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"; 

aktualisiert Code per Anregungen,

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"; 

Antwort

8

Sie können den /x Modifikator verwenden, um Ihren regex schönere, wenn nicht tatsächlich sauberer zu machen.

$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 

Wenn man es so aussehen, die Verbesserungen robokop und Konstantin Gredeskoul vorschlug werden offensichtlich:

$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 
+0

Wow, dass Regex-Ausdruck jetzt TINY ist. – ianc1215

+0

Funktioniert perfekt, ich gebe Ihnen die "Antwort". – ianc1215

4

Sie, indem Sie etwas mit dem Microsoft Windows-Matching der Rest wie und dann starten:

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

Tolle Idee! Ich werde damit beginnen. – ianc1215

1

Sie können Gruppe verwenden Klammer ähnliche Elemente in einer Regex, so dass Sie nicht jedes Mal "Microsoft \ sWindows" wiederholen müssen. Sie sollten auch verwenden? um ein optionales oder möglicherweise fehlendes Element wie (\ sWeb \ sEdition) anzuzeigen.

(Zeilenumbrüche sind für Klarheit)

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)"/ 

Hoffnung, das hilft.

+0

Ich habe versucht, Zeilenumbrüche wie diese und es konnte nicht das Muster auf allen von ihnen übereinstimmen. Nicht sicher warum. – ianc1215

+0

Es hat nicht funktioniert, weil ich nicht das "()" hatte, das den Teil des Ausdrucks umgibt. – ianc1215

+0

Ich mag auch Eugene die Antwort, die eine Reihe von Namen verwendet, um zu entsprechen. –

2

Sie können Interpolation im Muster verwenden, um sie besser lesbar zu machen:

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

Sie werden vielleicht nicht eine Regex wollen überhaupt, sowie aus Gründen der Klarheit für die Effizienz. Eine Option wäre, die Zeichenkette außerhalb des if-Blocks zu erfassen und mit Hash-Schlüsseln abzugleichen:

#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}; 
+0

Wow, das ist eine wirklich gute Idee, hätte nie daran gedacht. – ianc1215

Verwandte Themen