通过两个不同的分隔符将一条线拆分成多个部分

时间:2015-05-04 22:25:29

标签: perl

我有以下结构的行:

STRING1 space STRING2 space FREETEXT

STRING1STRING2都可以是:

  1. "空格*斜线空间*" \s*/\s*分隔的单词,例如word1 / word2 / word3
  2. 一个单词。正则表达式:\w+
  3. FREETEXT是任意字符串... (.*)
  4. 我知道如何匹配:

    * one word such `\w+`
    * two delimited words: `\w+\s*/\s*\w+'
    

    但不知道如何匹配" 1 更多"由\s*/\s*分隔的字词,例如像/(\w+(\s*/\s*)?)/

    这样的东西

    可能更容易理解的定义:

    line: string space string space freetext;
    string: \w+
            ||
            string \s*/\s* \w+
    space: \s+
    freetext: .*
    

    需要获得所有3个部分,例如以下代码

    use 5.014;
    use warnings;
    my $slash_string = qr(\w+|\w+\s*/\s*);                     #<- help1 here
    while(<DATA>) {
        if( m{^($slash_string)+\s+($slash_string)+\s+(.*)$} ) {  #<- help2 here
            say join ' | ', $1, $2, $3;
        }
    }
    __DATA__
    magnam est dolorem ea est
    non / ipsum harum asperiores nesciunt voluptatem
    nunt / harum / dicta nisi minus quo similique unde
    porro inventore / repudiandae dolorem ipsum
    enim  ipsam / aut / numquam illum vero eveniet
    natus / voluptas aut / deserunt et nisi sequi est
    sed / quam / magni ex / assumenda / et eaque cum et modi
    

    应该产生想要的输出

    magnam | est | dolorem ea est
    non / ipsum | harum | asperiores nesciunt voluptatem
    nunt / harum / dicta | nisi | minus quo similique unde
    porro | inventore / repudiandae | dolorem ipsum
    enim | ipsam / aut / numquam | illum vero eveniet
    natus / voluptas | aut / deserunt | et nisi sequi est
    sed / quam / magni | ex / assumenda / et | eaque cum et modi
    

2 个答案:

答案 0 :(得分:4)

这会按照你的要求行事。我已将$slash_string更改为单词,然后是零或多次出现的斜杠,后跟另一个单词。

我还将+量词关闭了($slash_string)+(因为我们只需要一个斜线分隔的单词序列),并添加了/x修饰符,以便通过添加无关紧要的空格,可以使模式更具可读性。

我很确定输出符合您的要求,但我只是通过眼睛检查。

use 5.014;
use warnings;

my $slash_string = qr/ \w+ (?: \s* \/ \s* \w+ )* /x;

while ( <DATA> ) { 
    if ( / ^ ($slash_string) \s+ ($slash_string) \s+ (.*) /x ) {
        say join '  ', map "[$_]", $1, $2, $3;
    }
}

__DATA__
magnam est dolorem ea est
non / ipsum harum asperiores nesciunt voluptatem
nunt / harum / dicta nisi minus quo similique unde
porro inventore / repudiandae dolorem ipsum
enim ipsam / aut / numquam illum vero eveniet
natus / voluptas aut / deserunt et nisi sequi est
sed / quam / magni ex / assumenda / et eaque cum et modi

<强>输出

[magnam]  [est]  [dolorem ea est]
[non / ipsum]  [harum]  [asperiores nesciunt voluptatem]
[nunt / harum / dicta]  [nisi]  [minus quo similique unde]
[porro]  [inventore / repudiandae]  [dolorem ipsum]
[enim]  [ipsam / aut / numquam]  [illum vero eveniet]
[natus / voluptas]  [aut / deserunt]  [et nisi sequi est]
[sed / quam / magni]  [ex / assumenda / et]  [eaque cum et modi]

答案 1 :(得分:3)

如果/周围的空格数不重要,问题可以减少到split at spaces。逻辑:

  • 仅使用\s*/\s*替换所有/ - 例如从word1 / word2 / word3您将获得word1/word2/word3
  • 将空格中的字符串分为3部分
  • 将每个/替换为/

while(<DATA>) {
    chomp;
    s!\s*/\s*!/!g;   #remove all spaces around the /
    my @parts = split /\s+/, $_, 3;
    say join ' | ', map {s!/! / !gr} @parts; #return the spaces
}

输出

magnam | est | dolorem ea est
non / ipsum | harum | asperiores nesciunt voluptatem
nunt / harum / dicta | nisi | minus quo similique unde
porro | inventore / repudiandae | dolorem ipsum
enim | ipsam / aut / numquam | illum vero eveniet
natus / voluptas | aut / deserunt | et nisi sequi est
sed / quam / magni | ex / assumenda / et | eaque cum et modi