【问题标题】:Regex expression to split a line to three segments in Perl正则表达式在 Perl 中将一行拆分为三个段
【发布时间】:2010-07-20 08:48:34
【问题描述】:

我正在解析一个文本文件,并得到如下所示形式的多行。

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

但是现在我在如何编写正则表达式时遇到了困难。我考虑过在空格上拆分并使用数组连接新字符串:

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;等等

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

$direction = S,H->E,reply; // 有时是M,H<-E,replyS,H<->ES,H->E,[reply] 等。part3 的每个子项之间没有空格:$direction

【问题讨论】:

  • 给定行的格式始终保持不变:S15,F49 大型配方下载请求 (LRDR) S,H->E,回复就像第一部分将包含逗号 (,) 或第二部分将包含圆括号()总是?
  • @Nikhil。是的,我只是想将这一行分成三段,并根据输出生成一个 XML 文件。

标签: regex perl concatenation


【解决方案1】:

如果$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+):与上面类似 - 匹配空格分隔符和非空格字符 --> $3.

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


*懒惰量词*?的原因是,否则,这部分正则表达式还将捕获除最后一个之外的所有以下空格分隔符。

【讨论】:

  • 起初我很好奇这是否可行,因为第二组的非贪婪。但由于最后一组需要至少一个字符,所以效果很好。如果第二组是贪婪的,我认为它可能会稍微快一点,因为它应该不那么频繁地回溯,但我不是 100% 肯定。当然这将是一个微优化,但我们不知道这段代码被调用的频率。
  • 我认为这不会对性能产生太大影响。但是,匹配结果会有所不同,具体取决于我使用的是惰性量词还是贪婪量词(请参阅底部的编辑)。
【解决方案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";

【讨论】:

    【解决方案3】:

    根据您的显示,这应该可以:

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

    由两个或多个空格分隔。

    这将自动咀嚼:

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

    【讨论】:

    • 我未能使用您的拆分方法实现。请查看链接了解更多详情。 codepad.org/8n5b8pAd 在我的笔记本电脑上显示警告(使用 ActivePerl 5.10):在 D:\learning\perl\nextLine.pl 第 24 行, 第 3 行的连接 (.) 或字符串中使用未初始化的值 $direction。方向 =
    • 在粘贴站点上,您只有一个选项卡。在名称和方向之间。所以我将正则表达式更改为阅读/\s{2,}|\t|\n/ 并得到我需要的东西。在您的示例中,您有 3 个空格。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-15
    • 2012-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-11
    • 2018-05-31
    相关资源
    最近更新 更多