3

I have a string filled something like this -

".... . -.--   .--- ..- -.. ."

I need to split it to substrings, but a space in the middle must be written to string array too.

public static string Decode(string morseCode)
{  
    string[] words = morseCode.Split(new char[] { ' ' });

    ...
}    

I expect :

words[0] = "...."; 
words[1] = "."; 
words[2] = "-.--"; 
words[3] = " ";     // <- Space in the middle should be preserved
words[4] = ".---";
...
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
Roomey
  • 716
  • 2
  • 9
  • 16
  • You probably have fixed width data and have to split on column index instead of splitting on spaces, or you have tab delimited data and have to split on the tab instead of a space. – jdweng Aug 05 '19 at 09:17
  • Possible duplicate of [Split a string with delimiters but keep the delimiters in the result in C#](https://stackoverflow.com/questions/4680128/split-a-string-with-delimiters-but-keep-the-delimiters-in-the-result-in-c-sharp) – Owen Pauling Aug 05 '19 at 09:20
  • @OwenPauling that doesn't seem like a real duplicate. OP here does not want to keep all the delimiters. Only the one that has both meanings: as a delimiter and as a symbol – Mong Zhu Aug 05 '19 at 09:27

2 Answers2

3

You can try regular expressions in order to match required chunks:

using System.Linq;
using System.Text.RegularExpressions;

public static string Decode(string morseCode) {
  string[] words = Regex.Matches(morseCode, @"(?<=^|\s).+?(?=$|\s)")
    .Cast<Match>()
    .Select(match => match.Value.All(c => char.IsWhiteSpace(c)) 
       ? match.Value 
       : match.Value.Trim())
    .ToArray();

  //Relevant code here
}

Demo:

  using System.Linq;
  using System.Text.RegularExpressions;

  ...

  string morseCode = ".... . -.--   .--- ..- -.. .";

  string[] words = Regex.Matches(morseCode, @"(?<=^|\s).+?(?=$|\s)")
    .Cast<Match>()
    .Select(match => match.Value.All(c => char.IsWhiteSpace(c)) 
       ? match.Value 
       : match.Value.Trim())
    .ToArray();

  string report = string.Join(Environment.NewLine, words
    .Select((word, i) => $"words[{i}] = \"{word}\""));

  Console.Write(report);

Outcome:

words[0] = "...."
words[1] = "."
words[2] = "-.--"
words[3] = " "
words[4] = ".---"
words[5] = "..-"
words[6] = "-.."
words[7] = "."
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • Thanks for helping! I have an error: The name 'match' does not exist in the current context. How i understand, i need to initialize it, how should i do it correctly? – Roomey Aug 05 '19 at 10:02
  • 1
    @Roomey: I'm sorry for the typo; it should be lambda `.Select(match => match.Value...` (please, see my edit) – Dmitry Bychenko Aug 05 '19 at 10:08
0

Try below also. It is with Regex itself.

string code = ".... . -.--   .--- ..- -.. .";
    code = Regex.Replace(code, @"(\s{2})", " ").ToString();
    string[] codes = code.Split(' ');
    for (int i=0; i<codes.Length;i++){
    Console.WriteLine(i + " - "+codes[i]);
    }

The output is as below

0 - ....
1 - .
2 - -.--
3 - 
4 - .---
5 - ..-
6 - -..
7 - .

I just replaced all consecutive spaces (>=2) with one space and than split the string. Hope this will help.

DhavalR
  • 1,409
  • 3
  • 29
  • 57
  • 1
    Your idea a bit generalized: `code = Regex.Replace(code, @"\s{2,}", m => new string(' ', m.Value.Length == 2 ? 1 : 2));` (if we have 2 spaces we treat them as 1, if 2+ spaces - as 2) – Dmitry Bychenko Aug 05 '19 at 09:34