Hungry
Hungry

Reputation: 11

Replace word in Java

There is some line, for example "1 qqq 4 aaa 2" and list {aaa, qqq}. I must change all words (consists only from letters) on words from list. Answer on this example "1 aaa 4 qqq 2". Try

StringTokenizer tokenizer = new StringTokenizer(str, " ");
while (tokenizer.hasMoreTokens()){
    tmp = tokenizer.nextToken();
    if(tmp.matches("^[a-z]+$"))
        newStr = newStr.replaceFirst(tmp, words.get(l++));
}

But it's not working. In result I have the same line.

All my code:

String space = " ", tmp, newStr;
Scanner stdin = new Scanner(System.in);
while (stdin.hasNextLine()) {
    int k = 0, j = 0, l = 0;
    String str = stdin.nextLine();
    newStr = str;
    List<String> words = new ArrayList<>(Arrays.asList(str.split(" ")));
    words.removeIf(new Predicate<String>() {
        @Override
        public boolean test(String s) {
            return !s.matches("^[a-z]+$");
        }
    });
    Collections.sort(words);
    StringTokenizer tokenizer = new StringTokenizer(str, " ");
    while (tokenizer.hasMoreTokens()){
        tmp = tokenizer.nextToken();
        if(tmp.matches("^[a-z]+$"))
            newStr = newStr.replaceFirst(tmp, words.get(l++));
    }
    System.out.printf(newStr);
}

Upvotes: 1

Views: 160

Answers (2)

burna
burna

Reputation: 2962

Just out of curiosity, another solution (the others really don't answer the question), which takes the input line and sorts the words alphabetically in the result, as you commented in your question.

public class Replacer {
    public static void main(String[] args) {
        Replacer r = new Replacer();

        Scanner in = new Scanner(System.in);
        while (in.hasNextLine()) {
            System.out.println(r.replace(in.nextLine()));
        }    
    }

    public String replace(String input) {
        Matcher m = Pattern.compile("([a-z]+)").matcher(input);    
        StringBuffer sb = new StringBuffer();

        List<String> replacements = new ArrayList<>();
        while (m.find()) {
            replacements.add(m.group());    
        }
        Collections.sort(replacements);    
        m.reset();

        for (int i = 0; m.find(); i++) {    
        m.appendReplacement(sb, replacements.get(i));
        }
        m.appendTail(sb);    

        return sb.toString();
    }
}

Upvotes: 0

Hendrik Simon
Hendrik Simon

Reputation: 231

I think the problem might be that replaceFirst() expects a regular expression as first parameter and you are giving it a String.

Maybe try

newStr = newStr.replaceFirst("^[a-z]+$", words.get(l++));

instead?

Update:

Would that be a possibility for you:

    StringBuilder _b = new StringBuilder();     
    while (_tokenizer.hasMoreTokens()){
        String _tmp = _tokenizer.nextToken();
        if(_tmp.matches("^[a-z]+$")){
            _b.append(words.get(l++));
       }
       else{
            _b.append(_tmp);
       }
       _b.append(" ");
    }
    String newStr = _b.toString().trim();

Update 2:

Change the StringTokenizer like this:

StringTokenizer tokenizer = new StringTokenizer(str, " ", true);

That will also return the delimiters (all the spaces).

And then concatenate the String like this:

    StringBuilder _b = new StringBuilder();     
    while (_tokenizer.hasMoreTokens()){
        String _tmp = _tokenizer.nextToken();
        if(_tmp.matches("^[a-z]+$")){
            _b.append(words.get(l++));
       }
       else{
            _b.append(_tmp);
       }
    }
    String newStr = _b.toString().trim();

That should work.

Update 3:

As @DavidConrad mentioned StrinkTokenizer should not be used anymore. Here is another solution with String.split():

final String[] _elements = str.split("(?=[\\s]+)");

int l = 0;
for (int i = 0; i < _tokenizer.length; i++){
    if(_tokenizer[i].matches("^[a-z]+$")){
        _b.append(_arr[l++]);
    }
    else{
        _b.append(_tokenizer[i]);     
    }
}

Upvotes: 2

Related Questions