用Java代替单词

时间:2015-11-12 22:01:27

标签: java regex

有一些行,例如" 1 qqq 4 aaa 2"并列出{aaa,qqq}。我必须改变列表中单词的所有单词(仅由字母组成)。回答这个例子" 1 aaa 4 qqq 2"。尝试

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

但它没有用。结果我有相同的路线。

我的所有代码:

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);
}

2 个答案:

答案 0 :(得分:2)

我认为问题可能是replaceFirst()期望正则表达式作为第一个参数而你给它一个字符串。

也许试试

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

代替?

<强>更新

这对您来说是否可能:

    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();

更新2:

像这样更改StringTokenizer:

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

这也将返回分隔符(所有空格)。

然后将字符串连接起来:

    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();

这应该有效。

更新3:

@DavidConrad提到StrinkTokenizer不应再使用了。以下是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]);     
    }
}

答案 1 :(得分:0)

出于好奇,另一种解决方案(其他人真的不回答问题),它会接受输入行并按照字母顺序对结果进行排序,如您在问题中所评论的那样。

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();
    }
}