Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 267
Peter Avatar asked Jun 01 '26 18:06

Peter


2 Answers

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 :-)

like image 98
TLama Avatar answered Jun 03 '26 09:06

TLama


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.

like image 32
Marcus Adams Avatar answered Jun 03 '26 08:06

Marcus Adams



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!