3
$\begingroup$

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?

$\endgroup$
  • $\begingroup$ You want to make a StringPattern and feed it to StringReplace $\endgroup$ – Jason B. Oct 11 '16 at 4:07
  • $\begingroup$ str is not a string. $\endgroup$ – corey979 Oct 11 '16 at 8:36
5
$\begingroup$

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[])

enter image description here

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

a work around:

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

and

str2=Last[Flatten[StringSplit[str]]]
$\endgroup$
0
$\begingroup$

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"}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.