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

I don't understand how delimiter works, can someone explain this in layman terms?

Ola Ström
  • 917
  • 1
  • 8
  • 23
NoMoreErrors
  • 1,093
  • 2
  • 10
  • 12
  • 2
    here, this is how it works: http://javatutorialhq.com/java/util/scanner-class-tutorial/usedelimiter-string-pattern-method-example/ – nafas Feb 27 '15 at 13:37
  • 1
    As javadoc says "breaks its input into tokens using a delimiter pattern, which by default matches whitespace. The resulting tokens may then be converted into values of different types using the various next methods". Isn't it clear? – ema Feb 27 '15 at 13:42
  • @ema--I assume that was tongue-in-cheek because it's only clear if you already "understand how delimiter works" and NoMoreErrors does NOT. E.g., what a "delimiter pattern" is might just un-clear what you've said, which surely isn't wrong, just not helpful to the Q. But at least you didn't insult NoMoreErrors like so many do, with glee, I imagine. – DSlomer64 Jan 03 '18 at 01:28

3 Answers3

94

The scanner can also use delimiters other than whitespace.

Easy example from 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(); 

The point is to understand the regular expressions (regex) inside the Scanner::useDelimiter. Find an useDelimiter tutorial here.


To start with regular expressions here you can find a nice tutorial.

Notes

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
Community
  • 1
  • 1
Jordi Castilla
  • 24,953
  • 6
  • 58
  • 97
  • 1
    `*` means **Zero or more repetitions** check my update and the link provided in the answer ;) – Jordi Castilla Nov 20 '15 at 11:52
  • @UnKnown as you can see in the regex table: `\\s*`is 0 or more repetitions of any whitespace character and `fish` is the pattern to find – Jordi Castilla Mar 30 '16 at 06:46
  • 1
    just fyi: this line: Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*"); actually has a resource leak, even if you call s.close(). The leak is on the scanner that useDelimiter is called on. If you instead call `Scanner s = new Scanner(input); s.useDelimiter(\\s*fish\\s);` you avoid this problem. – georges Aug 04 '16 at 21:40
  • @georges actually my line is: ("\\s*fish\\s*")... not ("\\sfish\\s") but can you please clarify what you mean? – Jordi Castilla Aug 30 '16 at 11:48
  • In other words, to a novice this Answer and comments is no help whatsoever to NoMoreErrors. Learn `regex` just to use `Scanner`?????? Sure, it would help, but it's waaaaaaay past what he needs. Just give an example. Simple friggin' example. – DSlomer64 Jan 03 '18 at 01:31
  • @DSlomer64 actuallty you don't need `regex` to use `Scanner` but if you want to use your custom delimiter is mandatory to use `regex` because is what `useDelimiter` method accepts as input. This is what OP asked and as long as is the accepted as answer, IMHO it suits OP. Why you think OP is a novice? If being a novice it's your case and the answer does not fit you please ask a new question `:)` – Jordi Castilla Jan 04 '18 at 11:36
  • @JordiCastilla--OP is almost definitely a novice because of the level of his question and rep 353. So his `useDelimiter` example certainly needs explaining, My point was that we need to factor in user's experience and actual need and not go off on a tangent (from user's point of view) but you've made me realize this: the user can quit reading comments once he's in too deep or continue reading to learn more.I was reading too much from OP's mind. Your point is well taken. **:^}** – DSlomer64 Jan 05 '18 at 11:14
11

With Scanner the default delimiters are the whitespace characters.

But Scanner can define where a token starts and ends based on a set of delimiter, wich could be specified in two ways:

  1. Using the Scanner method: useDelimiter(String pattern)
  2. Using the Scanner method : useDelimiter(Pattern pattern) where Pattern is a regular expression that specifies the delimiter set.

So useDelimiter() methods are used to tokenize the Scanner input, and behave like StringTokenizer class, take a look at these tutorials for further information:

And here is an Example:

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

Prints this output:

Anna Mills
Female
18
cнŝdk
  • 28,676
  • 7
  • 47
  • 67
3

For example:

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

This will let you use Enter as a delimiter.

Thus, if you input:

Hello world (ENTER)

it will print 'Hello World'.

Tim Malone
  • 2,894
  • 4
  • 31
  • 44
Eugenio
  • 39
  • 2
  • 1
    Yeah, but how does it work? What are TWO backslashes for? But hooray, now we know how to use Enter as a delimiter. Assuming it works. – DSlomer64 Jan 03 '18 at 01:34