как быстро распарсить строку

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Ответить
Аватара пользователя
Brainenjii
энтузиаст
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

как быстро распарсить строку

Сообщение Brainenjii »

есть строка '"index":"some \"value\""' мне нужно по запросу 'index' получить 'some "value"'. Сейчас реализовано так:

Код: Выделить всё

Function GetJSStr(Const aSource, aIndex: String): String;
Var
  aPos: Integer;
Begin
  aPos := Pos('"' + aIndex + '":"', aSource);
  If aPos = 0 Then Exit('');
  aPos := aPos + Length('"' + aIndex + '":"');
  Result := Copy(aSource, aPos, PosEx('"',aSource, aPos) - aPos);
end;

но экранированные кавычки такой "парсер", разумеется, не возьмёт...
Mr.Smart
долгожитель
Сообщения: 1796
Зарегистрирован: 29.03.2008 00:01:11
Откуда: из леса!

Сообщение Mr.Smart »

У меня так реализовано:

Код: Выделить всё

function CStrToStr(const S: String): String;
var
 j: Integer;
 esc: Boolean;
 b: Integer;
begin
  Result:='';
  j:=1;
  esc:=False;
  while j<=Length(S) do
   begin
    if esc then
     begin
      case S[j] of
       'A','a': Result:=Result+#7;
       'B','b': Result:=Result+#8;
       'T','t': Result:=Result+#9;
       'R','r': Result:=Result+#10;
       'V','v': Result:=Result+#11;
       'F','f': Result:=Result+#12;
       'N','n': Result:=Result+#13;
       'Q','q','"': Result:=Result+'"';
       'P','p','''': Result:=Result+'''';
       '0':
        begin
         if ((Length(S)-j)>2) and ((S[j+1]='x') or (S[j+1]='X')) then
          begin
           if TryStrToInt(Copy(S,j,4),b) then
            Result:=Result+chr(Byte(b));
           inc(j,3);
          end
         else
          Result:=Result+#0;
        end;
//       '': Result:=Result+'';
       else Result:=Result+S[j];
      end;
      esc:=False;
     end
    else if S[j]='' then
     esc:=True
    else
     Result:=Result+S[j];
    inc(j);
   end;
  if esc then
   Result:=Result+'';
end;


Добавлено спустя 4 минуты 14 секунд:
Не ту функцию кинул. Декводирование строк с учётом эскэйп последовательности

Код: Выделить всё

function StrQuoteBetween(var Str: String; out OStr: String; const Quote: Char = '"';
  const Esc: Char = '\'): Boolean;
var
 j,b: Integer;
 e: Boolean = False;
begin
  OStr:='';
  Result:=False;
  if (Length(Str)<2) and (Str[1]<>Quote) then
   Exit;
  j:=2;
  while j<=Length(Str) do
   begin
    if e then
     begin
      case Str[j] of
       'A','a': OStr:=OStr+#7;
       'B','b': OStr:=OStr+#8;
       'T','t': OStr:=OStr+#9;
       'R','r': OStr:=OStr+#10;
       'V','v': OStr:=OStr+#11;
       'F','f': OStr:=OStr+#12;
       'N','n': OStr:=OStr+#13;
       'Q','q','"': OStr:=OStr+'"';
       'P','p','''': OStr:=OStr+'''';
       '0':
        begin
         if ((Length(Str)-j)>2) and ((Str[j+1]='x') or (Str[j+1]='X')) then
          begin
           if TryStrToInt(Copy(Str,j,4),b) then
            OStr:=OStr+chr(Byte(b));
           inc(j,3);
          end
         else
          OStr:=OStr+#0;
        end;
       else OStr:=OStr+Str[j];
      end;
      e:=False;
     end
    else if Str[j]=Esc then
     e:=True
    else if Str[j]=Quote then
     begin
      Result:=True;
      Break;
     end
    else
     OStr:=OStr+Str[j];
    inc(j);
   end;
  Delete(Str,1,j);
end;
Аватара пользователя
Brainenjii
энтузиаст
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Сообщение Brainenjii »

циклом - это конечно вариант... Но вдруг есть какой-то волшебный метод, именно для экранируемых сиволов? ^_^ Штука-то часто встречающаяся...
Mr.Smart
долгожитель
Сообщения: 1796
Зарегистрирован: 29.03.2008 00:01:11
Откуда: из леса!

Сообщение Mr.Smart »

Там в любом случае цикл будет.
Ism
энтузиаст
Сообщения: 908
Зарегистрирован: 06.04.2007 17:36:08

Сообщение Ism »

Веселые чуваки

ExtractWord
http://www.freepascal.org/docs-html/rtl ... tword.html

Их комбинацией можно все сделать
Аватара пользователя
Brainenjii
энтузиаст
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Сообщение Brainenjii »

Обычным циклом можно гораздо оптимальней сделать ^_^
Спасибо за предложения
Ответить