Peter
Peter

Reputation: 75

Parse text in string

I've got a string like this :

((VIP) OU (CHALAND)) ET ((VIP) OU (CHALAND))

I must extract the word ET which is in 2 finals brackets. After this, i will apply a conditional test on result.

The hardest part is that the text is random width with sometimes many brackets and I haven't clue to how do it in Delphi language.


More examples:

(((VIP) ET (CHALAND)) ET ((VIP) OU (CHALAND))) OU (VIP)

Result: OU

((((VIP) ET (CHALAND)) ET ((VIP) OU (CHALAND))) OU (VIP)) ET (((VIP) ET (CHALAND)) ET ((VIP) OU (CHALAND)))

Result: ET

Upvotes: 2

Views: 208

Answers (2)

TLama
TLama

Reputation: 76693

As the other answer here, this code also counts parentheses during the char by char iteration. If there is an opening parenthesis, the internal BraceCnt counter is incremented. If there's a closing parenthesis, it is decremented. And if the counter reaches 0, it means we're in between the bracketless statement, so we can shift by spaces and copy two chars whose should be the conjuction operator:

function GetMainConjunction(const Expression: string): string;
var
  P: PChar;
  BraceCnt: Integer;
begin
  Result := '';
  BraceCnt := 0;
  P := PChar(Expression);

  while (P^ <> #0) do
  begin
    case P^ of
      '(': Inc(BraceCnt);
      ')': Dec(BraceCnt);
    end;
    Inc(P);

    if BraceCnt = 0 then
    begin
      while (P^ = ' ') do
        Inc(P);
      SetString(Result, P, 2);
      Exit;
    end;
  end;
end;

For haters, the pointer char iteration used here is my favorite technique for parsing, I'm not going to beat someone in speed (but if you want to :-)

Upvotes: 5

Marcus Adams
Marcus Adams

Reputation: 53850

You can go through the text, keeping track of state, but we're making a lot of assumptions here, such as there is only one word of text outside of the parenthesis, parenthesis is the only grouping character, and there are no errors in the expression.

function returnUnbracketedWord(const text: String): String;
var
  i: Integer;
  bracketCount: Integer;
  currentChar: String;
begin
  Result := '';
  bracketCount := 0;
  for i := 1 to Length(text) do
  begin
    currentChar := Copy(text, i, 1);
    if currentChar = ')' then
    begin
      bracketCount := bracketCount - 1;
    end
    else if currentChar = '(' then
    begin
      bracketCount := bracketCount + 1;
    end
    else if bracketCount = 0 then
    begin
      Result := Result + currentChar;
    end;
  end;
  Result := Trim(Result);
end;

You could do further checks, such as ensure that bracketCount = 0 at the end.

Upvotes: 5

Related Questions