【问题标题】:Using Look-ahead and Look-behind (perl)使用前瞻和后瞻 (perl)
【发布时间】:2011-09-12 23:40:54
【问题描述】:

我想用 perl 代码分割这种类型的行:

my $my_town = Madrid(32): Villa de Madrid (ES) Royal Palace of Madrid (Teatro Real)

到:

Madrid(32):
Villa de Madrid (ES)
Royal Palace of Madrid (Teatro Real)

我试过了:

my @travel = split(/(?<=\))\s*/, $my_town);

但输出结果是:

Madrid(32)
: Villa de Madrid (ES)
Royal Palace of Madrid (Teatro Real)

请给我一点帮助。

有没有什么方法可以让函数“)”返回所有找到更少的第一个字符? ": Villa de Madrid (ES)" 没有第一个字符串 ":", "Royal Palace of Madrid (Teatro Real)" 没有第一个字符串 "white space", ...

【问题讨论】:

    标签: regex perl


    【解决方案1】:

    split 可以完成这项工作

    my @matches = split(
       qr/
          (?: (?<= \) : ) 
          |   (?<= \) (?! : ) )
          )
          \s*
       /x,
       $my_town,
    );
    

    但由于输入在我看来并不像一个统一分隔的列表,我认为它是适合这项工作的错误工具。注意转向解析器是多么简单:

    my @matches = $my_town =~ / \S .*? \( [^)]+ \) :? /xgs;
    

    【讨论】:

    • 没有按要求工作,Madrid(32): Villa de Madrid (ES) 是第一个匹配项。 / \S .*? \( [^)]+ \) :? /xg 效果更好。
    • @Qtax,谢谢,已修复(虽然我没有使用您的修复)
    • OP 希望在第一场比赛结束时包含:
    • @user934718,正如 Qtax 指出的那样,我误读了这个问题。固定的。 (我想我看到了 sln 帖子的输出)
    • @Qtax,我想我将 sln 的帖子混淆为 OP 的一部分,并且 sln 不输出“:”。固定。
    【解决方案2】:

    分割线不是很科学的方法。

    use strict;
    use warnings;
    
    my $my_town = 'Madrid(32): Villa de Madrid (ES) Royal Palace of Madrid (Teatro Real)  ';
    my @travel = split( / (?<=\)):? \s* /x  , $my_town );
    
    for (@travel) {
       print "'$_'\n";
    }
    

    '马德里(32)'
    '马德里别墅 (ES)'
    “马德里皇宫(皇家剧院)”

    ** 编辑**

    我不知道为什么,但如果你只是在努力解决可变长度的后视问题
    并想看看如何将可选冒号 : 包含在拆分中
    你总是可以这样做:

    my @travel = split( / (?:(?<=\):)|(?<=\))(?!:)) \s* /x  , $my_town );
    

    '马德里(32):'
    '马德里别墅 (ES)'
    “马德里皇宫(皇家剧院)”

    【讨论】:

    • 第一个代码在没有冒号的情况下可以正常工作:作为拆分的一部分。谢谢。第二个代码根本不起作用。
    • @user934718:第一个和第二个代码都非常适合它们产生的相应输出。但我主要是猜测需要什么。
    猜你喜欢
    • 1970-01-01
    • 2013-11-09
    • 1970-01-01
    • 1970-01-01
    • 2012-07-22
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    • 2021-10-11
    相关资源
    最近更新 更多