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$
2
  • $\begingroup$ You want to make a StringPattern and feed it to StringReplace $\endgroup$
    – Jason B.
    Commented Oct 11, 2016 at 4:07
  • $\begingroup$ str is not a string. $\endgroup$
    – corey979
    Commented Oct 11, 2016 at 8:36

3 Answers 3

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$
4
  • $\begingroup$ Would not Repeated[_?(UpperCaseQ), {3}] work as well, rather than defining caps? $\endgroup$
    – march
    Commented Oct 11, 2016 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.
    Commented Oct 11, 2016 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
    Commented Oct 11, 2016 at 17:19
  • $\begingroup$ A regex variation: StringCases[{"A Big Cheese ABC", "examine your zipper XYZ"}, RegularExpression["((\\w|\\s)+) ([[:upper:]]{3})"] -> {"$1", "$3"}]. $\endgroup$ Commented Oct 12, 2016 at 6:55
1
$\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$
0
$\begingroup$

a work around:

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

and

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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