Biswajit_86
Biswajit_86

Reputation: 3739

perl: split string at exact index

I am looking for a perl function that can split a string at a certain index position into an array of 2 strings

For ex : splitting abcde at index 1 will give an array {ab} {cde}

I suppose I can find out the length of a string , and then get the first offset at substr $str, -$index and the second offset as $substr $str,0 $length-$index. However , I want to know if there is an existing perl function that does this.

Upvotes: 1

Views: 4950

Answers (3)

dlamblin
dlamblin

Reputation: 45321

I'm not sure how split 'abcde' at index 1 means ('ab','cde') instead of ('a','bcde'). Here's something that does it:

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;
use v5.22;
use feature qw(signatures);
no warnings qw(experimental::signatures);

sub split_ind($str, $i) {
  my $x = $i + 1;
  return (substr($str, 0, $x), substr($str, $x));
}

my $in = "abcde";
say Dumper($in, split_ind($in, 1));

And the output is:

$ ./string_split.pl
$VAR1 = 'abcde';
$VAR2 = 'ab';
$VAR3 = 'cde';

Upvotes: 0

Borodin
Borodin

Reputation: 126722

Since you seem to always want both parts of the string, and since your idea of a character position is one off from the Perl standard, it seems best to wrap this in a subroutine

Here are two methods, using substr and unpack. The former is probably clearer, but the latter may be a little faster if you're interested in speed. But in that case you should benchmark them and avoid copying the string from the stack

use strict;
use warnings;
use feature 'say';

say join ' ', map "{$_}", split_at('abcde', 1);
say join ' ', map "{$_}", split_at_2('abcde', 1);


sub split_at {
    my ($str, $n) = @_;
    ++$n;
    substr($str, 0, $n), substr($str, $n);
}

sub split_at_2 {
    my ($str, $n) = @_;
    ++$n;
    unpack "A$n A*", $str;
}

output

{ab} {cde}
{ab} {cde}

Upvotes: 0

Miller
Miller

Reputation: 35198

I'd recommend using substr.

#!/usr/bin/env perl

use strict;
use warnings;

my $string = 'abcde';

my $element1 = $string;
my $element0 = substr $element1, 0, 2, '';

use Data::Dump;

dd($element0, $element1);

However, you can use a regex:

#!/usr/bin/env perl

use strict;
use warnings;

my $string = 'abcde';

my @array = $string =~ /(.{2})(.*)/s or die "failed to match, booo";

use Data::Dump;

dd @array;

Or use split:

#!/usr/bin/env perl

use strict;
use warnings;

my $string = 'abcde';

my @array = split /(?<=.{2})/s, $string, 2;

use Data::Dump;

dd @array;

All techniques output:

("ab", "cde")

Upvotes: 1

Related Questions