使用Look-ahead和Look-behind(perl)

时间:2011-09-11 18:31:03

标签: regex perl

我想用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)

请给我一点帮助。

是否有任何方式为“)”返回所有发现较少的第一个字符的后视功能? “:马德里别墅(ES)”没有第一串“:”,“马德里皇家宫殿(皇家剧院)”没有第一串“白色空间”,...

2 个答案:

答案 0 :(得分:3)

split可以完成这项工作

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

但是由于输入对我来说看起来并不像一个统一的分隔列表,我认为这是错误的工具。请注意如何更简单地转向解析器:

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

答案 1 :(得分: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)' '马德里皇宫(Teatro Real)'

**编辑**

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

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

'马德里(32):'
'马德里别墅(ES)' '马德里皇宫(Teatro Real)'