2012-06-24 6 views
0

{n}d {n}h {n}m {n}s으로 입력 할 수있는 문자열이 있습니다. {n}은 일, 시간, 분, 초를 나타내는 정수입니다. 이 {n} 숫자를 문자열에서 어떻게 추출합니까?문자열의 정수 부분을 구문 분석

사용자가 4-d, h, m, s를 모두 입력 할 필요는 없습니다. 그는 단지 4d를 입력 할 수 있었는데, 4d 또는 5h 2s는 5 시간 2 초를 의미합니다.

다음은 내가 가지고있는 것입니다. 분명히 이것을 할 수있는 더 좋은 방법이 있어야합니다. 또한 모든 경우를 다루지는 않습니다.

int d; int m; int h; int sec; 
string [] split = textBox3.Text.Split(new Char [] {' ', ','}); 
List<string> myCollection = new List<string>(); 

foreach (string s in split) 
{ 
    d = Convert.ToInt32(s.Substring(0,s.Length-1)); 
    h = Convert.ToInt32(split[1].Substring(1)); 
    m = Convert.ToInt32(split[2].Substring(1)); 
    sec = Convert.ToInt32(split[3].Substring(1)); 
} 
dt =new TimeSpan(h,m,s); 

답변

3

일, 시간, 분, 초 순서가 고정되어있는 경우에, 당신은 정규 표현식을 사용할 수 있습니다

string input = textBox3.Text.Trim(); 
Match match = Regex.Match(input, 
    "^" + 
    "((?<d>[0-9]+)d)? *" + 
    "((?<h>[0-9]+)h)? *" + 
    "((?<m>[0-9]+)m)? *" + 
    "((?<s>[0-9]+)s)?" + 
    "$", 
    RegexOptions.ExplicitCapture); 

if (match.Success) 
{ 
    int d, h, m, s; 
    Int32.TryParse(match.Groups["d"].Value, out d); 
    Int32.TryParse(match.Groups["h"].Value, out h); 
    Int32.TryParse(match.Groups["m"].Value, out m); 
    Int32.TryParse(match.Groups["s"].Value, out s); 
    // ... 
} 
else 
{ 
    // Invalid input. 
} 
+0

캡쳐되지 않은 그룹을 사용하지 않고'RegexOptions.ExplicitCapture'를 지정하면 잘됩니다 ... – Lucero

+0

@Lucero : 와우, 뭔가를 배웠습니다. 새로운! –

0

상태 기계를 사용하여 문자열의 각 부분이 정확히 무엇인지 확인하는 맞춤 구문 분석기를 작성하십시오.

아이디어는 문자열의 각 문자를 반복하고 상태에 따라 상태를 변경하는 것입니다. 그래서, 당신은 Number 상태 Day, Month, Hour, Seconds 상태, SpaceStartEnd 상태를 가질 것입니다.

0

하나의 방법은 sscanf()을 사용하는 것일 수 있습니다. 이는 매우 쉽게 수행 할 수 있습니다. C#에서 this article에이 함수 버전을 구현했습니다.

잠재적 인 구문 오류를보다 잘 처리해야하는 경우에는 자체 구문 분석기를 구현하는 것이 좋습니다. 각 캐릭터를 하나 하나씩 검사하면됩니다.

+0

'sscanf' in C#? – Oded

+0

죄송합니다. 혼란 스럽지만 C#에 대한 답을 반올림했습니다. –

+0

'C'로 시작하는 C 스타일의 언어가 충분하지 않다고 생각합니다.) – Oded

0

다양한 옵션이 있습니다. TimeSpan.TryParse 함수를 사용하려고 시도 할 수도 있지만 다른 입력 형식이 필요합니다. 또 다른 방법은 문자열을 공백으로 분리하고 각 부분을 반복하는 것입니다. 이렇게하는 동안 부품에 d, h, s 등이 있는지 확인하고 값을 원하는 변수에 추출 할 수 있습니다. RegEx를 사용하여 문자열을 파싱 할 수도 있습니다. 여기에 예는 반복을 기반으로합니다

static void Main(string[] args) 
    { 
     Console.WriteLine("Enter the desired Timespan"); 
     string s = Console.ReadLine(); 

     //ToDo: Make sure that s has the desired format 

     //Get the TimeSpan, create a new list when the string does not contain a whitespace. 
     TimeSpan span = s.Contains(' ') ? extractTimeSpan(new List<string>(s.Split(' '))) : extractTimeSpan(new List<string>{s}); 

     Console.WriteLine(span.ToString()); 

     Console.ReadLine(); 
    } 

    static private TimeSpan extractTimeSpan(List<string> parts) 
    { 
     //We will add our extracted values to this timespan 
     TimeSpan extracted = new TimeSpan(); 

     foreach (string s in parts) 
     { 
      if (s.Length > 0) 
      { 
       //Extract the last character of the string 
       char last = s[s.Length - 1]; 

       //extract the value 
       int value; 
       Int32.TryParse(s.Substring(0, s.Length - 1), out value); 

       switch (last) 
       { 
        case 'd': 
         extracted = extracted.Add(new TimeSpan(value,0,0,0)); 
         break; 
        case 'h': 
         extracted = extracted.Add(new TimeSpan(value, 0, 0)); 
         break; 
        case 'm': 
         extracted = extracted.Add(new TimeSpan(0, value, 0)); 
         break; 
        case 's': 
         extracted = extracted.Add(new TimeSpan(0, 0, value)); 
         break; 
        default: 
         throw new Exception("Wrong input format"); 
       } 
      } 
      else 
      { 
       throw new Exception("Wrong input format"); 
      } 
     } 

     return extr 
0

당신은 당신의 접근 방식을 구체화 할 수 있습니다 약간

int d = 0; 
int m = 0; 
int h = 0; 
int s = 0; 

// Because of the "params" keyword, "new char[]" can be dropped. 
string [] parts = textBox3.Text.Split(' ', ','); 

foreach (string part in parts) 
{ 
    char type = part[part.Length - 1]; 
    int value = Convert.ToInt32(part.Substring(0, part.Length - 1)); 
    switch (type) { 
     case 'd': 
      d = value; 
      break; 
     case 'h': 
      h = value; 
      break; 
     case 'm': 
      m = value; 
      break; 
     case 's': 
      s = value; 
      break; 
    } 
} 

이제 누락 된 부품 세트가 정확하게 있습니다. 누락 된 부분은 여전히 ​​0입니다. 값을 TimeSpan으로 변환 할 수 있습니다.

var ts = TimeSpan.FromSeconds(60 * (60 * (24 * d + h) + m) + s); 

모든 경우를 포함합니다.

관련 문제