using System.Diagnostics;
using System.Collections.Generic;
using System.Collections;
using System.Text.RegularExpressions;
var arr = new[] { "job0", "job1", "job11", "job2", "z0", "z1", "z11", "z2", "0", "1", "11", "111", "2", "21", "a0b11", "a0b111", "a0b2", "a0b20" };
var tmp = arr.Select(name => (orig: name, parts: GetParts(Regex.Match(name, @"^([a-zA-Z ]+)(?:(\d+)([a-zA-Z ]+))*(\d+)?$|^(\d+)(?:([a-zA-Z ]+)(\d+))*([a-zA-Z ]+)?$")))).ToList();
tmp.Sort(new AlphaNumericalComparer());
foreach(var item in tmp.Select(x => x.orig)) Console.Write(item + ", ");
static object GetObject(string s) => Regex.IsMatch(s, @"^\d+$") ? (object)Convert.ToInt32(s) : s;
static IEnumerable<object> GetParts(Match m) =>
char.IsDigit(m.Groups.Cast<Group>().Skip(1).First(m => m.Success).Value[0])
? Enumerable.Repeat((object)"", 1).Concat(m.Groups.Cast<Group>().Skip(1).Where(m => m.Success).Select(m => GetObject(m.Value)).ToList())
: m.Groups.Cast<Group>().Skip(1).Where(m => m.Success).Select(m => GetObject(m.Value)).ToList();
class AlphaNumericalComparer : IComparer<(string name, IEnumerable<object> parts)>
public int Compare((string name, IEnumerable<object> parts) left, (string name, IEnumerable<object> parts) right)
foreach(var lr in left.parts.Cast<IComparable>().Zip(right.parts.Cast<IComparable>()))
var cmp = lr.Item1.CompareTo(lr.Item2);