# creating sublists by rules

I have a list:

lis = {{ghi ,0,1,0,1,3,prq ,2,4,3,2,5},{abc 12-3,0,0,2,0,1,def 1-3,0,1,1,1,3}}


I'd like to:

1. delete each element whose first sub-element does not end with the combo space/integer(s)/"-"/integer(s)

and then

1. delete from the remaining elements the pattern space/integer(s)/"-"/integer(s) to give:

res = {abc,0,0,2,0,1,def,0,1,1,1,3}


Thanks for any thoughts!

ClearAll[numberdashnumber, patterntest, trimStrings]

numberdashnumber = NumberString ~~ "-" ~~ NumberString ~~ ___;

patterntest = StringMatchQ[__ ~~ " " ~~ numberdashnumber];

trimStrings = Cases[#, p : {_String?patterntest, __} :>
(p /. s_String?patterntest :> StringTrim@First@StringSplit[s, numberdashnumber]),
All] &;


Examples:

lis = {{"ghi ", 0, 1, 0, 1, 3, "prq ", 2, 4, 3, 2, 5},
{"abc 12-3", 0, 0, 2, 0, 1, "def 1-3", 0, 1, 1, 1, 3}};

trimStrings[lis]

 {{"abc", 0, 0, 2, 0, 1, "def", 0, 1, 1, 1, 3}}

lis2 = {{" ghi ", 0, 1, 0, 1, 3, " prq ", 2, 4, 3, 2, 5},
{" abc 12-3", 0, 0, 2, 0, 1, " def 1-3", 0, 1, 1, 1, 3}};

trimStrings[lis2]

 {{"abc", 0, 0, 2, 0, 1, "def", 0, 1, 1, 1, 3}}

lis3 = {{" North ", 17, 3, 10, 3, 30, " South East ", 0, 3, 0, 0, 3},
{" West South West ", 0, 14, "-" 5, 14, " East ", 21, 17, 7, 5, 45},
{" North 0-1 ", 0, 9, 5, 6, 22, " North East 1-0 ", 2, 14, 14, 0, 30},
{" South 0-1 ", 0, 0, 0, 0, 0, " North West 1-0 ", 7, 24, 7, 7, 45}};

trimStrings[lis3]

 {{"North", 0, 9, 5, 6, 22, "North East", 2, 14, 14, 0, 30},
{"South", 0, 0, 0, 0, 0, "North West", 7, 24, 7, 7, 45}}

• @Suite401, please see the update.
– kglr
Aug 29, 2021 at 4:35
• I could not get your method to work with this: lis3 = lis3 = {{" North ", 17, 3, 10, 3, 30, " South East ", 0, 3, 0, 0, 3}, {" West South West ", 0, 14, "-" 5, 14, " East ", 21, 17, 7, 5, 45}, {" North 0-1 ", 0, 9, 5, 6, 22, " North East 1-0 ", 2, 14, 14, 0, 30}, {" South 0-1 ", 0, 0, 0, 0, 0, " North West 1-0 ", 7, 24, 7, 7, 45}}; I apologize for not making the question clearer Aug 29, 2021 at 5:19
• @Suite401, updated with a modification that works for the example in your comment.
– kglr
Aug 29, 2021 at 6:07
lis3 = {{" North ", 17, 3, 10, 3, 30, " South East ", 0, 3, 0, 0, 3},
{" West South West ", 0, 14, "-" 5, 14, " East ", 21, 17, 7, 5, 45},
{" North 0-1 ", 0, 9, 5, 6, 22, " North East 1-0 ", 2, 14, 14, 0, 30},
{" South 0-1 ", 0, 0, 0, 0, 0, " North West 1-0 ", 7, 24, 7, 7, 45}};

