18

I have a string of the form:

codename123

Is there a regular expression that can be used with Regex.Split() to split the alphabetic part and the numeric part into a two-element string array?

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501

8 Answers8

50

I know you asked for the Split method, but as an alternative you could use named capturing groups:

var numAlpha = new Regex("(?<Alpha>[a-zA-Z]*)(?<Numeric>[0-9]*)");
var match = numAlpha.Match("codename123");

var alpha = match.Groups["Alpha"].Value;
var num = match.Groups["Numeric"].Value;
Josh
  • 44,706
  • 7
  • 102
  • 124
  • +1 I remember ever seeing one of such implementations for parsing INI files and I honestly thought it's very wonderful. – Alex Essilfie Sep 15 '10 at 17:22
  • Using named capturing groups sure beats doing `array[0]`, but that is just me :) – Josh Sep 15 '10 at 17:29
  • 1
    If the alphabetic part and the numeric part are both *required* to be present, the regex expression is incorrect. It should be `(?[a-zA-Z]+)(?[0-9]+)` – Chris Apr 30 '13 at 20:30
  • Would this work for a string like this? "1/0ACSR" so it comes out with "1/0" and "ACSR" ? – Josh P Feb 26 '15 at 15:01
  • 2
    Answered my own question: var numAlpha = new Regex("(?[0-9]*/*[0-9]*)(?[a-zA-Z]*)"); – Josh P Feb 26 '15 at 15:11
  • I completely copy pasted your code. but `alpha` stays `NULL` when I match the regex with "69DD", while `num` gets filled with 69. could somebody explain to me why this happens? – FllnAngl May 15 '19 at 10:30
  • 2
    @FllnAngl - This expression is order dependent. `Alpha` comes before `Numeric` – Josh Jun 20 '19 at 14:44
10
splitArray = Regex.Split("codename123", @"(?<=\p{L})(?=\p{N})");

will split between a Unicode letter and a Unicode digit.

Tim Pietzcker
  • 328,213
  • 58
  • 503
  • 561
5

Regex is a little heavy handed for this, if your string is always of that form. You could use

"codename123".IndexOfAny(new char[] {'1','2','3','4','5','6','7','8','9','0'})

and two calls to Substring.

Bob
  • 3,301
  • 1
  • 16
  • 11
4

A little verbose, but

Regex.Split( "codename123", @"(?<=[a-zA-Z])(?=\d)" );

Can you be more specific about your requirements? Maybe a few other input examples.

harpo
  • 41,820
  • 13
  • 96
  • 131
4

IMO, it would be a lot easier to find matches, like:

Regex.Matches("codename123", @"[a-zA-Z]+|\d+")
     .Cast<Match>()
     .Select(m => m.Value)
     .ToArray();

rather than to use Regex.Split.

Ani
  • 111,048
  • 26
  • 262
  • 307
1

Well, is a one-line only: Regex.Split("codename123", "^([a-z]+)");

atejeda
  • 3,705
  • 1
  • 18
  • 11
0

Another simpler way is

string originalstring = "codename123";
string alphabets = string.empty;
string numbers = string.empty;

foreach (char item in mainstring)
{
   if (Char.IsLetter(item))
   alphabets += item;
   if (Char.IsNumber(item))
   numbers += item;
}
N Khan
  • 366
  • 1
  • 6
  • 15
  • Probably an old question but that is what the regular expression do under the hood, although in an efficient and optimized way – KMarto Oct 06 '17 at 08:57
0

this code is written in java/logic should be same elsewhere

public String splitStringAndNumber(String string) {
    String pattern = "(?<Alpha>[a-zA-Z]*)(?<Numeric>[0-9]*)";

    Pattern p = Pattern.compile(pattern);
    Matcher m = p.matcher(string);
    if (m.find()) {
        return (m.group(1) + " " + m.group(2));
    }
    return "";
}
Mohit Singh
  • 5,977
  • 2
  • 24
  • 25