我对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]
答案 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;}
}