a = Pick[lis3, StringContainsQ[Last[StringSplit[#]], "-"] & /@
lis3[[All, 1]], True];

res = a /. b_String /; StringContainsQ[b, "-"] :>
StringDrop[b, -StringLength[Last@StringSplit[b]] - 1]

{{" North ", 0, 9, 5, 6, 22, " North East ", 2, 14, 14, 0, 30},
{" South ", 0, 0, 0, 0, 0, " North West ", 7, 24, 7, 7, 45}}


Allow me to present a step-by-step solution. I have put all the use cases in the list called lis3.

lis3 = {
{" North ", 17, 3, 10, 3, 30, " South East ", 0, 3, 0, 0,
3}, {" West South West ", 0, 14, "-" 5, 14, " East ", 21, 17, 7,
5, 45}, {" North 0-1 ", 0, 9, 5, 6, 22, " North East 1-0 ", 2, 14,
14, 0, 30}, {" South 0-1 ", 0, 0, 0, 0, 0, " North West 1-0 ", 7,
24, 7, 7, 45},
{" ghi ", 0, 1, 0, 1, 3, " prq ", 2, 4, 3, 2, 5},
{" abc 12-3", 0, 0, 2, 0, 1, " def 1-3", 0, 1, 1, 1, 3},
{"ghi ", 0, 1, 0, 1, 3, "prq ", 2, 4, 3, 2, 5},
{"abc 12-3", 0, 0, 2, 0, 1, "def 1-3", 0, 1, 1, 1, 3}
};

p1 = ___ ~~ " " ~~ DigitCharacter .. ~~ "-" ~~ DigitCharacter .. ~~ ___


The pattern p1 is a space,digit(s),dash,digit(s) (preceded and followed by 0 or more characters. Now we need to detect this pattern in (only) the first element of each of the sublists.

StringMatchQ[First@#, p1] & /@ lis3


{False, False, True, True, False, True, False, True}

Pick the sublists where the pattern p1 matched and True was returned.

t1 = Pick[lis3, StringMatchQ[First@#, p1] & /@ lis3]

{{" North 0-1 ", 0, 9, 5, 6, 22, " North East 1-0 ", 2, 14, 14, 0,
30}, {" South 0-1 ", 0, 0, 0, 0, 0, " North West 1-0 ", 7, 24, 7, 7,
45}, {" abc 12-3", 0, 0, 2, 0, 1, " def 1-3", 0, 1, 1, 1,
3}, {"abc 12-3", 0, 0, 2, 0, 1, "def 1-3", 0, 1, 1, 1, 3}}

f2[x_String] := StringReplace[
x, " " ~~ (DigitCharacter ..) ~~ "-" ~~ (DigitCharacter ..) :>   ""]
f2[x_] := x


f2 will replace the pattern with empty string using MapAll. Strings will be affected; other values are not altered due to the second defn above.

t2 = f2 //@ t1

{{" North ", 0, 9, 5, 6, 22, " North East ", 2, 14, 14, 0,
30}, {" South ", 0, 0, 0, 0, 0, " North West ", 7, 24, 7, 7,
45}, {" abc", 0, 0, 2, 0, 1, " def", 0, 1, 1, 1, 3}, {"abc", 0, 0,
2, 0, 1, "def", 0, 1, 1, 1, 3}}


Now comes the trimming part. Here I have copied the pattern from the docs (search Whitespace. Using appropriate alteration, you can either remove spaces from the leading or trailing edge of the strings. If all space is to be trimmed, use Trim (that has been commented out).

f3[x_String] := StringReplace[x,
(StartOfString ~~ Whitespace) | (Whitespace ~~ EndOfString) :> ""];
(* f3[x_String]:=StringTrim[x] *)
f3[x_] := x


Once again, f3 alters strings only when MapAll is applied.

t3 = f3 //@ t2

{{"North", 0, 9, 5, 6, 22, "North East", 2, 14, 14, 0, 30}, {"South",
0, 0, 0, 0, 0, "North West", 7, 24, 7, 7, 45}, {"abc", 0, 0, 2, 0,
1, "def", 0, 1, 1, 1, 3}, {"abc", 0, 0, 2, 0, 1, "def", 0, 1, 1, 1,
3}}