1

I'm trying to build one final method that will take a string such as

I will be the *greatest* hero ever!

and will look for the start and end asterisks, between them, whatever is there will be taken and made upper case, and then reinserting back in to look

I will be the GREATEST hero ever!

So far my code only takes whatever is between the asterisks and spits out only as a result:

"GREATEST"

I've been trying to correct this, and I've been told to use a function called "replace".

I found the reference here: a link

  while(n4.hasNext()) {
    sLine = n4.next();
    F1 = sLine.indexOf("*");
    L1 = sLine.indexOf("*", F1+1);
    count  = F1;
    if (count < L1){
      upperC = sLine.toUpperCase();
      sLine = upperC.replace("*",upperC);
      count++;
    }
  }
  return sLine;
}

So far, this only outputs "all!" after I try passing "To you the *victor* of all!"

Could someone please tell me what I'm missing or at least tell me where I can look to correct this?


UPDATE:

Here's the code so far, but now it's printing a sentence, but I'm still on the fence on how to replace the word between asterisks with a upper cased word that has no additional asterisks.

It prints: "To you the * * *VICTOR* * * of all!"

        while(n4.hasNext()) {
            sLine = n4.next();
            s += sLine + " ";
            F1 = sLine.indexOf("*");
            L1 = sLine.indexOf("*", F1+1);
            count  = F1;
            if (count < L1){

                upperC = sLine.toUpperCase();
                s = s.replaceAll("victor",upperC);
                count++;
            }
        }
        return s;
    }
Community
  • 1
  • 1

3 Answers3

2

Often the best way to debug code is to remove it. Less code means less you have to get right, and less places there are for bugs to lurk.

Accordingly, try this:

while (input.matches(".*\\*.*\\*.*")) {
    String starred = input.replaceAll("[^*]*[*]([^*]+).*", "$1");
    input = input.replace("*" + starred +"*", starred.toUpperCase());
}

This works by:

  • loop while there are is "asterisk-quoted" text
  • use regex to find the (first) asterisk-quoted text
  • do a standard (non-regex) replace of found text with its upper case equivalent
  • back to start of loop

This code also handles there being an odd number of asterisks, in which case the last (odd) one is ignored, because the while condition requires two asterisks to be in the string.

More detail

The regex in matches(".*\\*.*\\*.*") means "any chars, a escaped (ie literal) *, any chars, a literal *, any chars". The .* (any chars) is needed on either end because matches() only returns true if the whole string matches the regex.

The replaceAll() call matches the entire string, but captures the the part between the first and second * chars in the string. Breaking it down:

  • [^*]* any number of any char not a *
  • [*] a literal * - equivalent to \\*, but looks way cooler
  • ([^*]+) at least one of any char not a *, captured as "group 1"
  • .* the rest of the string

the replacement term "$1" puts back what was captured in group 1 of the match.

The overall effect is to replace the whole string with the captured part - effectively extracting the captured part. It's a very handy idiom for grabbing part of a string with minimal code.

The final replace(), which uses plain text (not regex), is less mysterious - it replaces the target for the iteration with its uppercase version.


Some test code:

String input = "I am the *greatest* of *all* time :*)";
while (input.matches(".*\\*.*\\*.*")) {
    String starred = input.replaceAll("[^*]*[*]([^*]+).*", "$1");
    input = input.replace("*" + starred +"*", starred.toUpperCase());
}
System.out.println(input);

Output:

I am the GREATEST of ALL time :*)
Community
  • 1
  • 1
Bohemian
  • 412,405
  • 93
  • 575
  • 722
0

May b you can follow some functionaliry like below

  1. Take whatever character sequence you want (first & lsat * symbol).
  2. make it as an character array.
  3. rotate till the last index.
  4. & use .toUpperCase();

Check if this can help you

0

You could use a simple state machine. In pseudo code:-

STATE = NOT_PROCESSING_TO_UPPER
WHILE( c = getChar() )
    SWITCH STATE
         CASE NOT_PROCESSING_TO_UPPER:
              IF c == '*'
                  STATE = PROCESSING_TO_UPPER
              ELSE
                 copy c to output
              BREAK
         CASE PROCESSING_TO_UPPER:
              IF c != *
                 copy UPPER CASE c to output
              ELSE
                 STATE = NOT_PROCESSING_TO_UPPER
              BREAK
    END SWITCH
END_WHILE

This will handle any number of words surrounded by *'s.

At the end of the while, if STATE is still PROCESSING_TO_UPPER, you have a mis-matched *, which you can report.

Here is some tested java code. The solution may not be the shortest, but it is readable and handles all cases.

private final static int PROCESSING_UPPER = 1;
private final static int NOT_PROCESSING_UPPER = 2;

private void test () {
    String sIn = "I am just *awsome* and *more*";
    String sOut = "";
    int state = NOT_PROCESSING_UPPER;

    for( int i=0; i < sIn.length(); i++) {
        char c=sIn.charAt(i);
        switch (state) {
            case NOT_PROCESSING_UPPER:
                if(c=='*')
                    state = PROCESSING_UPPER;
                else
                    sOut += c;
                break;

            case PROCESSING_UPPER:
                if (c!='*') {
                    String sTemp = "" + c;
                    sOut += sTemp.toUpperCase ();
                } else {
                    state = NOT_PROCESSING_UPPER;
                }
                break;
            default:
                // Error handling here.
                break;                
        }
    }
}
BryanT
  • 412
  • 3
  • 12