2010-07-20 62 views
1

我正在解析一个文本文件,并在下面显示的窗体中获得多行。正则表达式在Perl中将一行分割为三段

然后我尝试将每一行分成三段:Part1:sf;第二部分:名称;第三部分:方向。

但现在我遇到了如何写出正则表达式的困难。我曾经想过在空格分割和使用阵列来连接新的字符串:

S15,F49 Large Recipe Download Request (LRDR) S,H->E,reply 

my ($sf, $name, $direction) =~/I don't know how to implement here/ 

我怎样才能获得$ SF = S15,F49 //其他线路一样S1,F11; S6,F1; etc

$ name = Large Recipe Download Request (LRDR) //不同的$ sf的不同名称。

$方向= S,H->E,reply; //一些时间,它是M,H<-E,replyS,H<->ES,H->E,[reply]等没有为3部分的每个子项之间没有空格:$方向

+0

给定行的格式始终保持不变: S15,F49大型配方下载请求(LRDR)S,H-> E,回复 像第一部分将包含逗号(,)或第二部分将包含圆括号()总是? – 2010-07-20 09:10:46

+0

@Nikhil。是的,我只是想将这一行分成三段,并根据输出生成一个XML文件。 – 2010-07-21 01:02:13

回答

4

如果在$sf内没有空白和在$direction项目,那么你可以在下面的代码适用于每一行:

if ($subject =~ m/^(\S+)\s+(.*?)\s+(\S+)$/) { 
    $sf = $1; 
    $name = $2; 
    $direction = $3; 
} else { 
    // no match found 
} 

说明:

^:在字符串的开始处锚定正则表达式。

(\S+):匹配一个或多个非空格字符。捕获$1中的匹配。

\s+:匹配一个或多个空格字符(=分隔符到下一个项目)。 。

(.*?):匹配任何数目的字符,尽可能少仍然允许整体匹配成功,并捕获在$2 *

\s+(\S+):与上面类似 - 匹配空格分隔符(S)和非空格字符 - >$3

$:将搜索锚定在字符串末尾。


*的原因懒惰量词*?是,否则,正则表达式,这部分也将捕获所有除了最后一个下面的空间分隔。

+1

起初我很好奇这是否会因为第二组的非贪心而起作用。但是由于最后一组需要至少一个字符,所以它工作正常。如果第二组是贪婪的,我认为它可能稍微快一点点,因为它应该不太频繁地回溯,但我不是100%确定的。当然,这将是一个微型优化,但我们不知道这个代码被调用的频率。 – musiKk 2010-07-20 09:16:36

+0

我不认为这会对性能产生很大的影响。但是,匹配结果会有所不同,具体取决于我是使用懒惰还是贪婪量词(请参阅底部的编辑)。 – 2010-07-20 09:23:36

+0

它工作得很好。 – 2010-07-20 09:25:11

2
my $str = "S15,F49 Large Recipe Download Request (LRDR) S,H->E,reply"; 

$str =~ /^([^\s]+) # sf: anything except whitespace until first whitespace 
      \s+ 
      (.+)  # name: anything 
      \s+ 
      ([^\s]+)$ # direction: anything except whitespace, from last 
        # whitespace to the end 
     /x; 
my ($sf, $name, $direction) = ($1, $2, $3); 
print $sf, "\n", $name, "\n", $direction, "\n"; 
1

从大家展示一下,这应该工作:通过以上两个或多个空格

my ($sf, $name, $direction) = split /\s{2,}/, $line; 

拆分。

这将自动格格:

my ($sf, $name, $direction) = split /\s{2,}|\n/, $line; 
+0

我未能用您的拆分方法实施。 请参阅链接了解更多详情。 http://codepad.org/8n5b8pAd 我的笔记本电脑 显示警告(使用的activeperl 5.10):(。)的串联或串在d未初始化值$方向的使用:\学习\ Perl的\ nextLine.pl线24 ,第3行。 direction = – 2010-07-21 01:15:40

+0

在粘贴网站上,您有一个选项卡。名称和方向之间。所以我会改变正则表达式来读取'/ \ s {2,} | \ t | \ n /'并且得到我需要的。在你的例子中,你有3个空格。 – Axeman 2010-07-21 02:45:37