Как я могу сделать этот REGEX чище? - PullRequest
0 голосов
/ 12 января 2011

У меня есть это регулярное выражение, которое я сделал для сравнения имен ОС со строкой в ​​файле 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 ]

8 голосов
/ 13 января 2011

Вы можете использовать модификатор /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

Когда вы смотрите на это так, улучшения, предложенные Робокопом и Константином Гредескулом, становятся очевидными:

$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
5 голосов
/ 13 января 2011

Возможно, вы вообще не захотите регулярное выражение из соображений эффективности и ясности. Один из вариантов - захватить строку за пределами блока 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};
4 голосов
/ 12 января 2011

Вы можете начать делать что-то с соответствием Microsoft Windows, а затем остальные, как:

Microsoft\sWindows\s(Server\s2003,Web\sEdition|Small\SBussines...)
2 голосов
/ 13 января 2011

Вы можете использовать интерполяцию в шаблоне, чтобы сделать его более читабельным:

my $names = join '|', @names;
if ($vmx_file =~ m/guestOSAltName\s+=\s(?:$names)) {
    $virtual_machines{$vm}{Architecture} = "32-bit";
}
1 голос
/ 13 января 2011

Вы можете использовать круглые скобки для группировки похожих элементов в регулярном выражении, чтобы вам не приходилось повторять «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)"/

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...