2

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

4
  • You need an expression parser. The JEDI library has a good one. I'm afraid that you question does not fit here. Unless of course you will accept this comment as an answer. I suspect you are looking for more than that. Either your want a library recommendation, and that's off-topic, or you want someone to write you an expression parser which is a big task and not appropriate for here. Commented Nov 5, 2013 at 14:19
  • I agree with David. If a human can "extract the word ET", so can a computer. You just have to figure out what the rules are and code them. Do you need to parse it? Probably, but we don't know your rules. Commented Nov 5, 2013 at 14:32
  • @DavidHeffernan, Je sais, mes merci. Unfortunately, we don't know what the OP knows. What does he even mean "apply conditional test on result"? I'm not assuming much. Commented Nov 5, 2013 at 14:47
  • Okey let me clarify, I just need to parse (maybe with RegExp) a string like this to extract the final word between masters brackets. It can be 'ET' or 'OU' and i will test this result (if is it 'ET' or 'OU') and change my icon with Commented Nov 5, 2013 at 14:53

2 Answers 2

5

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

Sign up to request clarification or add additional context in comments.

1 Comment

Very nice, efficient, and specific.
5

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.