应该在java.util.Scanner中使用什么模式来获取下一个String标识符?

时间:2011-02-05 20:59:50

标签: java pattern-matching java.util.scanner

在一行文字中,我有“*(,identifier1*(identifier2”,我想阅读标识符,定义为单词字符([a-zA-Z_0-9])。

我应该使用哪种模式?我想过使用:

scanner.next( "[\\w]+");

但我得到例外java.util.InputMismatchException

2 个答案:

答案 0 :(得分:5)

扫描仪的默认分隔符是空格,因此扫描仪对象中的第一个(也是唯一的)标记是整个字符串"*(,identifier1*(identifier2"。你试图通过调用next("[\\w]+")获得的字符串,这会导致异常被抛出,因为它与你的输入不匹配。

你所追求的更像是findInLine("\\w+")

Scanner scan = new Scanner("*(,identifier1*(identifier2");
System.out.println(scan.findInLine("\\w+"));
System.out.println(scan.findInLine("\\w+"));

产生:

identifier1
identifier2

或者,如果要将输入字符串拆分为一个或多个非(ascii)alpha-num-chars(和_),请尝试:

Scanner scan = new Scanner("*(,identifier1*(identifier2").useDelimiter("\\W+");
while(scan.hasNext()) {
  System.out.println(scan.next());
}

产生与以前相同的输出。

请注意,我使用了大写W,它等于:

\W == [^\w] == [^a-zA-Z0-9_]

答案 1 :(得分:1)

除非出于某种原因必须使用扫描仪,否则您可以从任何地方获取字符串,然后直接提取单词。当然,这会立即将所有单词加载到内存中,而使用扫描程序,它们会一次读入一个:

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
    public static void main(String[] args) {
        List<String> words = extractWords("*(,identifier1*(identifier2");
        for (String word : words)
            System.out.println(word);
    }

    public static List<String> extractWords(String input) {
        List<String> out = new ArrayList<String>();

        Pattern re = Pattern.compile("\\w+");
        Matcher matcher = re.matcher(input);
        while (matcher.find())
            out.add(matcher.group());

        return out;
    }
}

生成输出:

identifier1
identifier2