in reply to split string at variable position with matching

I'd use rindex to find the last * before position 30. Note that you don't split on /\*/ but on /\* /.

You can use the look-behind (?<= to specify that the space is preceded by that many characters:

#!/usr/bin/perl use strict; use warnings; my $string = "hello my * name is Rob * and * I am a very nice person * + at least * I think * so"; my $part1 = "hello my * name is Rob * and *"; my $part2 = "I am a very nice person * at least * I think * so"; sub split_before { my ($string, $pos) = @_; my $pos = rindex $string, '*', 30; split /(?<=^.{$pos}\*) /, $string, 2 } use Test2::V0; is "$part1 $part2", $string; is [split_before($string, 30)], [$part1, $part2]; done_testing();

BTW,

(split /(^.{,30}\* )/, $string, 2)[1, 2]
passes the first test, too (but not the second one, as the space is still part of $part1).

Update: Read below for a fix, thanks AnomalousMonk. I shouldn't work on two different tasks at the same time.

map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

Replies are listed 'Best First'.
Re^2: split string at variable position with matching
by AnomalousMonk (Archbishop) on Sep 12, 2021 at 02:28 UTC
    sub split_before { my ($string, $pos) = @_; my $pos = rindex $string, '*', 30; split /(?<=^.{$pos}\*) /, $string, 2 }

    The quoted code has a problem: the $pos subroutine argument (offset of '*' character of '* ' sequence to be used to split on) is masked by another my $pos definition, and then is not used at all. This is easily fixed. With many (largely imaginary) test cases (update: and there are many corner cases uncovered, but my imagination only stretches so far):

    Note that for any $pos to the left of the leftmost '*' in the string, no meaningful split is returned.


    Give a man a fish:  <%-{-{-{-<

Re^2: split string at variable position with matching
by LanX (Saint) on Sep 11, 2021 at 20:44 UTC
    TIMTOWT-KISS ;)

    Once you have the position with rindex (which is a great idea), why not apply substr instead of a sophisticated regex in split?

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      I wanted to use "some backwards regex" ;-)

      map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]