Home > Net >  Continue regex if the previous matched word/digit satisfies a condition
Continue regex if the previous matched word/digit satisfies a condition

Time:03-19

For example this is the string

"cat_dog_bat_ball_up_down_hot_cold"

If i use the regex as

/^(.*)_(.*)_(.*)_(.*)_(.*)_(.*)_(.*)_(.*)/

Then i get each values split up on the basis of "_"

my $var1 = $1; #results as var1 = cat
my $var2 = $2; #results as var2 = dog
my $var3 = $3; #results as var3 = bat
my $var4 = $4; #results as var4 = ball
my $var5 = $5; #results as var5 = up
my $var6 = $6; #results as var6 = down
my $var7 = $7; #results as var7 = hot
my $var8 = $8; #results as var8 = cold

I need my output something like this :

var1 = cat_dog
var2 = bat_ball
var3 = up_down
var4 = hot_cold

I don't want to split the next word on the basis of _. If the previous word is a certain word. example if the previous word matches "up" I don't want to split up_down on the basis of _.

But if the previous word is ball then I want to split the ball_up on the basis of _. How can i go about doing this? Not necessarily in a regex form, but maybe any other ways also if its possible.

CodePudding user response:

My take on your question is that you want to avoid splitting on any underscore if they are preceded by certain words. What you could try is to throw these exceptions inside a non-capture group and use a SKIP-FAIL combination:

(?<=^|_)(?:[bc]at|up|hot)_(*SKIP)(*F)|_

See an online demo


  • (?<=^|_) - Positive lookbehind to assert position is following either the start-line anchor or an underscore;
  • (?:[bc]at|up|hot)_ - An non-capture group to match your words that need no split, followed by an underscore;
  • (*SKIP)(*F) - Forget what is previous matched;
  • |_ - Match any other underscore as the alternative.

CodePudding user response:

my @words = /
   (
      (?: (?: cat | bat | up | hot ) _ )*
      [^_] 
   )
/xg;
  • Related