Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

This seems like it should be trivial, but how do I partition a string into length n substrings? I can of course write something like

chunk[s_, n_] := StringJoin[#] & /@ Partition[Characters[s], n]

so that chunk["ABCDEF",2] -> {"AB","CD","EF"} but this appears unnecessarily cumbersome.

share|improve this question
Welcome to Mathematica.SE! This is a good question, as there doesn't seem to be a direct built-in way (I bumped into this before). Please consider filling out the name field in your profile, so it will show as something easier to remember than 'user1268' – Szabolcs May 17 '12 at 9:19
Link to MathGroup version. – Szabolcs May 17 '12 at 10:22
Note StringJoin[#] & is the same as just StringJoin. – amr Oct 3 '12 at 19:59
up vote 23 down vote accepted

Try this:

StringCases["ABCDEFGHIJK", LetterCharacter ~~ LetterCharacter]

{"AB", "CD", "EF", "GH", "IJ"}

or for more general cases (i.e. not just for letters, but any characters, and for any partition size):

stringPartition1[s_String, n_Integer] := StringCases[s, StringExpression @@ Table[_, {n}]];

It is more elegant though to use Repeated (thanks rcollyer):

stringPartition2[s_String, n_Integer] := StringCases[s, Repeated[_, {n}]];

stringPartition2["longteststring", 4]

{"long", "test", "stri"}

share|improve this answer
Instead of Table[_,{n}], I'd consider using Repeated[_, {n}], instead. – rcollyer May 17 '12 at 1:34
Thanks @rcollyer, I felt I missed something, but it was too late. Incorporated now. – István Zachar May 17 '12 at 9:50

I wanted a solution using StringSplit[]

chunk[s_, n_] := StringSplit[s, RegularExpression["(.{" <> ToString@n <> "})"] -> "$1"]
                                                                     ~ DeleteCases ~ ""
share|improve this answer
Cleaner, IMO: StringSplit[s, x : Repeated[_, {n}] :> x][[;; ;; 2]]. I don't see an advantage over StringCases however. – Mr.Wizard May 4 '14 at 11:05
@Mr.Wizard No advantage. I just wanted a way to use StringSplit[] as said. But I'm too old to remember why I wanted that. – Dr. belisarius May 5 '14 at 3:49

Not completely original, but very compact.

chunk[s_, n_] := StringJoin@@@Partition[Characters[s], n, n, 1, {}]

Update for V10.1

This new function is exactly for that:


{"AB", "CD", "EF"}

share|improve this answer

This will give better performance (3 times faster in my test, partitioning into length-two strings) than your original code:

chunk[s_, n_] := FromCharacterCode@Partition[ToCharacterCode[s], n]

The reason is that the first few steps of the computation are done with packed arrays.

It will still be slower than the regex-based approaches (István's and Jens's), on my machine by a factor of 2.

The StringTake approach is much slower than all the others in my machine.


Function definitions:

(* original *)
chunk1[s_, n_] := StringJoin[#] & /@ Partition[Characters[s], n]

(* István *)
chunk2[s_, n_] := StringCases[s, Repeated[_, {n}]]

(* Jens *)
chunk3[s_, n_] := StringCases[s, RegularExpression[".{1," <> ToString[n] <> "}"]]

(* TomD *)
chunk4 = StringTake[#, Partition[Range@StringLength@#, #2, #2, 1, {}]] &;

(* mine *)
chunk5[s_, n_] := FromCharacterCode@Partition[ToCharacterCode[s], n]

text = ExampleData[{"Text", "Hamlet"}];
testString = StringJoin[ConstantArray[text, 20]];

StringLength[testString] (* 3438740 *)


(* original *)
In[10]:= Timing[chunk1[testString, 2];]
         Timing[chunk1[testString, 100];]

Out[10]= {5.968, Null}
Out[11]= {1.703, Null}

(* István - fastest *)
In[12]:= Timing[chunk2[testString, 2];]
         Timing[chunk2[testString, 100];]

Out[12]={1.25, Null}
Out[13]={0.11, Null}

(* Jens - fastest *)
In[14]:= Timing[chunk3[testString, 2];]
         Timing[chunk3[testString, 100];]

Out[14]= {1.313, Null}
Out[15]= {0.125, Null}

(* TomD *)
In[16]:= Timing[chunk4[testString, 2];]
         Timing[chunk4[testString, 100];]

(* More than a few minutes. Didn't wait for it to finish ... *)

(* mine *)
In[18]:= Timing[chunk5[testString, 2];]
         Timing[chunk5[testString, 100];]

Out[18]= {2.25, Null}
Out[19]= {0.266, Null}

Conclusion: use regex-based methods. The built-in string patterns also use a regex library internally, I believe, but they are easier to construct programmatically because they are represented as expressions.

share|improve this answer
Scrollbar ate your timing results... First I thought it was so lightning fast you did not bother to write it out in numbers :) – István Zachar May 17 '12 at 9:54
Thanks, Szabolcs, and everyone who answered. As ever, more than one way to skin a cat with Mathematica. I'm a bit surprised that there isn't a StringPartition function taking the same arguments as Partition as a built-in, analogous to StringTake vs. Take. – David G May 17 '12 at 13:23
Your code can be further sped up by using Developer`PartitionMap to apply FromCharacterCode to each term in the list. This does not unpack the list. The speed up is marginal, though, on my machine 1.25793 -> 1.12617 and 0.135588 -> 0.095252. So, still not a contender for the fastest method. – rcollyer May 17 '12 at 16:38
@rcollyer Good point! I never used Developer`PartitionMap before. (I've seen it in the docs, but I didn't realize its significance: not unpacking.) – Szabolcs May 17 '12 at 16:40
@rcollyer I solved the 'mystery': it was auto-compilation. It avoids unpacking only if the list is above the auto-compilation length. – Szabolcs May 17 '12 at 17:08

Another possibility:

   Partition[Range@StringLength@#, 2, 2, 1, {}]] &@"abcdefghi"


(*  {"ab", "cd", "ef", "gh", "i"} *)
share|improve this answer

Here is the regular-expression way:

chunk[s_, n_] := 
 StringCases[s, RegularExpression[".{1," <> ToString[n] <> "}"]]

chunk["Hello this is a test string", 2]

{"He", "ll", "o ", "th", "is", " i", "s ", "a ", "te", "st", " s", "tr", "in", "g"}

chunk["Hello this is a test string", 4]

{"Hell", "o th", "is i", "s a ", "test", " str", "ing"}

Note that the last substrings didn't fit the chunk size but were still included.

If you don't want to include them, change the regular expression from ".{1," <> ToString[n] <> "}" to ".{" <> ToString[n] <> "}".

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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