1

I have a string expressions like this:

(code   name   credits) or ((code   name   credits) and (code   name   credits))

I want to recognize all (code name credits) combinations in the string, and replace them with a value.

Code is a combination of letters and numbers.

Name is a combination of words, separated by a single space, words can have both letters and numbers.

Credit is a number.

Each component is separated by a tab.

An actual example of (code name credits) combination is the following:

IABIG-02    Computer Graphics    5

This is not related to the question, but this is what I want to achieve:

Input:

(IABIG-02    Computer Graphics    5) or ((AIBJH88    Computer Vision    5) and (AIKKH10    Computer Architecture    5))

Output:

T or (F and T) 
Martin
  • 95
  • 1
  • 6
  • What code have you tried? Post it. You just have to split the string on "or" and "and" then strip the extra parenthesis. The remaining parts will be what you are looking for. – AdrianS Apr 22 '16 at 14:09
  • This is quite similar to a question I just answered - [http://stackoverflow.com/questions/36787560/how-to-evaluate-custom-parenthesis-expression-in-c](http://stackoverflow.com/questions/36787560/how-to-evaluate-custom-parenthesis-expression-in-c). It's C#, but shouldn't be that hard to adapt for your needs. – SamWhan Apr 22 '16 at 14:18
  • Thanks for suggestion @Blitzkr1eg, the answer that Nicolas Filotto gave, gives all I wanted. – Martin Apr 22 '16 at 15:40

1 Answers1

1

Here is a potential way to do it, I could not find any clean way to implement it:

String value = "(IABIG-02\tComputer Graphics\t5) or ((AIBJH88\tComputer Vision\t5) and (AIKKH10\tComputer Architecture\t5))";
Pattern pattern = Pattern.compile("\\((\\w|-)+\\t\\w+( \\w+)*\\t\\d\\)");
Matcher matcher = pattern.matcher(value);
StringBuilder builder = new StringBuilder(value.length());
Map<String, Character> replacements = new HashMap<>();
char c = 'A';
int index = 0;
while (matcher.find(index)) {
    builder.append(value, index, matcher.start());
    String found = matcher.group();
    Character replacement = replacements.get(found);
    if (replacement == null) {
        replacement = c++;
        replacements.put(found, replacement);
    }
    builder.append(replacement);
    index = matcher.end();
}
if (index < value.length()) {
    builder.append(value, index, value.length());
}

System.out.println(builder);

Output:

A or (B and C)

It replaces all patterns found with a replacement character starting from A. I use a Map in order to be able to reuse the character previously given to the same exact pattern.

Nicolas Filotto
  • 43,537
  • 11
  • 94
  • 122