开发者

Why does this regex only half work?

I am trying to use a regex to match another line in a VMX file but it only "half" works. I will explain.

The line I am trying to match for example is scsi0:0.fileName = "Test01.vmdk. My regex seems to work fine for that. Now the curveball, if I try to use the same regex to look for scsi0:1.fileName = "Test01_1.vmdk. My regex does not find it and only display the first disk it found for each VM. I know I am missing something I just can't put my finger on it. The only thing that is odd but I don't think makes any difference is the line for the second disk scsi0:1.fileName = "Test01_1.vmdk is located at the bottom of the file and the line for scsi0:0.fileName = "Test01.vmdk is at the middle of the file with more lines for other option after it. Is the regex stopping too soon? Is that even possible?

Anyhow here is the code block I am working on.

    foreach my $vm (@virtual_machines) {
    my $vmx_file = $ssh1->capture("cat $v开发者_Python百科irtual_machines{$vm}{VMX}");
    my $inc = -1;
    if ($vmx_file =~ m/scsi([0-3]):([0-9]|1[0-5])\.fileName\s+=\s+"(?<DISK>\w+?\.vmdk)"/xm) {
        ++$inc;
        $virtual_disks{$vm}{"Disk$inc"} = "$+{DISK}";
    }

This is odd, but if I explicitly plug in the numbers of the SCSI id I am looking for it work. For some reason it is not able to find it on its own. I updated my example too.


If you want to find all matches in a string, change the if to a while and add the g modifier for global matching. @mob is also right that you should use non-greedy matching.

The character group [0-15] is equivalent to [015]: if you want to match 0-15, then you should change this to (?:[0-9]|1[0-5]). You don't need to escape the :. And I assume you left out the closing " in your strings by mistake when typing the question.

Works on rubular.


I suppose this may be the culprit

[0-15]

this means the following digits: 0, 1, 5. Whereas you probably meant

([0-9]|1[0-5])

i.e. all numbers in the range [0 15]


I'd be concerned that "(?<DISK>.+)" section of the regex is too greedy and captures everything up to the last quotation mark in the (multi-line?) input rather than the next quotation mark.

I'd try something like

"(?<DISK>[^"]+)"

which is to say, match one or more chars that are not quotation marks.


Some things you could try:
/scsi[0-3] : (?:[0-9]|1[0-5]) \. fileName \s*=\s* "(?<DISK>.+?)"/xs

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