在Java中,如何使用Scanner.useDelimiter来使用分隔符?

67
sc = new Scanner(new File(dataFile));
sc.useDelimiter(",|\r\n");

我不理解分隔符是如何工作的,有人能用通俗易懂的语言解释一下吗?


2
这是它的工作原理:在这里,这是如何工作的:http://javatutorialhq.com/java/util/scanner-class-tutorial/usedelimiter-string-pattern-method-example/ - nafas
1
正如Javadoc所说:“使用分隔符模式将输入分解为标记,默认情况下匹配空格。然后可以使用各种next方法将生成的标记转换为不同类型的值。”这难道不清楚吗? - ema
1
@ema——我猜你是在开玩笑,因为只有当你已经"理解了分隔符的工作原理"时才会很清楚,而NoMoreErrors并没有。例如,"分隔符模式"是什么可能会让你所说的变得不太清楚,这肯定不是错误的,但对问题没有帮助。但至少你没有像许多人那样嘲笑NoMoreErrors。 - DSlomer64
3个回答

102

扫描器还可以使用除空格以外的分隔符。

Scanner API提供了一个简单的示例:

 String input = "1 fish 2 fish red fish blue fish";

 // \\s* means 0 or more repetitions of any whitespace character 
 // fish is the pattern to find
 Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");

 System.out.println(s.nextInt());   // prints: 1
 System.out.println(s.nextInt());   // prints: 2
 System.out.println(s.next());      // prints: red
 System.out.println(s.next());      // prints: blue

 // don't forget to close the scanner!!
 s.close(); 

重点在于理解regex表达式,它们位于Scanner::useDelimiter中。在这里可以找到useDelimiter的教程。


若想学习正则表达式,可以在这里找到一个好的教程。

注释

abc…    Letters
123…    Digits
\d      Any Digit
\D      Any Non-digit character
.       Any Character
\.      Period
[abc]   Only a, b, or c
[^abc]  Not a, b, nor c
[a-z]   Characters a to z
[0-9]   Numbers 0 to 9
\w      Any Alphanumeric character
\W      Any Non-alphanumeric character
{m}     m Repetitions
{m,n}   m to n Repetitions
*       Zero or more repetitions
+       One or more repetitions
?       Optional character
\s      Any Whitespace
\S      Any Non-whitespace character
^$     Starts and ends
(…)     Capture Group
(a(bc)) Capture Sub-group
(.*)    Capture all
(ab|cd) Matches ab or cd

1
只是提醒一下:这行代码:Scanner s = new Scanner(input).useDelimiter("\sfish\s"); 实际上存在资源泄漏,即使你调用了s.close()。泄漏发生在调用useDelimiter的scanner上。如果你改为以下写法: Scanner s = new Scanner(input); s.useDelimiter(\\s*fish\\s); 就可以避免这个问题。 - georges
@georges,实际上我的代码行是:("\sfish\s")... 而不是("\sfish\s"),但您能否请澄清一下您的意思? - Jordi Castilla
换句话说,对于一个新手来说,这个答案和评论对NoMoreErrors没有任何帮助。为了使用Scanner而学习正则表达式????确实,这会有所帮助,但远远超出了他的需求。只需给出一个例子。简单明了的例子。 - DSlomer64
@DSlomer64实际上您不需要使用regex来使用Scanner,但如果要使用自定义分隔符,则必须使用regex,因为这是useDelimiter方法接受的输入。这就是OP所问的,只要被接受为答案,我认为它适合OP。为什么您认为OP是新手?如果您是新手并且答案不适合您,请提出一个新问题:) - Jordi Castilla
@JordiCastilla--OP几乎肯定是个新手,因为他的问题水平和声望353。所以他的useDelimiter示例肯定需要解释。我的观点是,我们需要考虑用户的经验和实际需求,而不是离题(从用户的角度来看),但你让我意识到了这一点:用户可以在深入阅读后停止阅读评论或继续阅读以了解更多信息。我从OP的想法中读得太多了。你的观点很好。**:^}** - DSlomer64

12

使用Scanner时,默认的分隔符是空格字符。

但是Scanner可以基于一组分隔符来定义token的起始位置和结束位置,这些分隔符可以通过两种方式指定:

  1. 使用Scanner的方法:useDelimiter(String pattern)
  2. 使用Scanner的方法:useDelimiter(Pattern pattern)其中Pattern是指定分隔符集的正则表达式。

因此,useDelimiter()方法用于对Scanner输入进行标记化,并且类似于StringTokenizer类,请参考这些教程以获取更多信息:

以下是一个示例

public static void main(String[] args) {

    // Initialize Scanner object
    Scanner scan = new Scanner("Anna Mills/Female/18");
    // initialize the string delimiter
    scan.useDelimiter("/");
    // Printing the tokenized Strings
    while(scan.hasNext()){
        System.out.println(scan.next());
    }
    // closing the scanner stream
    scan.close();
}

打印此输出:

Anna Mills
Female
18

3

例如:

String myInput = null;
Scanner myscan = new Scanner(System.in).useDelimiter("\\n");
System.out.println("Enter your input: ");
myInput = myscan.next();
System.out.println(myInput);

这将允许您使用回车作为分隔符。
因此,如果您输入:
Hello world (ENTER)

这将会打印出 'Hello World'。


1
是的,但它是如何工作的?两个反斜杠有什么用?但是太好了,现在我们知道如何使用回车作为分隔符。假设它能正常工作。 - DSlomer64

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接