Как выделить число из сложносоставной строки?

 
Столкнулся с необходимостью выделить число из сложносоставной строки в переменную типа double, чтобы затем можно было использовать его в расчетах. При этом число находится в середине строки (неизвестно где) и функция StringToDouble не помогает. Ниже приведу пример такой строки. Как можно выделить из нее число?
 
string test = "test-test box 1.23456 impossible m +"; 
Документация по MQL5: Преобразование данных / StringToDouble
Документация по MQL5: Преобразование данных / StringToDouble
  • www.mql5.com
StringToDouble - Преобразование данных - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
leon_17:
Столкнулся с необходимостью выделить число из сложносоставной строки в переменную типа double, чтобы затем можно было использовать его в расчетах. При этом число находится в середине строки (неизвестно где) и функция StringToDouble не помогает. Ниже приведу пример такой строки. Как можно выделить из нее число?
 

Строка всегда постоянна, кроме значения?

  string test = "test-test box 1.23456 impossible m +";
  double res=0;
  string str[];
  int r=StringSplit(test,' ',str);
  if(r>2)
    res=(double)str[2];
  Print(res);
 

Наиболее очевидный и в то же время универсальный способ (без привязки к формату строки) - посимвольная обработка строки. Тип string - это массив символов.

void OnStart()
{
   string test = "test-test box 1.23456 impossible m +"; 
   
   int nLength = StringLen(test);
   string sRes = "";
   int nLastDigitIndex = -2;
   for (int i = 0; i < nLength; ++i)
   {
      if ((test[i] < '0' || test[i] > '9') && test[i] != '.' && test[i] != '-') 
         continue;
         
      if (sRes != "" && nLastDigitIndex < i - 1)
         sRes = "";
         
      nLastDigitIndex = i;
      sRes += StringSubstr(test, i, 1);
   }
   
   Print("Result: ", sRes);
}

Скорее всего, есть более изящные решения.

 
bool IsNumber( const ushort Char )
{
  return((Char >= '0') && (Char <= '9'));
}

double GetDouble( const string Str )
{
  const int Size = StringLen(Str) - 1;
  double Res = 0;
  
  for (int i = 0; i <= Size; i++)
    if (IsNumber(Str[i]) ||
        ((Str[i] == '-') && (i < Size) && IsNumber(Str[i + 1])))
    {
      Res = (double)StringSubstr(Str, i);
      
      break;
    }    
  
  return(Res);
}
 
#property show_inputs

input string test = "test-test box 1.23456 impossible m +"; 

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
void OnStart() {
  
   int len=StringLen(test);
   int pos_start=-1;
   
   for (int i=0; i<len-1; i++) {
      string s=StringSubstr(test,i,1);
      if (s=="0" || s=="1" || s=="2" || s=="3" || s=="4" || s=="5" || s=="6" || s=="7" || s=="7" || s=="9") {
         pos_start=i;
         //Print("   pos_start="+(string)pos_start);
         break;
      }
   }
   
   if (pos_start<0) {
      Print("   Number was not found.");
      return;
   }
   else {
      double d=StringToDouble(StringSubstr(test,pos_start,len-pos_start+1));
      Print("   Double number: "+DoubleToString(d));
   }
  
}
//+------------------------------------------------------------------+
 
Vitaly Muzichenko #:

Строка всегда постоянна, кроме значения?

Нет строка непостоянная. То есть число может находиться где угодно и не факт, что оно там вообще есть. Интересует сам принцип (подход) поиска необходимого числа в тексте.

Большое спасибо ВСЕМ за предложенные решения! Буду изучать... 

 
leon_17 #:

Нет строка непостоянная. То есть число может находиться где угодно и не факт, что оно там вообще есть. Интересует сам принцип (подход) поиска необходимого числа в тексте.

Большое спасибо ВСЕМ за предложенные решения! Буду изучать... 

Тогда подойдет только последний вариант

 
leon_17:
Столкнулся с необходимостью выделить число из сложносоставной строки в переменную типа double, чтобы затем можно было использовать его в расчетах. При этом число находится в середине строки (неизвестно где) и функция StringToDouble не помогает. Ниже приведу пример такой строки. Как можно выделить из нее число?
 
Самый оптимальный способ - изменить алгоритм так, чтобы не было такой ситуации, когда из string нужно получать число. 
Ведь строка до этого как-то была сформирована из числа. 
Это очень дорого и не разумно - сначала из числа формировать строку, а потом из строки выковыривать это же число.

 
Nikolai Semko #:
Самый оптимальный способ - изменить алгоритм так, чтобы не было такой ситуации, когда из string нужно получать число. 
Ведь строка до этого как-то была сформирована из числа. 
Это очень дорого и не разумно - сначала из числа формировать строку, а потом из строки выковыривать это же число.

Может быть вбито ручками...

Например: "Я встретил Вас спустя 6 лет, и думал не узнаю, Вы были в чёрных галифе, в зубах была сигара" ...

 

На мой взгляд, при всём неприятии его кодов, это лучший вариант

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Как выделить число из сложносоставной строки?

fxsaber, 2023.12.21 09:01

bool IsNumber( const ushort Char )
{
  return((Char >= '0') && (Char <= '9'));
}

double GetDouble( const string Str )
{
  const int Size = StringLen(Str) - 1;
  double Res = 0;
  
  for (int i = 0; i <= Size; i++)
    if (IsNumber(Str[i]) ||
        ((Str[i] == '-') && (i < Size) && IsNumber(Str[i + 1])))
    {
      Res = (double)StringSubstr(Str, i);
      
      break;
    }    
  
  return(Res);
}

Но я-бы уточнил, перед числом обязательно будет пробел? И тогда этот код можно сократить поиском пробела и проверки следующего за пробелом символа, а не каждого в цикле. 

 

может лучше использовать такое?


Причина обращения: