# How to replace sequences in a list based on specific patterns?

I have this list:

list = {V1, A1, B1, A2, B2, B1 A1, V2}


I want to replace sequences like A1, B1 with {A1, B1} if they exist, and A2, B2 with {A2, B2}, B1, A1 with {B1, A1}, etc. The desired result should be:

{V1, {A1, B1}, {A2, B2}, {B1 A1}, V2}


Does anyone know of a neat way to accomplish this?

• Can you make the rule more precise? Why V1, A1 is not combined as {V1,A1}? Only A and B matters? Commented Jun 21 at 6:43
• @A.Kato ah, the rules are predetermined. Commented Jun 21 at 6:44

SequenceReplace[list, (x : {A1, B1} | {B1, A1} | {A2, B2} | {B2, A2}) -> x]
(* {V1, {A1, B1}, {A2, B2}, {B1 A1}, V2} *)


If you also want to handle A3,B3 etc, then it's really not convenient to have your variable be one single symbol. It would be more idiomatic to have them look like A[1], A[2], etc.

• Thanks, I was thinking about doing something similar but list one by one so it was too long. Commented Jun 21 at 6:41
• (+1) Also SequenceReplace[list, (x : {OrderlessPatternSequence[A1, B1] | OrderlessPatternSequence[A2, B2]}) -> x] Commented Jun 21 at 11:36

It is not clear from the question, but I understand that only A? and B? are combined, but somehow A? and V? are not. Then, the following code will work for a data containing A3 and B3 as well. (I assume that the input data "list" consists of Symbols, rather than Strings.)

list = {V1, A1, B1, A2, B2, B1, A1, V2}

(* {V1, A1, B1, A2, B2, B1, A1, V2} *)

slist = StringPartition[ToString[#], 1] & /@ list;
SplitBy[slist, {MatchQ[#[[1]], "A" | "B"], #[[2;;]]} &] /. back

(* {{V1}, {A1, B1}, {A2, B2}, {B1, A1}, {V2}} *)

i = InternalCopyListStructure[#1, #2] &;
list = {V1, A1, B1, A2, B2, B1 , A1, V2};
r = {A1 -> 1, B1 -> 1, A2 -> 2, B2 -> 2};
i[Split[list /. r] /. {a_} :> a, list]


->{V1, {A1, B1}, {A2, B2}, {B1, A1}, V2}

Note:

• potential fragility Internal` functions
• need modification for more general patterns