๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Java

[Java] String.matches() ๋Œ€์‹  Pattern์„ ์‚ฌ์šฉํ•˜์ž

by kriorsen 2024. 3. 17.

๐Ÿค”  String.matches()๋Š” ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„๋˜์–ด ์žˆ์„๊นŒ?


    // String.java
    public boolean matches(String regex) {
	return Pattern.matches(regex, this);
    }

 

์ž๋ฐ”์—์„œ String ํด๋ž˜์Šค์˜ matches() ๋ฉ”์„œ๋“œ์—์„œ ๋‚ด๋ถ€์ ์œผ๋กœ Pattern ํด๋ž˜์Šค์˜ matches ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด Pattern์˜ matches() ๋ฉ”์„œ๋“œ๋Š” ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ์ •๊ทœ์‹๊ณผ ๋ฌธ์ž์—ด์˜ ๋งค์นญ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ• ๊นŒ?

    // Pattern.java
    public static boolean matches(String regex, CharSequence input) {
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(input);
        return m.matches();
    }

 

Pattern ํด๋ž˜์Šค์—์„œ๋Š” ์ž…๋ ฅ๋œ ์ •๊ทœ์‹(regex)์„ ์ปดํŒŒ์ผํ•˜์—ฌ ์ƒˆ๋กœ์šด Pattern ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ํ•ด๋‹น ์ธ์Šคํ„ด์Šค์—์„œ ๋น„๊ตํ•  ๋ฌธ์ž์—ด์„ ์ž…๋ ฅ๋ฐ›์•„ Matcher ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋˜ ๋งŒ๋“ค๊ณ  ๋งค์นญ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

๐Ÿฅ”  String.matches()์˜ ๋ฌธ์ œ์ 


package blackjack.domain.participant;

import blackjack.exception.NonAlphabeticNameException;

public class Name {
    private static final String NAME_FORMAT = "^[a-zA-Z๊ฐ€-ํžฃ]*$";

    private final String value;

    public Name(String value) {
        validateIsAlphabetic(value);
        this.value = value;
    }

    private void validateIsAlphabetic(String name) {
        if (!name.matches(NAME_FORMAT)) {
            throw new NonAlphabeticNameException();
        }
    }
}

 

๋‚˜๋Š” ๋ธ”๋ž™์žญ ๋ฏธ์…˜์„ ๊ตฌํ˜„ํ•˜๋ฉด์„œ ์œ„์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๋Š”๋ฐ, String ํด๋ž˜์Šค์˜ ๊ตฌํ˜„์— ๋”ฐ๋ผ validateIsAlphabetic()์ด๋ผ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ์™€ ๊ฐ™์ด ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

    private void validateIsAlphabetic(String name) {
        Pattern p = Pattern.compile(NAME_FORMAT);
        Matcher m = p.matcher(name);
        if (!m.matches()) {
            throw new NonAlphabeticNameException();
        }
    }

 

๋ฌธ์ œ๊ฐ€ ์—†์–ด ๋ณด์ด์ง€๋งŒ, ๋ถˆํ•„์š”ํ•œ Pattern ์ธ์Šคํ„ด์Šค๊ฐ€ ๊ณ„์† ์ƒ์„ฑ๋˜๊ณ  ์žˆ๋‹ค. name์€ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์— ๋”ฐ๋ผ ๋ฐ”๋€Œ๋Š” ๊ฐ’์ด๋ผ Matcher ์ธ์Šคํ„ด์Šค์˜ ์ƒ์„ฑ์€ ํ”ผํ•  ์ˆ˜ ์—†์ง€๋งŒ, Pattern์˜ ๊ฒฝ์šฐ์—๋Š” NAME_FORMAT์ด๋ผ๋Š” ์ƒ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๋Ÿฌ ๋ฒˆ ์ƒ์„ฑํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

๐Ÿ“Œ  ๋ถˆํ•„์š”ํ•œ ๊ฐ์ฒด ์ƒ์„ฑ์„ ์ค„์ด๋Š” ๋ฐฉ๋ฒ•

String.matches()์˜ ๋ฌธ์ œ์ ์„ ํŒŒ์•…ํ–ˆ์œผ๋‹ˆ, ์ด๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž. ๊ฑฐ์ฐฝํ•˜๊ฒŒ ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ๋ถ€๋ฅด๊ธฐ๋„ ์• ๋งคํ•˜์ง€๋งŒ, ์•„๋ž˜์™€ ๊ฐ™์ด ๋ฌธ์ž์—ด ์ •๊ทœ์‹ ๋Œ€์‹  Pattern์„ ์ƒ์ˆ˜๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋„๋ก ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด ๋œ๋‹ค.

package blackjack.domain.participant;

import blackjack.exception.NonAlphabeticNameException;

import java.util.regex.Pattern;

