Cfaniak
Cfaniak

Reputation: 409

substring at first alphanumeric char

I'm looking for a fast method to split string into two after first alphanumeric character.

I know I could make foreach character in string and check if it is numeric or alphanumeric, but I dont know if it is fast.

For example I have a string "25I10"

I need to split it to 25 and I10 (I cant substring it 0,2 because the first number can be smaller or bigger. I have to split it on the first AlphaNumeric character as this is where the command starts.

It needs to be fast because I'm getting a lot commands on telnet and I dont want to slow it down.

Yes, I know I could send string to another thread and than split it, but I dont want to create a lot threads for such thing.

Does anyone know the best option?

Upvotes: 1

Views: 5100

Answers (3)

MRM
MRM

Reputation: 435

string str = "10|25";
string[] strArray = System.Text.RegularExpressions.Regex.Split(str, @"(\D.*$)");

it give you array with length 3, the first and second element are the strings that you want and the last element always be "".

Upvotes: 0

kol
kol

Reputation: 28698

Here is a compilable code, which uses Regex:

using System;
using System.Text.RegularExpressions;

public static class Splitter
{
  private static Regex regex;

  static Splitter()
  {
    string separator = "[a-zA-Z]";
    string notSeparator = "[^a-zA-Z]";
    string pattern = "^(?<left>" + notSeparator + "+)(?<right>" + separator + ".*)$";
    regex = new Regex(pattern, RegexOptions.Compiled | RegexOptions.ExplicitCapture);
  }

  public static bool Split(string input, out string left, out string right)
  {
    var match = regex.Match(input);
    if (match.Success && match.Groups["left"].Captures.Count == 1 && match.Groups["right"].Captures.Count == 1)
    {
      left = match.Groups["left"].Captures[0].Value;
      right = match.Groups["right"].Captures[0].Value;
      return true;
    }
    else
    {
      left = null;
      right = null;
      return false;
    }
  }
}

public static class Program
{
  public static void Test(string input)
  {
    string left, right;
    if (Splitter.Split(input, out left, out right))
      Console.WriteLine("\"" + input + "\" -> \"" + left + "\" + \"" + right + "\"");
    else
      Console.WriteLine("The string \"" + input + "\" could not be split");
  }

  public static void Main()
  {
    Test("2510");
    Test("2510I");
    Test("I2510");
    Test("25I10");
  }
}

Output:

The string "2510" could not be split
"2510I" -> "2510" + "I"
The string "I2510" could not be split
"25I10" -> "25" + "I10"

Upvotes: 1

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112437

int pos = Regex.Match("123abc456", "[a-z]").Index;

You can also test if you have a match:

Match m = Regex.Match("123abc456", "[a-z]");
int pos = -1;
if (m.Success) {
    pos = m.Index;
}

The pattern \p{L} instead of [a-z] will also match accented letters from non-english languages.

Also you can split directly with Regex:

string[] parts = Regex.Split("123X456", @"\p{L}");

Upvotes: 3

Related Questions