Сплит по специальному критерию (perl) - PullRequest
1 голос
/ 28 октября 2011

У меня есть строка, которая содержит одно, два или три слова, которые начинаются с LowerCase, за которым следует двоеточие, а за каждым следуют несколько (произвольных) слов, начинающихся с UpperCase:

пример (произвольно):

alpha: Beta beta gamma: Alpha Beta gamma beta gamma: Omega Omega omega alpha: Gamma Omega Phi

критерий разделения: любое количество слов, начинающихся со строчных букв, следует за двоеточием.

пример:

alpha: Beta
beta gamma: Alpha Beta
gamma beta gamma: Omega Omega
omega alpha: Gamma Omega Phi

небольшая помощь приветствуется.Спасибо

Ответы [ 5 ]

2 голосов
/ 28 октября 2011
use strict;
use warnings;

my $lcword  = qr!\b[a-z]+!;      # all-lowercase word
my $ucfword = qr!\b[A-Z][a-z]+!; # word with a leading uppercase letter
my @list = $string =~ m!((?:$lcword|\s)+: (?:$ucfword|\s)+)!g;
print join("\n", @list), "\n";
0 голосов
/ 28 октября 2011

Это то, что вы хотите?

use strict; use warnings;
my $string="alpha: Beta beta gamma: Alpha Beta gamma beta gamma: "
    ."Omega Omega omega alpha: Gamma Omega Phi";
my @list = split /\s([^A-Z]+|\s+)\:\s+/, $string;
my @first = split /\:/, $list[0];
shift @list;
@list = (@first,@list);
print $string.$/;
print $_,$/ for @list;
0 голосов
/ 28 октября 2011

Возможно, вам лучше разбить, но если вы хотите сделать это с помощью регулярного выражения:

#!/usr/bin/perl -w

use strict;

my $string = "alpha: Beta beta gamma: Alpha Beta gamma beta gamma: Omega Omega omega alpha: Gamma Omega Phi";

my @list = $string =~ /(\b[a-z]\w+(?: [a-z]\w+){0,2}: [A-Z]\w+(?: [A-Z]\w+)*)/g;

print "$_\n" for @list;
0 голосов
/ 28 октября 2011

В вашем примере точка с запятой (вы имели в виду двоеточие?), Кажется, не несет нагрузки. Попробуйте это:

#!/usr/bin/env perl

use strict;
use warnings;

while (<DATA>) {       # for each line, look for
  s! \b([A-Z][a-z]+)   #  - a capitalized word
       \s+             #  - followed by whitespace
     ([a-z]+)          #  - followed by a lowercased word
   !$1\n$2!xg;         # and turn that whitespace into a newline
  print;
}

__END__
alpha: Beta beta gamma: Alpha Beta gamma beta gamma: Omega Omega omega alpha: Gamma Omega Phi

Это печатает:

alpha: Beta
beta gamma: Alpha Beta
gamma beta gamma: Omega Omega
omega alpha: Gamma Omega Phi
0 голосов
/ 28 октября 2011

Используйте замену, а не разделение.

$string =~ s/(stuff that must precede a newline)(stuff that must follow a newline)/\1\n\2/g;

Буква g в конце делает его глобальным. Первое имя должно соответствовать любому числу слов, начинающихся с заглавной буквы, а второе должно соответствовать любому количеству строчных слов, за которыми следует двоеточие (или точка с запятой).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...