从具有相同模式的多行中获取一些变量时出错

时间:2017-06-08 07:04:29

标签: regex perl

我对perl真的很陌生。我需要使用perl脚本从具有相同模式的多行中获取一些变量。

这些是具有相同模式的多行的示例,并存储在input.txt中:

input -input_port -port top_port 21.303 [open_port -op {input_port[0]} -file "file_name == top_input_port[0]"]
input -input_port -port bot_port 98.324 [open_port -op {input_port[10]} -file "file_name == bot_input_port[10]"]

该行的格式为:

input -input_port -port portname value [open_port -op {input_port[10]} -file "file_name == filename"]

所以,我尝试使用Google中的示例创建此脚本:

#! /tools/perl/5.8.8/linux/bin/perl
use strict;
use warnings;

while (<>) {
    if ($_ =~ /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\d+)\s+
              \[(\S+)\s+(\S+)\s
              \{(\S+)\[(\d+)\]\}\s(\S+)\s(\S+)\s*==\s(\S+)*"\]$/x ) {
        $io = $1;
        $io_port = $2;
        $port = $3;
        $portname = $4;
        $value = $5;
        $openclose = $6;
        $op = $7;
        $io_num = $8;
        $number = $9;
        $filetype = $10;
        $file = $11;
        $file_name = $12;
        print "$io $portname $value $file_name\n";
    }
}

我只想打印$ io,$ portname,$ value和$ file_name。但是,它显示编译错误。我该如何解决这个错误?

我希望输出在新的txt文件中:

输入top_port 21.303 top_input_port [0]

输入bot_port 98.324 bot_input_port [10]

1 个答案:

答案 0 :(得分:2)

老实说,正则表达式太复杂了。你正在做一些匹配,而且很脆弱。

21.303 \d+很可能与#!/usr/bin/env perl use strict; use warnings; while ( <DATA> ) { my ( $io ) = m/^(\w+)/; #first word on line my ( $portname, $value ) = m/-port (\w+) ([\d\.]+)/; #look for 'port' keyword. my ( $file_name ) = m/file_name == (\S+)\"/; #look for 'file_name' keyword print "$io $portname $value $file_name\n"; } __DATA__ input -input_port -port top_port 21.303 [open_port -op {input_port[0]} -file "file_name == top_input_port[0]"] input -input_port -port bot_port 98.324 [open_port -op {input_port[10]} -file "file_name == bot_input_port[10]"] 匹配。

所以你的正则表达式打破了,那就是那个......

但我可以建议一种不同的方法吗?不要整个事情,这意味着复杂和难以阅读 - 和脆弱 - 正则表达。

为什么不改为:

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        var p = new MyPerson();
        p.Name = "test";
        p.AddPhonenumber("555-2356");
        Console.WriteLine(string.Join(", ", p.Phonenumber));

        var c = new MyContact();
        c.Name = "contact";
        c.AddPhonenumber("222-235");
        Console.WriteLine(string.Join(", ", c.Phonenumber));
    }
}


public class Contact
{
    public Contact() {
        this.Phonenumber = new List<string>();
    }
    public string Name { get; set; }
    public List<string> Phonenumber { get; set; }
    public string Foo { get; set; }
}
public class Person
{
    public Person() {
        this.Phonenumber = new List<string>();
    }
    public string Name { get; set; }
    public List<string> Phonenumber { get; set; }
    public string Bar { get; set; }
}

public class MyContact: Contact, IType {
}

public class MyPerson: Person, IType {
}


public static class Extensions {
    public static void AddPhonenumber(this IType type, string number){
        type.Phonenumber.Add(number);
    }
}

public interface IType {
    string Name {get; set; }
    List<string> Phonenumber {get; set;}
}