I would probably use split
here, since that's what you're doing after all. Below I give you the choice between 3 ways:
#!/usr/bin/perl
use strict;
use warnings;
use Test::More;
while( <DATA>)
{ chomp;
my( $string, $expected_substring, $expected_remainder)= split /\s+/;
{ # method 1: split on letter, captured letter is added to the remainder
# the 3rd arg to split is the LIMIT (see perldoc -f split)
my( $substring, $letter, $remainder)= split /([a-zA-Z])/, $string, 2;
$remainder= $letter . $remainder if $letter;
is( $substring, $expected_substring, "method 1, substring, s: '$string'");
is( $remainder, $expected_remainder, "method 1, remainder, s: '$string'");
}
{ # method 2: add space before letter, split on space
my $string_copy= $string; # or $string would be modified
$string_copy=~ s/([a-zA-Z])/ $1/;
my( $substring, $remainder)= split / /, $string_copy, 2;
is( $substring, $expected_substring, "method 2, substring, s: '$string'");
is( $remainder, $expected_remainder, "method 2, remainder, s: '$string'");
}
{ # method 3: method 2 shortened using s//r (perl 5.14 and above)
my( $substring, $remainder)= split / /, $string=~ s/([a-zA-Z])/ $1/r, 2;
is( $substring, $expected_substring, "method 3, substring, s: '$string'");
is( $remainder, $expected_remainder, "method 3, remainder, s: '$string'");
}
}
done_testing();
# test data, string, substring and remainder are on one line, space separated
__DATA__
12345A678 12345 A678
12345AB678 12345 AB678
12345A67B8 12345 A67B8
12345678 12345678