# Rule-based string manipulation

I am studying string manipulation. I have a list of strings all members of which consist of 2 or 3 words followed by a 3 letter capital appreviation of the words, for example

str={A Big Cheese ABC}


I'd like to get two substrings:

str1={A Big Cheese}


and

str2={ABC}


Using UpperCaseQ returning "True" for three characters in a row would appear to be a first step. Any thoughts?

• You want to make a StringPattern and feed it to StringReplace Oct 11 '16 at 4:07
• str is not a string. Oct 11 '16 at 8:36

First you need a string pattern that matches your inputs. The first part of your string "A Big Cheese", can be matched by two underscores, __. The last part is always three upper case letters in a row. You can match any upper case letter with

caps = Alternatives @@ (ToUpperCase /@ Alphabet[])


You can see it work here,

StringMatchQ["A", caps]
(* True *)


To catch three capital letters in a row, you can join them using ~~

StringMatchQ["ABC", caps ~~ caps ~~ caps]
(* True *)

StringMatchQ["AbC", caps ~~ caps ~~ caps]
(* False *)


Or you can use Repeated,

StringMatchQ["XYZ", Repeated[caps, {3}]]
(* True *)


Now that we have our pattern we can give it to StringCases. You need to name the patterns and apply a transformation rule

StringCases["A Big Cheese ABC", a__ ~~ b : Repeated[caps, {3}] :> {a, b}]
(* {{"A Big Cheese ", "ABC"}} *)


You can wrap this up into a function, using First to remove the extra curly brackets,

splitSTRING["examine your zipper XYZ"]
(* {"examine your zipper ", "XYZ"} *)


## Edit

As march points out you don't have to use Alternatives to make a Pattern, you could use UpperCaseQ to make a PatternTest:

StringCases["A Big Cheese ABC",
a__ ~~ b : Repeated[_?(UpperCaseQ), {3}] :> {a, b}]
(* {{"A Big Cheese ", "ABC"}} *)

• Would not Repeated[_?(UpperCaseQ), {3}] work as well, rather than defining caps? Oct 11 '16 at 16:47
• Yes indeed you can - I just have been using Alternatives a lot lately so that was my go-to solution. Oct 11 '16 at 17:12
• Yeah okay, I didn't do it myself, so I wasn't sure if there was some pitfall there I just wasn't seeing. Oct 11 '16 at 17:19
• A regex variation: StringCases[{"A Big Cheese ABC", "examine your zipper XYZ"}, RegularExpression["((\\w|\\s)+) ([[:upper:]]{3})"] -> {"$1", "$3"}]. Oct 12 '16 at 6:55

Since the input strings end with a 3 letter capital abbreviation of the words, you can use StringTake:

StringTake["A Big Cheese ABC", {{1, -5}, -3}]


{"A Big Cheese", "ABC"}

a work around:

str1=StringJoin[Riffle[Most[Flatten[StringSplit[str]]], " "]]


and

str2=Last[Flatten[StringSplit[str]]]