Найти позиции заданных персонажей - PullRequest
1 голос
/ 22 ноября 2010

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

my @charpos=();
s/(?=([«»\n]))/push @charpos, [$1, 0+($-[0])]; "";/ge;
# sort {$a->[1] <=> $b->[1]} @charpos;

Но это решение использует оператор «замена» для замены пустой строкой, это нормально?Следует ли комментировать строку без комментария?

Ответы [ 4 ]

2 голосов
/ 22 ноября 2010

Для решения вашей общей проблемы вы можете изучить sub parse_line в Text :: ParseWords .

В контексте кода, который вы задали в своем вопросе, я бы не стал изменять исходную строку:

#!/usr/bin/perl

use utf8;
use strict; use warnings;

my $x = q{«...«...»...«...»...»};

my @pos;

while ( $x =~ /([«»\n])/g ) {
    push @pos, $-[1];
}

use YAML;
print Dump \@pos;
2 голосов
/ 22 ноября 2010

Существует более одного способа снятия шкуры с кошки:

#!/usr/bin/env perl

use 5.010;
use utf8;
use strict;
use warnings qw< FATAL all >;
use autodie;
use open qw< :std OUT :utf8 >;

END { close STDOUT }

my @pos = ();
my $string = q{«...«...»...«...»...»};
($string .= "\n") x= 3;

say "string is:\n$string";

for ($string) {
    push @pos, pos while m{
        (?= [«»\n] )
    }sxg;;
}
say "first  test matches \@ @pos";

@pos = ();

## this smokes :)
"ignify" while $string =~ m{
    [«»\n]
    (?{ push @pos, $-[0] })
}gx;
say "second test matches \@ @pos";

__END__
string is:
«...«...»...«...»...»
«...«...»...«...»...»
«...«...»...«...»...»

first  test matches @ 0 4 8 12 16 20 21 22 26 30 34 38 42 43 44 48 52 56 60 64 65
second test matches @ 0 4 8 12 16 20 21 22 26 30 34 38 42 43 44 48 52 56 60 64 65

Но, пожалуйста, укажите Синан .

2 голосов
/ 22 ноября 2010

В общем, чтобы найти позиции символов в строке, вы можете сделать это следующим образом:

my $str = ...;
my @pos;
push @pos, pos $str while $str =~ /(?=[...])/g;

И тогда все позиции, с которыми сопоставлено регулярное выражение, будут в @pos.По крайней мере, с помощью этого метода вы не будете постоянно переписывать исходную строку.

0 голосов
/ 22 ноября 2010

Скимизация кота без регулярного выражения для добавления в руководство.Чудовищно ли это в глазах смотрящего:

use List::Util q/min/;
my @targets = ('«','»',"\n");
my $x = q{«...«...»...«...»...»};
my $pos = min map { my $z = index($x,$_); $z<0?Inf:$z } @targets;
my @pos;
while ($pos < Inf) {
    push @pos, $pos;
    $pos = min map { my $z = index($x,$_,$pos+1); $z<0?Inf:$z } @targets;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...