6
$\begingroup$

Is there some simpler way than the one below to convert a CamelCased string to a string consisting of separate words?

A crude way, with tedious typing, is the following:

unCamelCase[str_] := 
 StringDrop[
  StringJoin[
   StringSplit[
    str, {"A" -> " a", "B" -> " b", "C" -> " c", "H" -> " h", 
     "I" -> " i", "O" -> " o", "S" -> " s", "Z" -> " z"}]], 1]

(In the above I omitted from the list of replacements in StringSplit the letters I don't need for the particular example below, but for the method being used, in general I'd need the list of all 26 replacements.)

For example:

   unCamelCase["CompactSubspaceOfHausdorffSpaceIsClosed"]
(* compact subspace of hausdorff space is closed *)
$\endgroup$
1

5 Answers 5

5
$\begingroup$

There are two resource functions: FromCamelCase and ToCamelCase. FromCamelCase splits camel case phrases into words. Add ToLowerCase to convert to lower case.

ResourceFunction["FromCamelCase"]["CompactSubspaceOfHausdorffSpaceIsClosed"]
(* "Compact Subspace Of Hausdorff Space Is Closed" *)
$\endgroup$
15
$\begingroup$
StringReplace["CompactSubspaceOfHausdorffSpaceIsClosed", 
 u_?UpperCaseQ :> " " <> ToLowerCase[u]]

(*" compact subspace of hausdorff space is closed"*)
$\endgroup$
2
  • 1
    $\begingroup$ I like your answer. It does create an extra space at the beginning so perhaps adding StringTrim would help. Although that would remove spaces if they existed. $\endgroup$
    – Mark R
    Sep 2, 2021 at 2:08
  • $\begingroup$ @MarkR That was not the original question. However that can be addressed by adding one more rule StringReplace["CompactSub...", {RegularExpression["^\\s*[A-Z]"] :> ToLowerCase["$0"], u_?UpperCaseQ :> " " <> ToLowerCase[u]}]. It depends what exactly is required. $\endgroup$ Sep 2, 2021 at 13:41
4
$\begingroup$

This handles acronyms and numbers properly:

deCamelCase[s_]:=StringRiffle@StringSplit[s,{RegularExpression["(?<=[A-Z])(?=[A-Z][a-z])"],RegularExpression["(?<=[^A-Z])(?=[A-Z])"],RegularExpression["(?<=[A-Za-z])(?=[^A-Za-z])"]}]  

Based on an answer from https://stackoverflow.com/questions/2559759/how-do-i-convert-camelcase-into-human-readable-names-in-java

$\endgroup$
4
$\begingroup$
splitCamelCase = ToLowerCase @ 
   StringInsert[#, " ", StringPosition[#, _?UpperCaseQ][[2;;, 1]]] &;

splitCamelCase @ "CompactSubspaceOfHausdorffSpaceIsClosed"
"compact subspace of hausdorff space is closed"
$\endgroup$
2
  • $\begingroup$ This won't work correctly with acronyms inside of the string. But has the advantage of supporting languages other than English. $\endgroup$ Sep 2, 2021 at 10:49
  • 1
    $\begingroup$ Of course the proper noun "Hausdorff" should not be lower-cased, but that's a semantic issue rather than a syntactical issue that could only be addressed by some kind of dictionary look-up to identify proper nouns (and even that can be ambiguous). $\endgroup$
    – murray
    Sep 3, 2021 at 13:39
3
$\begingroup$

Use a Regular Expression with a positive look-behind to insert a space before each capital letter that is preceded by either a lower-case letter or a digit (that is, insert a space before each capital letter except the first)

StringReplace[str, RegularExpression["(?<=[a-z1-9])([A-Z])"]:> " $1" ] // ToLowerCase

    (*compact subspace of hausdorff space is closed*)

If str begins with a space, or contains digits:

str2="  Compact1Subspace2OfHausdorffSpace3IsClosed"
StringReplace[str2, RegularExpression["(?<=[a-z1-9])([A-Z])"]:> " $1" ]//ToLowerCase

(*  compact1 subspace2 of hausdorff space3 is closed*)
$\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.