<p>How do you sort an array of strings <a href="http://blog.codinghorror.com/sorting-for-humans-natural-sort-order/" rel="nofollow noreferrer">naturally</a> in different programming languages? Post your implementation and what language it is in in the answer.</p>

[{'answer_id': 34528, 'author': 'Marius', 'author_id': 1585, 'author_profile': 'https://Stackoverflow.com/users/1585', 'pm_score': 3, 'selected': False, 'text': '<p><strong>JavaScript</strong></p>\n\n<pre><code>Array.prototype.alphanumSort = function(caseInsensitive) {\n  for (var z = 0, t; t = this[z]; z++) {\n    this[z] = [], x = 0, y = -1, n = 0, i, j;\n\n    while (i = (j = t.charAt(x++)).charCodeAt(0)) {\n      var m = (i == 46 || (i &gt;=48 &amp;&amp; i &lt;= 57));\n      if (m !== n) {\n        this[z][++y] = "";\n        n = m;\n      }\n      this[z][y] += j;\n    }\n  }\n\n  this.sort(function(a, b) {\n    for (var x = 0, aa, bb; (aa = a[x]) &amp;&amp; (bb = b[x]); x++) {\n      if (caseInsensitive) {\n        aa = aa.toLowerCase();\n        bb = bb.toLowerCase();\n      }\n      if (aa !== bb) {\n        var c = Number(aa), d = Number(bb);\n        if (c == aa &amp;&amp; d == bb) {\n          return c - d;\n        } else return (aa &gt; bb) ? 1 : -1;\n      }\n    }\n    return a.length - b.length;\n  });\n\n  for (var z = 0; z &lt; this.length; z++)\n    this[z] = this[z].join("");\n}\n</code></pre>\n\n<p><a href="http://my.opera.com/GreyWyvern/blog/show.dml/1671288" rel="noreferrer">Source</a></p>\n'}, {'answer_id': 34542, 'author': 'Rytis', 'author_id': 979, 'author_profile': 'https://Stackoverflow.com/users/979', 'pm_score': 3, 'selected': False, 'text': '<p>For MySQL, I personally use code from a Drupal module, which is available at hhttp://drupalcode.org/project/natsort.git/blob/refs/heads/5.x-1.x:/natsort.install.mysql</p>\n\n<p>Basically, you execute the posted SQL script to create functions, and then use <code>ORDER BY natsort_canon(field_name, \'natural\')</code></p>\n\n<p>Here\'s a readme about the function:\n<a href="http://drupalcode.org/project/natsort.git/blob/refs/heads/5.x-1.x:/README.txt" rel="nofollow noreferrer">http://drupalcode.org/project/natsort.git/blob/refs/heads/5.x-1.x:/README.txt</a></p>\n'}, {'answer_id': 34780, 'author': 'dmckee --- ex-moderator kitten', 'author_id': 2509, 'author_profile': 'https://Stackoverflow.com/users/2509', 'pm_score': 2, 'selected': False, 'text': '<p>If the OP is asking about idomatic sorting expressions, then not all languages have a <em>natural</em> expression built in. For c I\'d go to <code>&lt;stdlib.h&gt;</code> and use <code>qsort</code>. Something on the lines of :</p>\n\n<pre><code>/* non-functional mess deleted */\n</code></pre>\n\n<p>to sort the arguments into lexical order. Unfortunately this idiom is rather hard to parse for those not used the ways of c.</p>\n\n<hr>\n\n<p><em>Suitably chastened by the downvote, I actually read the linked article. Mea culpa.</em></p>\n\n<p>In anycase the original code did not work, except in the single case I tested. Damn. Plain vanilla c does not have this function, nor is it in any of the usual libraries. </p>\n\n<p>The code below sorts the command line arguments in the <strong>natural</strong> way as linked. <em>Caveat emptor</em> as it is only lightly tested.</p>\n\n<pre><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;string.h&gt;\n#include &lt;ctype.h&gt;\n\nint naturalstrcmp(const char **s1, const char **s2);\n\nint main(int argc, char **argv){\n  /* Sort the command line arguments in place */\n  qsort(&amp;argv[1],argc-1,sizeof(char*),\n    (int(*)(const void *, const void *))naturalstrcmp);\n\n  while(--argc){\n    printf("%s\\n",(++argv)[0]);\n  };\n}\n\nint naturalstrcmp(const char **s1p, const char **s2p){\n  if ((NULL == s1p) || (NULL == *s1p)) {\n    if ((NULL == s2p) || (NULL == *s2p)) return 0;\n    return 1;\n  };\n  if ((NULL == s2p) || (NULL == *s2p)) return -1;\n\n  const char *s1=*s1p;\n  const char *s2=*s2p;\n\n  do {\n    if (isdigit(s1[0]) &amp;&amp; isdigit(s2[0])){ \n      /* Compare numbers as numbers */\n      int c1 = strspn(s1,"0123456789"); /* Could be more efficient here... */\n      int c2 = strspn(s2,"0123456789");\n      if (c1 &gt; c2) {\n    return 1;\n      } else if (c1 &lt; c2) {\n    return -1;\n      };\n      /* the digit strings have equal length, so compare digit by digit */\n      while (c1--) {\n    if (s1[0] &gt; s2[0]){\n      return 1;\n    } else if (s1[0] &lt; s2[0]){\n      return -1;\n    }; \n    s1++;\n    s2++;\n      };\n    } else if (s1[0] &gt; s2[0]){\n      return 1;\n    } else if (s1[0] &lt; s2[0]){\n      return -1;\n    }; \n    s1++;\n    s2++;\n  } while ( (s1!=\'\\0\') || (s2!=\'\\0\') );\n  return 0;\n}\n</code></pre>\n\n<p>This approach is pretty brute force, but it is simple and can probably be duplicated in any imperative language.</p>\n'}, {'answer_id': 35969, 'author': 'Jeremy', 'author_id': 3657, 'author_profile': 'https://Stackoverflow.com/users/3657', 'pm_score': 2, 'selected': False, 'text': '<p>In C++ I use this <a href="http://web.archive.org/web/20071217040157/http://www.boostcookbook.com/Recipe:/1235053" rel="nofollow noreferrer">example code</a> to do natural sorting.  The code requires the boost library.</p>\n'}, {'answer_id': 341599, 'author': 'Eclipse', 'author_id': 8701, 'author_profile': 'https://Stackoverflow.com/users/8701', 'pm_score': 2, 'selected': False, 'text': '<p>I just use <a href="http://msdn.microsoft.com/en-us/library/bb759947.aspx" rel="nofollow noreferrer">StrCmpLogicalW</a>.  It does exactly what Jeff is wanting, since it\'s the same API that explorer uses.  Admittedly, it\'s not portable.</p>\n\n<p>In C++:</p>\n\n<pre><code>bool NaturalLess(const wstring &amp;lhs, const wstring &amp;rhs)\n{\n    return StrCmpLogicalW(lhs.c_str(), rhs.c_str()) &lt; 0;\n}\n\nvector&lt;wstring&gt; strings;\n// ... load the strings\nsort(strings.begin(), strings.end(), &amp;NaturalLess);\n</code></pre>\n'}, {'answer_id': 341730, 'author': 'Darius Bacon', 'author_id': 27024, 'author_profile': 'https://Stackoverflow.com/users/27024', 'pm_score': 3, 'selected': False, 'text': '<p>Here\'s a cleanup of <a href="http://nedbatchelder.com/blog/200712.html#e20071211T054956" rel="nofollow noreferrer">the code</a> in <a href="https://blog.codinghorror.com/sorting-for-humans-natural-sort-order/" rel="nofollow noreferrer">the article</a> the question linked to:</p>\n\n<pre><code>def sorted_nicely(strings): \n    "Sort strings the way humans are said to expect."\n    return sorted(strings, key=natural_sort_key)\n\ndef natural_sort_key(key):\n    import re\n    return [int(t) if t.isdigit() else t for t in re.split(r\'(\\d+)\', key)]\n</code></pre>\n\n<p>But actually I haven\'t had occasion to sort anything this way.</p>\n'}, {'answer_id': 341745, 'author': 'jfs', 'author_id': 4279, 'author_profile': 'https://Stackoverflow.com/users/4279', 'pm_score': 3, 'selected': False, 'text': '<p>Here\'s how you can get explorer-like behaviour in Python:</p>\n\n\n\n<pre class="lang-py prettyprint-override"><code>#!/usr/bin/env python\n"""\n&gt;&gt;&gt; items = u\'a1 a003 b2 a2 a10 1 10 20 2 c100\'.split()\n&gt;&gt;&gt; items.sort(explorer_cmp)\n&gt;&gt;&gt; for s in items:\n...     print s,\n1 2 10 20 a1 a2 a003 a10 b2 c100\n&gt;&gt;&gt; items.sort(key=natural_key, reverse=True)\n&gt;&gt;&gt; for s in items:\n...     print s,\nc100 b2 a10 a003 a2 a1 20 10 2 1\n"""\nimport re\n\ndef natural_key(astr):\n    """See http://www.codinghorror.com/blog/archives/001018.html"""\n    return [int(s) if s.isdigit() else s for s in re.split(r\'(\\d+)\', astr)]\n\ndef natural_cmp(a, b):\n    return cmp(natural_key(a), natural_key(b))\n\ntry: # use explorer\'s comparison function if available\n    import ctypes\n    explorer_cmp = ctypes.windll.shlwapi.StrCmpLogicalW\nexcept (ImportError, AttributeError):\n    # not on Windows or old python version\n    explorer_cmp = natural_cmp        \n\nif __name__ == \'__main__\':\n    import doctest; doctest.testmod()\n</code></pre>\n\n<p>To support Unicode strings, <code>.isdecimal()</code> should be used instead of <code>.isdigit()</code>.</p>\n\n<p><code>.isdigit()</code> may also fail (return value that is not accepted by <code>int()</code>) for a bytestring on Python 2 in some locales e.g., <a href="https://stackoverflow.com/a/19440958/4279">\'\\xb2\' (\'²\') in cp1252 locale on Windows</a>.</p>\n'}, {'answer_id': 348036, 'author': 'Svante', 'author_id': 31615, 'author_profile': 'https://Stackoverflow.com/users/31615', 'pm_score': 2, 'selected': False, 'text': '<p>Just a link to some nice work in Common Lisp by Eric Normand:</p>\n\n<p><a href="http://www.lispcast.com/wordpress/2007/12/human-order-sorting/" rel="nofollow noreferrer">http://www.lispcast.com/wordpress/2007/12/human-order-sorting/</a></p>\n'}, {'answer_id': 753548, 'author': 'RHSeeger', 'author_id': 26816, 'author_profile': 'https://Stackoverflow.com/users/26816', 'pm_score': 0, 'selected': False, 'text': '<p>For Tcl, the -dict (dictionary) option to lsort:</p>\n\n<pre><code>% lsort -dict {a b 1 c 2 d 13}\n1 2 13 a b c d\n</code></pre>\n'}, {'answer_id': 753739, 'author': 'T.E.D.', 'author_id': 29639, 'author_profile': 'https://Stackoverflow.com/users/29639', 'pm_score': 1, 'selected': False, 'text': '<p>Note that for most such questions, you can just consult the <a href="http://www.rosettacode.org/wiki/Main_Page" rel="nofollow noreferrer">Rosetta Code Wiki</a>. I adapted my answer from the entry for sorting integers.</p>\n\n<p>In a system\'s programming language doing something like this is generally going to be uglier than with a specialzed string-handling language. Fortunately for Ada, the most recent version has a library routine for just this kind of task.</p>\n\n<p>For Ada 2005 I believe you could do something along the following lines (warning, not compiled!):</p>\n\n<pre><code>type String_Array is array(Natural range &lt;&gt;) of Ada.Strings.Unbounded.Unbounded_String;\nfunction "&lt;" (L, R : Ada.Strings.Unbounded.Unbounded_String) return boolean is\nbegin\n   --// Natural ordering predicate here. Sorry to cheat in this part, but\n   --// I don\'t exactly grok the requirement for "natural" ordering. Fill in \n   --// your proper code here.\nend "&lt;";\nprocedure Sort is new Ada.Containers.Generic_Array_Sort \n  (Index_Type   =&gt; Natural;\n   Element_Type =&gt; Ada.Strings.Unbounded.Unbounded_String,\n   Array_Type   =&gt; String_Array\n  );\n</code></pre>\n\n<p>Example use:</p>\n\n<pre><code>    using Ada.Strings.Unbounded;\n\n    Example : String_Array := (To_Unbounded_String ("Joe"),\n                               To_Unbounded_String ("Jim"),\n                               To_Unbounded_String ("Jane"),\n                               To_Unbounded_String ("Fred"),\n                               To_Unbounded_String ("Bertha"),\n                               To_Unbounded_String ("Joesphus"),\n                               To_Unbounded_String ("Jonesey"));\nbegin\n    Sort (Example);\n    ...\nend;\n</code></pre>\n'}, {'answer_id': 1344071, 'author': 'Norman Ramsey', 'author_id': 41661, 'author_profile': 'https://Stackoverflow.com/users/41661', 'pm_score': 2, 'selected': False, 'text': "<p>In C, this solution correctly handles numbers with leading zeroes:</p>\n\n<pre><code>#include &lt;stdlib.h&gt;\n#include &lt;ctype.h&gt;\n\n/* like strcmp but compare sequences of digits numerically */\nint strcmpbynum(const char *s1, const char *s2) {\n  for (;;) {\n    if (*s2 == '\\0')\n      return *s1 != '\\0';\n    else if (*s1 == '\\0')\n      return 1;\n    else if (!(isdigit(*s1) &amp;&amp; isdigit(*s2))) {\n      if (*s1 != *s2)\n        return (int)*s1 - (int)*s2;\n      else\n        (++s1, ++s2);\n    } else {\n      char *lim1, *lim2;\n      unsigned long n1 = strtoul(s1, &amp;lim1, 10);\n      unsigned long n2 = strtoul(s2, &amp;lim2, 10);\n      if (n1 &gt; n2)\n        return 1;\n      else if (n1 &lt; n2)\n        return -1;\n      s1 = lim1;\n      s2 = lim2;\n    }\n  }\n}\n</code></pre>\n\n<p>If you want to use it with <code>qsort</code>, use this auxiliary function:</p>\n\n<pre><code>static int compare(const void *p1, const void *p2) {\n  const char * const *ps1 = p1;\n  const char * const *ps2 = p2;\n  return strcmpbynum(*ps1, *ps2);\n}\n</code></pre>\n\n<p>And you can do something on the order of</p>\n\n<pre><code>char *lines = ...;\nqsort(lines, next, sizeof(lines[0]), compare);\n</code></pre>\n"}, {'answer_id': 4001057, 'author': 'adw', 'author_id': 484688, 'author_profile': 'https://Stackoverflow.com/users/484688', 'pm_score': 1, 'selected': False, 'text': "<p>Python, using itertools:</p>\n\n<pre><code>def natural_key(s):\n    return tuple(\n        int(''.join(chars)) if isdigit else ''.join(chars)\n        for isdigit, chars in itertools.groupby(s, str.isdigit)\n    )\n</code></pre>\n\n<p>Result:</p>\n\n<pre><code>&gt;&gt;&gt; natural_key('abc-123foo456.xyz')\n('abc-', 123, 'foo', 456, '.xyz')\n</code></pre>\n\n<p>Sorting:</p>\n\n<pre><code>&gt;&gt;&gt; sorted(['1.1.1', '1.10.4', '1.5.0', '42.1.0', '9', 'banana'], key=natural_key)\n['1.1.1', '1.5.0', '1.10.4', '9', '42.1.0', 'banana']\n</code></pre>\n"}, {'answer_id': 6924517, 'author': 'Thang Mai', 'author_id': 807672, 'author_profile': 'https://Stackoverflow.com/users/807672', 'pm_score': 1, 'selected': False, 'text': '<p>My implementation on Clojure 1.1:</p>\n\n<pre><code>(ns alphanumeric-sort\n  (:import [java.util.regex Pattern]))\n\n(defn comp-alpha-numerical\n  "Compare two strings alphanumerically."\n  [a b]\n  (let [regex (Pattern/compile "[\\\\d]+|[a-zA-Z]+")\n        sa (re-seq regex a)\n        sb (re-seq regex b)]\n    (loop [seqa sa seqb sb]\n      (let [counta (count seqa)\n            countb (count seqb)]\n        (if-not (not-any? zero? [counta countb]) (- counta countb)\n          (let [c (first seqa)\n                d (first seqb)\n                c1 (read-string c)\n                d1 (read-string d)]\n             (if (every? integer? [c1 d1]) \n               (def result (compare c1 d1)) (def result (compare c d)))\n             (if-not (= 0 result) result (recur (rest seqa) (rest seqb)))))))))\n\n(sort comp-alpha-numerical ["a1" "a003" "b2" "a10" "a2" "1" "10" "20" "2" "c100"])\n</code></pre>\n\n<p>Result:</p>\n\n<p>("1" "2" "10" "20" "a1" "a2" "a003" "a10" "b2" "c100")</p>\n'}, {'answer_id': 26478632, 'author': 'grant sun', 'author_id': 3509287, 'author_profile': 'https://Stackoverflow.com/users/3509287', 'pm_score': 0, 'selected': False, 'text': '<p>php has a easy function "natsort" to do that,and I implements it by myself:</p>\n\n<pre><code>&lt;?php\n$temp_files = array(\'+====\',\'-==\',"temp15-txt","temp10.txt",\n"temp1.txt","tempe22.txt","temp2.txt");\n$my_arr = $temp_files;\n\n\nnatsort($temp_files);\necho "Natural order: ";\nprint_r($temp_files);\n\n\necho "My Natural order: ";\nusort($my_arr,\'my_nat_func\');\nprint_r($my_arr);\n\n\nfunction is_alpha($a){\n    return $a&gt;=\'0\'&amp;&amp;$a&lt;=\'9\' ;\n}\n\nfunction my_nat_func($a,$b){\n    if(preg_match(\'/[0-9]/\',$a)){\n        if(preg_match(\'/[0-9]/\',$b)){\n            $i=0;\n            while(!is_alpha($a[$i]))    ++$i;\n            $m  = intval(substr($a,$i));            \n            $i=0;\n            while(!is_alpha($b[$i]))    ++$i;\n            $n  = intval(substr($b,$i));\n            return $m&gt;$n?1:($m==$n?0:-1);\n        }\n        return 1;\n    }else{\n        if(preg_match(\'/[0-9]/\',$b)){\n            return -1;\n        }\n        return $a&gt;$b?1:($a==$b?0:-1);\n    }\n}\n</code></pre>\n'}, {'answer_id': 71668742, 'author': 'vsk.rahul', 'author_id': 3116461, 'author_profile': 'https://Stackoverflow.com/users/3116461', 'pm_score': 0, 'selected': False, 'text': '<p><strong>Java solution:-</strong></p>\n<p>This can be achieved by implementing new <code>Comparator&lt;String&gt;</code> and pass it to <code>Collections.sort(list, comparator)</code> method.</p>\n<pre><code>@Override\npublic int compare(String s1, String s2) {\n    int len1 = s1.length();\n    int len2 = s2.length();\n    int lim = Math.min(len1, len2);\n    char v1[] = s1.toCharArray();\n    char v2[] = s2.toCharArray();\n\n    int k = 0;\n    while (k &lt; lim) {\n        char c1 = v1[k];\n        char c2 = v2[k];\n        if (c1 != c2) {\n            if(this.isInteger(c1) &amp;&amp; this.isInteger(c2)) {\n                int i1 = grabContinousInteger(v1, k);\n                int i2 = grabContinousInteger(v2, k);\n                return i1 - i2;\n            }\n            return c1 - c2;\n        }\n        k++;\n    }\n    return len1 - len2;\n}\n\nprivate boolean isInteger(char c) {\n    return c &gt;= 48 &amp;&amp; c &lt;= 57; // ascii value 0-9\n}\n\nprivate int grabContinousInteger(char[] arr, int k) {\n    \n    int i = k;\n    while(i &lt; arr.length &amp;&amp; this.isInteger(arr[i])) {\n        i++;\n    }\n    return Integer.parseInt(new String(arr, k, i - k));\n}\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/34518', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1585/']