【问题标题】:Splitting a line into parts by two different delimiter用两个不同的分隔符将一条线分成几部分
【发布时间】:2015-05-05 08:02:50
【问题描述】:

我有以下结构的行:

STRING1 space STRING2 space FREETEXT

STRING1STRING2 都可能是:

  1. "space* slash space*" \s*/\s* 分隔的单词,例如word1 / word2 / word3
  2. 一个单字。正则表达式:\w+
  3. FREETEXT 是任何字符串...(.*)

我知道如何匹配:

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

但不知道如何匹配由\s*/\s* 分隔的“1 个更多”字,例如类似/(\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

【问题讨论】:

    标签: perl


    【解决方案1】:

    这将按照您的要求进行。我已将 $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]
    

    【讨论】:

    • 是的!这正是我所期待的。格式精美的输出。谢谢。
    【解决方案2】:

    如果/ 周围的空格数无关紧要,问题可以简化为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
    

    【讨论】:

    • 也可以,但我更喜欢正则表达式解决方案。谢谢。
    猜你喜欢
    • 2021-12-15
    • 2016-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-12
    • 1970-01-01
    • 2017-07-17
    相关资源
    最近更新 更多