2017-12-19 8 views
0

문자열에서 double을 추출하고 싶습니다.문자열에서 double 값 추출하기 C#

buff = "VA VV_CELL1 3.55" 

난 내 다른 문자열을 다음 코드

private void GetLine(string msg, string buff, double numb) 
{ 
    comPort.WriteLine(msg); 
    Thread.Sleep(50); 
    buff = comPort.ReadExisting(); 
    Thread.Sleep(50); 
    MatchCollection matches = Regex.Matches(buff, @".*?([-]{0,1} *\d+.\d+)"); 
    List<double> doubles = new List<double>(); 
    foreach (Match match in matches) 
    { 
     string value = match.Groups[1].Value; 
     value = value.Replace(" ", ""); 
     doubles.Add(double.Parse(value)); 
     Thread.Sleep(200); 
     numb = doubles[0];     
    } 
} 

이 코드가 작동을 사용하지만 "CELL1은"숫자가 내가 원하는 값 "3.55"어떤 아이디어를 얻을 해달라고 그래서 포함되어있는 경우?

+0

을 반환하기 때문에 난 몰라 스레드의 목표를 이해하십시오.수면 '루프에서 – Pac0

+0

그냥 구문 분석하기 전에 모든 숫자가 아닌 문자 (10 진수 분리 자 제외)에 대한 값을 테스트 –

+0

항상 문자열에서 마지막 숫자를 추출 하시겠습니까? – Magnus

답변

5

왜이 문자열을 분할하고 마지막 부분을 차지하지 않으십니까?

string numberPart = buff.Substring(buff.LastIndexOf(' ')).Trim(); 

your comment에 도움을하려면 :

나는이 방법을 사용하는 것

string numberPart = buff.Split().Last(); 
double num; 
bool validNum = double.TryParse(numberPart, NumberStyles.Any, CultureInfo.InvariantCulture, out num); 

또 다른 방법은 (공백이없는 경우 실패) SubstringLastIndexOf을 사용하는 것입니다 double? (null 일 수있는 double)을 반환합니다.

double? GetNumber(string buff) 
{ 
    string numberPart = buff.Split().Last(); 
    double num; 
    bool validNum = double.TryParse(numberPart, NumberStyles.Any, CultureInfo.InvariantCulture, out num); 
    if (validNum) 
     return num; 
    else 
     return null; 
} 

이제 방법을 사용할 수 있으며, 심지어 숫자가 성공적 여부를 구문 분석 할 수 있는지를 알고,이 정규식 표현

double? result = GetNumber("VA VV_CELL1"); 
bool wasValid = result.HasValue; 
if(wasValid) 
{ 
    double value = result.Value; 
} 
+0

Splitting은 많은 수의 레코드를 파싱 할 때 매우 비쌀 수있는 많은 임시 문자열을 생성합니다. 레코드가 고정 길이이지만 라인 수가 짧거나 레코드 수가 적 으면 정규 표현식이 과도 할 수 있습니다 –

+0

@PanagiotisKanavos : OP의 샘플에서는 3 개의 임시 문자열을 생성합니다. 나는 이것이 너무 많은 오버 헤드라고 생각하지 않는다. 그러나'buff.Substring (buff.LastIndexOf ('')). Trim()'을 사용할 수도 있습니다. 일반적으로 정규식은 훨씬 더 비쌉니다. –

+0

Thx 메이트가 많은 도움이되었습니다! – xBehemoth

0

시도 : \s+\d+(.)?\d+

0

난 당신이 모두를 캡처 할 가정을 복소수 및 정수를 사용하면 \d+\.\d+을 쓸 수 있습니다. 이 :

Regex.Matches("VA VV_CELL1 3.55",@"\d+\.\d+")[0] 

는 3.55을 반환하지만 355

당신은 \s+\d+(\.\d+)?와 공백 앞에 정수 또는 10 진수를 캡처 할 수 있습니다 캡처 할 수 없습니다.

Regex.Matches("VA VV_CELL1 355",@"\s+\d+(\.\d+)?")[0] 

355

를 돌려

Regex.Matches("VA VV_CELL1 3.55",@"\s+\d+(\.\d+)?")[0] 

반환 3.55 동안 당신은 예를 들어, 당신이 \s+\d+(\.\d+)?$를 사용할 수있는 마지막 필드를 캡처 할 경우

Regex.Matches("VA VV_CELL1 3.54 3.55",@"\s+\d+(\.\d+)?$")[0] 

반환 3.55

double.Parse이 공백을 무시하기 때문에 공백을자를 필요가 없습니다. 당신은 괄호와 숫자를 주변으로하지만 별도의 그룹의 수를 캡처하는 패턴을 변경할 수 있습니다

Regex.Matches("VA VV_CELL1 3.54 3.55",@"\s+(\d+(\.\d+)?)$")[0].Groups[1] 

당신은 Groups[1]를 사용할 필요가 첫 번째 그룹은 항상 전체 캡처에게