Find the positions of these characters

I want to find the positions of some characters to process them without using a monstrous recursive and inefficient regular expression. Here is how I do it:

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

But this solution uses the "substitute" operator to replace with an empty string, is this normal? Should the commented line uncomment?

+1
source share
4 answers

For your common problem, you can examine sub parse_line in Text :: ParseWords .

In the context of the code that you indicated in your question, I would not change the source line:

 #!/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
source

In general, to find the positions of characters in a string, you can do this as follows:

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

And then all the positions in which the regular expression matches will be in @pos. At least with this method, you do not constantly rewrite the original string.

+2
source

There are several ways to throw a cat:

 #!/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 

But please take Sinan .

+2
source

A regular expression for a cat to be added to the guide. Is this monstrous in the eyes of the observer:

 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; } 
0
source

All Articles