회고록 블로그

[Java 공부] Scanner 클래스의 useDelimiter 메소드를 이용해서 구분자를 쉼표로 변경해보기 본문

2. 프로그래밍 언어 공부/Java

[Java 공부] Scanner 클래스의 useDelimiter 메소드를 이용해서 구분자를 쉼표로 변경해보기

김간장 2021. 11. 30. 00:16

Java 문법을 공부하다가 뜬금없이 Scanner의 구분자를 변경하고 싶어졌다. (그것도 굳이 꼭 쉼표로)

근데 생각보다 쉽게 해결이 안됐다.. 한 2-3시간은 잡고 있었던 듯..

 

이것저것 해보다가 해결법을 찾아서 기록해놓기로 했다.

 


[시도1] useDelimiter 메소드에 쉼표를 인자로 주기

아래의 코드를 입력하면 어찌저찌 실행은 할 수 있다.

하지만, 단순하게 인자를 쉼표로 주면 꼭 마지막에 "쉼표(,)"를 붙여줘야했다.

sc.useDelimiter(",");

아마 구분자가 쉼표이기 때문에 어쩔 수 없나보다.

 

그나마 String타입은 문자열이기 때문에 공백을 함께 저장할 수 있어서,

아래와 같이 쉼표(구분자) 뒤에 공백을 넣어도 오류(Error)는 발생하지 않았다.

물론 결과가 좀 이상해졌지만, 어쨌든 오류는 발생하지 않을 수 있었다.

 

하지만 int타입은 아니다.

정해진 구분자로 맞춰서 쓰지 않으면 바로 오류가 발생했다.

입력값 : 1,2, (가능)
입력값 : 1, 2, (불가능)
입력값 : 1 ,2, (불가능)

 

 

[시도2] 인자로 정규표현식 넣기

2.1. 1차 시도

도대체 어떻게 해야하지 여기저기 찾다가 useDelimiter의 인자로 정규표현식을 넣어줘야한다는 것을 찾았다.

출처 : https://stackoverflow.com/questions/28766377/how-do-i-use-a-delimiter-with-scanner-usedelimiter-in-java

 

How do I use a delimiter with Scanner.useDelimiter in Java?

sc = new Scanner(new File(dataFile)); sc.useDelimiter(",|\r\n"); I don't understand how delimiter works, can someone explain this in layman terms?

stackoverflow.com

 

그리고 조금 더 또 해답을 찾아다니다가 좋은 질문을 찾아냈다.

https://stackoverflow.com/questions/40027915/java-scanning-comma-delimited-double-and-int-values

 

Java - Scanning comma delimited double and int values

I'm trying to use Java's Scanner class to scan in double and int values delimited by commas. The following Scanner input = new Scanner(System.in).useDelimiter("\\D"); can only scan int values sepa...

stackoverflow.com

 

위의 분은 인자로 "[,\n]"을 전달해서 해결됐다고 한다.

 물론 나도 해봤지만 해결되지 않았다.

 

2.2. 2차 시도

혹시 개행문자(\n)의 문제인가 싶어서 아래와 같이 \r\n으로 수정해봤다.

 

와, 성공했다.

시스템마다 사용하는 개행문자가 다르다고 하니 \r\n , \r , \n 등 다양하게 넣어봐야할 것 같다.

 

참고자료: https://hianna.tistory.com/602

 

[Java] 줄바꿈 하기 (\n, \r, \r\n 의 차이)

Java에서 문자열의 줄바꿈을 표현할 때 주로 아래와 같은 escape 문자를 사용합니다. \n \r \r\n 그렇다면 위 3가지 escape 문자의 차이점은 무엇일까요? 세가지 표현 모두 줄바꿈을 나타내지만, 시스템

hianna.tistory.com

 

 

2.3. 3차 시도

하지만 여전히 아래처럼 유연하게 입력값을 받아주지는 못했다.

일단 쉼표 뒤에 띄어쓰기가 들어가면 반드시 에러가 발생했다.

사람이 입력을 하다보면 띄어쓰기를 넣을 수도 있을텐데... 어떡하지?

입력값 : 1,2, (가능)
입력값 : 1,2 (가능)
입력값 : 1, 2, (불가능)
입력값 : 1 ,2, (불가능)

 

더이상 스택오버플로우 질문들에만 의존할 수 없어서 안되겠다 싶어 정규표현식을 잠깐 짧게 공부하기로 했다.

 

그리고 아래처럼 코드를 작성하였다.

 

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		sc.useDelimiter("(\s*,\s*)|(\r\n)");
		
		int num1 = sc.nextInt();
		int num2 = sc.nextInt();
		
		System.out.println(num1);
		System.out.println(num2);
	}
}

 

성공했다.

 

 

문자열도 성공했다.


입력한 정규표현식을 짧게 정리해보자면 이렇다.

\s : 공백 1개

* : 앞의 값이 없거나 한번 이상 나옴

→ \s* : 공백(\s)이 없거나 한번 이상 나온다

| : or

\r\n : 개행문자

 

즉, 

1) \s*,\s* : 처음에 공백(\s)이 없거나 한번 이상 나온다 -> 그 다음 쉼표가 나오고 -> 다시 공백(\s)이 없거나 한번 이상 나온다

2) | : 혹은

3) \r\n : 개행문자가 온다

(\s*,\s*)|(\r\n)

 

이렇게해서 구분자가 "쉼표 혹은 개행문자"가 되었다.

(심지어 쉼표 뒤에 띄어쓰기를 넣어도 문제가 발생하지 않게 되었다)

Comments