# Select UPPER CASE list items with spaces and punctuation

I have a sample list that includes people's names in Title Case, and their companies in UPPER CASE.

list = {"Bob Jones", "ACME-SYSTEMS", "John Smith", "FUTURETECH123",
"Sally Jones", "CITY SCHOOL", "Jane Black", "CONSULTANT",
"Max Speed", "A.B. CORP"}


I would like to select only the list items that are in upper case. The most obvious approach would be to use UpperCaseQ:

Select[list, UpperCaseQ]
(*{"CONSULTANT"}*)


Unfortunately, UpperCaseQ returns FALSE for any list item that has a non letter characters such as space or punctuation in it.

I did find that I can incorporate StringReplace within UpperCaseQ to ignore some symbols:

Select[list, UpperCaseQ[StringReplace[#, {" ", "-", "."} -> ""]] &]
(*{"ACME-SYSTEMS", "CITY SCHOOL", "CONSULTANT", "A.B. CORP"}*)


Besides spaces, periods and hyphens, there is also the issue of numbers and symbols in strings (hence FUTURETECH123 being off the list). On a small dataset, you can hand code the exceptions, but as you get larger, you would need to automate it.

I was able to come up with this code as a way to automatically select the non letter characters, but I would think running the code on a very large document would not be very efficient.

allcharacters =
DeleteDuplicates[Flatten[Characters[list]]]; nonletters =
Select[allcharacters, LetterQ[#] == False &];
Select[list, UpperCaseQ[StringReplace[#, nonletters -> ""]] &]
(*{"ACME-SYSTEMS","FUTURETECH123","CITY SCHOOL","CONSULTANT","A.B. CORP"}*)


Is there a more simple way to select items in a list that are UPPER CASE while ignoring the non letter characters?

The following code might not be quite fast but it takes into account foreign languages.

list = {"Bob Jones", "ACME-SYSTEMS", "John Smith", "FUTURETECH123",
"Sally Jones", "CITY SCHOOL", "Jane Black", "CONSULTANT",
"Max Speed", "A.B. CORP", "TЯUMP", "яUSSIam"};
Select[list, ToUpperCase[#] === # &]


You can see it catches the Russian TЯUMP.

UPDATE

Apparently, Russians cannot be caught. In the example below, an accented letter á (as those used in Spanish) is processed by the system but the Russian one is quite stealthy.

string = "áа";
ToCharacterCode[string]
ToUpperCase[string]
(*
{225, 1072}
"Áа"
*)

• What a simple solution. Now just to make sure I am following correctly, the code is essentially selecting all items in the list where using ToUpperCase produces the exact same result as the original item. Right? Jul 19 '18 at 20:38
• @kickert Yes, exactly. Jul 19 '18 at 20:42
• "Russian TЯUMP." That's a good one! ;) Jul 19 '18 at 20:47

The simplest regex that I can think of that does what the OP asks is the following:

list // Pick[#, StringContainsQ[#, RegularExpression["^[^a-z]+$"]]] &  "ACME-SYSTEMS", "FUTURETECH123", "CITY SCHOOL", "CONSULTANT", "A.B. \ CORP"} For the cases discussed by Hector, maybe: Join[list, {"TЯUMP", "яUSSIam", "ЯЯ", "TЯЯUMP", "Яя", "TЯяUMP"}] // Pick[#, StringContainsQ[#, RegularExpression["^[^a-zа-я]+$"]]] &


{"ACME-SYSTEMS", "FUTURETECH123", "CITY SCHOOL", "CONSULTANT", "A.B. \ CORP", "TЯUMP", "ЯЯ", "TЯЯUMP"}

list2 // Pick[#, StringContainsQ[#, RegularExpression["[ALPHA]"]]] &


{"ACME-SYSTEMS", "FUTURETECH123", "CITY SCHOOL", "CONSULTANT", "A.B. \ CORP", "TЯUMP"}

A very beautiful solution, which gives the right answer. Things began to unravel, however, when I read Hector's comment, got an unexpected result, and tried the following:

 list// Pick[#, StringContainsQ[#, RegularExpression["[ALPHB]"]]]&


{"Bob Jones", "ACME-SYSTEMS", "FUTURETECH123", "CITY SCHOOL", "Jane \ Black", "CONSULTANT", "A.B. CORP"}

• A coworker of mine just suggested looking into RegularExpression for this problem. Seems like a great option for more complicated string manipulations. Thanks for the alternative approach. Jul 19 '18 at 21:35
• @tomd My version of MMA does not have StringContainsQ. Do you mind checking the result of your approach on "Яя". I noticed MMAv9 does not classify the Russian alphabet (even thought my OS does). I am wondering whether regular expressions in MMA are any better in latter versions of MMA. Jul 19 '18 at 21:59
• @Hector. On reading your comment, I realized my original solution was wrong! I have modified it to use the simplest regex that I can think of that does what the OP asks. I prefer your solution. Jul 20 '18 at 10:40