public class Name {
    private static final Pattern NAME_PATTERN = Pattern.compile("^[a-zA-Z๊ฐ€-ํžฃ]*$");

    private final String value;

    public Name(String value) {
        validateIsAlphabetic(value);
        this.value = value;
    }

    private void validateIsAlphabetic(String name) {
        if (!NAME_PATTERN.matcher(name).matches()) {
            throw new NonAlphabeticNameException(name);
        }
    }
}

 

๐Ÿง  String.matches()๊ณผ Pattern ์‚ฌ์šฉ ์‹œ์˜ ์„ฑ๋Šฅ ์ฐจ์ด


๋‘ ์ฝ”๋“œ์˜ ์„ฑ๋Šฅ ์ฐจ์ด๋ฅผ ์•Œ์•„๋ณด๊ธฐ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค.

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.util.regex.Pattern;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class StringTest {
    private static final String NAME_FORMAT = "^[a-zA-Z๊ฐ€-ํžฃ]*$";
    private static final Pattern NAME_PATTERN = Pattern.compile(NAME_FORMAT);

    @DisplayName("String.matches()๋กœ ๋ฌธ์ž์—ด์„ ๋น„๊ตํ•œ๋‹ค.")
    @Test
    void stringMatchesTest() {
        assertTrue(() -> "hello".matches(NAME_FORMAT));
    }

    @DisplayName("Pattern.matcher()๋กœ ๋ฌธ์ž์—ด์„ ๋น„๊ตํ•œ๋‹ค.")
    @Test
    void patternMatcherTest() {
        assertTrue(() -> NAME_PATTERN.matcher("hello").matches());
    }
}

 

 

๋‹น์—ฐํ•˜๊ฒŒ๋„ ๋‚ด๋ถ€์ ์œผ๋กœ Pattern ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ณผ์ •์„ ์ถ”๊ฐ€์ ์œผ๋กœ ๊ฑฐ์น˜๋Š” ์ฒซ ๋ฒˆ์งธ ๊ฒฝ์šฐ๊ฐ€ ์‹คํ–‰ ์‹œ๊ฐ„์ด ์กฐ๊ธˆ ๋” ๊ธด ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์ž์ฃผ ์‹คํ–‰๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด ๊ฐ€๋…์„ฑ์„ ํƒํ•ด์„œ String.matches()๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ๋‚˜์˜์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.util.regex.Pattern;

public class StringTest {
    private static final int loop = 100_000_000;
    private static final String NAME_FORMAT = "^[a-zA-Z๊ฐ€-ํžฃ]*$";
    private static final Pattern NAME_PATTERN = Pattern.compile(NAME_FORMAT);

    @DisplayName("String.matches()๋กœ ๋ฌธ์ž์—ด์„ ๋น„๊ตํ•œ๋‹ค.")
    @Test
    void stringMatchesTest() {
        for (int i = 0; i < loop; i++) {
            "hello".matches(NAME_FORMAT);
        }
    }

    @DisplayName("Pattern.matcher()๋กœ ๋ฌธ์ž์—ด์„ ๋น„๊ตํ•œ๋‹ค.")
    @Test
    void patternMatcherTest() {
        for (int i = 0; i < loop; i++) {
            NAME_PATTERN.matcher("hello").matches();
        }
    }
}

 

๊ทธ๋Ÿฌ๋‚˜ ์œ„์™€ ๊ฐ™์ด ์‹คํ–‰ ํšŸ์ˆ˜๊ฐ€ ๋งŽ์ด ๋Š˜์–ด๋‚œ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ฒŒ ๋œ๋‹ค.

 

๐Ÿ“Œ  ๊ฒฐ๋ก 


Java์—์„œ ์ •๊ทœ ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜๋Š” ์ƒํ™ฉ์ด ์˜จ๋‹ค๋ฉด ๋˜๋„๋ก Pattern์„ ์ƒ์ˆ˜ํ™”ํ•˜์ž. ์ด๊ฑด ๋‹จ์ˆœํžˆ ํ•˜๋‚˜์˜ ์˜ˆ์‹œ์ผ๋ฟ์ด๊ณ  ์‹ค์ œ๋กœ๋„ ๊ต‰์žฅํžˆ ๋‹ค์–‘ํ•œ ์ผ€์ด์Šค๋กœ ์ด๋Ÿฐ ์‚ฌ์†Œํ•œ ๋ถ€๋ถ„๋“ค์„ ๋†“์น  ์ˆ˜ ์žˆ์œผ๋‹ˆ, Java์˜ ์ฝ”๋“œ ๋‚ด๋ถ€ ๊ตฌํ˜„์— ๋Œ€ํ•œ ๊ณต๋ถ€๊ฐ€ ๋งŽ์ด ํ•„์š”ํ•  ๊ฒƒ ๊ฐ™๋‹ค.