2

I want to split a string to an array of sub-strings. The string is delimited by space, but space may appear inside the sub-strings too. And spliced strings must be of the same length.

Example:

"a b aab bb  aaa" -> "a b", "aab", "bb ", "aaa"

I have the following code:

var T = Regex.Split(S, @"(?<=\G.{4})").Select(x => x.Substring(0, 3));

But I need to parameterize this code, split by various length(3, 4, 5 or n) and I don't know how do this. Please help.

If impossible to parameterize Regex, fully linq version ok.

2
  • 2
    Are you going to automatically detect the length of the sub-strings? Commented Sep 13, 2015 at 11:22
  • No, length is stored in variable. Commented Sep 13, 2015 at 11:50

3 Answers 3

2

You can use the same regex, but "parameterize" it by inserting the desired number into the string.

In C# 6.0, you can do it like this:

var n = 5;
var T = Regex.Split(S, $@"(?<=\G.{{{n}}})").Select(x => x.Substring(0, n-1));

Prior to that you could use string.Format:

var n = 5;
var regex = string.Format(@"(?<=\G.{{{0}}})", n);
var T = Regex.Split(S, regex).Select(x => x.Substring(0, n-1));
Sign up to request clarification or add additional context in comments.

6 Comments

Life is easier with string interpolation.
Shouldn't you change the parameter of Substring function?
@RichardSchneider Yes, this is easily my most favorite addition to the language.
@RichardSchneider On the other hand, it is horrible if you want to localize interpolated strings, once you replaced string.Format with this neat $ thing.
@UweKeim I strongly doubt that interpolated strings were intended for localization. It's great for things where the string does not get presented to end-users - e.g. diagnostics, SQL generation from metadata, and so on.
|
1

It seems rather easy with LINQ:

var source = "a b aab bb  aaa";

var results =
    Enumerable
        .Range(0, source.Length / 4 + 1)
        .Select(n => source.Substring(n * 4, 3))
        .ToList();

Or using Microsoft's Reactive Framework's team's Interactive Extensions (NuGet "Ix-Main") and do this:

var results =
    source
        .Buffer(3, 4)
        .Select(x => new string(x.ToArray()))
        .ToList();

Both give you the output you require.

1 Comment

Thanks, this code works for me, var results = Enumerable .Range(0, (source.Length / (n + 1)) + 1) .Select(x => source.Substring(x * n, n - 1)) .ToArray();
1

A lookbehind (?<=pattern) matches a zero-length string. To split using spaces as delimiters, the match has to actually return a "" (the space has to be in the main pattern, outside the lookbehind).

Regex for length = 3: @"(?<=\G.{3}) " (note the trailing space)

Code for length n:

var n = 3;
var S = "a b aab bb  aaa";
var regex = @"(?<=\G.{" + n + @"}) ";
var T = Regex.Split(S, regex);

Run this code online

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.