์ง€์‹ ์ •๋ฆฌ/JAVA

[JAVA] Spring์˜ split์— ๋Œ€ํ•˜์—ฌ

27200 2025. 8. 9. 11:19

๐Ÿค” ๋ฌธ์ œ์˜์‹

ํ‰์†Œ ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ ์—ฐ์Šต์„ ํ•˜๋‹ค ๋ณด๋ฉด split์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค.

ํ•˜์ง€๋งŒ ๋•Œ๋•Œ๋กœ ์›ํ•˜๋Š” ๋ฐ˜ํ™˜๊ฐ’์ด ์•„๋‹Œ ์˜ˆ์ƒ์™ธ์˜ ๊ฐ’์ด ๋‚˜์™”๊ณ , ์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ์ข… ๋ถ„๊ธฐ๋ฌธ์„ ์ถ”๊ฐ€ํ•œ ์ ์ด ์žˆ๋‹ค.

์™œ ๊ทธ๋Ÿฐ ๊ฒƒ์ธ์ง€ ์ •๋ฆฌํ•˜๊ณ , ๊น”๋”ํ•˜๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ์—ˆ๋‹ค.


๐Ÿ“– String.split()

public String[] split(String regex) {
    return split(regex, 0, false);
}

private String[] split(String regex, int limit, boolean withDelimiters) {
    /* fastpath if the regex is a
     * (1) one-char String and this character is not one of the
     *     RegEx's meta characters ".$|()[{^?*+\\", or
     * (2) two-char String and the first char is the backslash and
     *     the second is not the ascii digit or ascii letter.
     */
    char ch = 0;
    if (((regex.length() == 1 &&
            ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
            (regex.length() == 2 &&
                    regex.charAt(0) == '\\' &&
                    (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&
                    ((ch-'a')|('z'-ch)) < 0 &&
                    ((ch-'A')|('Z'-ch)) < 0)) &&
            (ch < Character.MIN_HIGH_SURROGATE ||
                    ch > Character.MAX_LOW_SURROGATE))
    {
        // All the checks above can potentially be constant folded by
        // a JIT/AOT compiler when the regex is a constant string.
        // That requires method inlining of the checks, which is only
        // possible when the actual split logic is in a separate method
        // because the large split loop can usually not be inlined.
        return split(ch, limit, withDelimiters);
    }
    Pattern pattern = Pattern.compile(regex);
    return withDelimiters
            ? pattern.splitWithDelimiters(this, limit)
            : pattern.split(this, limit);
}

private String[] split(char ch, int limit, boolean withDelimiters) {
    int matchCount = 0;
    int off = 0;
    int next;
    boolean limited = limit > 0;
    ArrayList<String> list = new ArrayList<>();
    String del = withDelimiters ? String.valueOf(ch) : null;
    while ((next = indexOf(ch, off)) != -1) {
        if (!limited || matchCount < limit - 1) {
            list.add(substring(off, next));
            if (withDelimiters) {
                list.add(del);
            }
            off = next + 1;
            ++matchCount;
        } else {    // last one
            int last = length();
            list.add(substring(off, last));
            off = last;
            ++matchCount;
            break;
        }
    }
    // If no match was found, return this
    if (off == 0)
        return new String[] {this};

    // Add remaining segment
    if (!limited || matchCount < limit)
        list.add(substring(off, length()));

    // Construct result
    int resultSize = list.size();
    if (limit == 0) {
        while (resultSize > 0 && list.get(resultSize - 1).isEmpty()) {
            resultSize--;
        }
    }
    String[] result = new String[resultSize];
    return list.subList(0, resultSize).toArray(result);
}

 

์ƒ๊ฐ๋ณด๋‹ค ๋ฐฉ๋Œ€ํ•œ ์–‘์˜ ์ฝ”๋“œ๊ฐ€ ์กด์žฌํ•œ๋‹ค.
์šฐ๋ฆฌ๊ฐ€ ์ฃผ์š”ํ•˜๊ฒŒ ์•Œ์•„์•ผ ํ•  ๊ฒƒ์€ limit์ด๋‹ค.


1๏ธโƒฃ ๊ธฐ๋ณธ ๋ฌธ๋ฒ•

String[] result = str.split(String regex);
String[] result = str.split(String regex, int limit);
  • regex
    • split์€ ๋‹จ์ˆœ ๋ฌธ์ž๊ฐ€ ์•„๋‹ˆ๋ผ ์ •๊ทœํ‘œํ˜„์‹(regular expression)์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.
    • ., |, *, ? ๊ฐ™์€ ๋ฉ”ํƒ€๋ฌธ์ž๋Š” ์ด์Šค์ผ€์ดํ”„(\\)ํ•ด์•ผ ๋ฌธ์ž ๊ทธ๋Œ€๋กœ ์ธ์‹๋œ๋‹ค.
    • "a.b".split("\\.") // ["a", "b"]
  • limit
    • ๋‚˜๋ˆŒ ์ตœ๋Œ€ ๊ฐœ์ˆ˜ ๋˜๋Š” ๋นˆ ๋ฌธ์ž์—ด ์ฒ˜๋ฆฌ ๋ฐฉ์‹์— ์˜ํ–ฅ์„ ์ค€๋‹ค.

2๏ธโƒฃ limit ๊ฐ’์— ๋”ฐ๋ฅธ ๋™์ž‘

limit ๊ฐ’๋™์ž‘
> 0 ์ตœ๋Œ€ limit๊ฐœ์˜ ์š”์†Œ ๋ฐ˜ํ™˜.
๋งˆ์ง€๋ง‰ ์š”์†Œ์—๋Š” ๋‚˜๋จธ์ง€ ๋ฌธ์ž์—ด ์ „๋ถ€ ํฌํ•จ.
0 (๊ธฐ๋ณธ๊ฐ’) ๋ฐฐ์—ด ๋๋ถ€๋ถ„์˜ ๋นˆ ๋ฌธ์ž์—ด์„ ์ „๋ถ€ ์ œ๊ฑฐ ํ›„ ๋ฐ˜ํ™˜.
→ ํŒจํ„ด์ด ๋งจ ๋์— ์žˆ์œผ๋ฉด ๋นˆ ๋ฌธ์ž์—ด์ด ์‚ฌ๋ผ์ง
< 0 ๋ฐฐ์—ด ๋์˜ ๋นˆ ๋ฌธ์ž์—ด๋„ ํฌํ•จํ•˜์—ฌ ๋ชจ๋‘ ๋ฐ˜ํ™˜.
→ ๋งจ ์•ž/๋’ค ํŒจํ„ด๋„ ๋†“์น˜์ง€ ์•Š์Œ

 

3๏ธโƒฃ ๋™์ž‘ ์˜ˆ์‹œ

์˜ˆ์‹œ 1 : ๊ธฐ๋ณธ(0)

"EWEW".split("EW") // []
"EWEWE".split("EW") // ["", "", "E"]
  • "EWEW" → ๋งˆ์ง€๋ง‰์ด "EW"๋กœ ๋๋‚˜์„œ ๋นˆ ๋ฌธ์ž์—ด๋งŒ ๋‚จ์Œ → ์ œ๊ฑฐ๋จ → ๊ธธ์ด 0
  • "EWEWE" → ๋งˆ์ง€๋ง‰์ด "E"๋กœ ๋๋‚˜์„œ ๋นˆ ๋ฌธ์ž์—ด ์•„๋‹˜ → ์œ ์ง€๋จ

์˜ˆ์‹œ 2 : limit = -1

"EWEW".split("EW", -1) // ["", "", ""]
"EWEWE".split("EW", -1) // ["", "", "E"]
  • ๋นˆ ๋ฌธ์ž์—ด๋„ ์œ ์ง€ → ํ•ญ์ƒ "EW" ๊ฐœ์ˆ˜๋Š” (๋ฐฐ์—ด ๊ธธ์ด - 1)

์˜ˆ์‹œ 3 : ์ •๊ทœ์‹ ์ฃผ์˜

"a|b|c".split("\\|") // ["a", "b", "c"]
"a|b|c".split("|") // ["a", "|", "b", "|", "c"] // ์ž˜๋ชป๋œ ์‚ฌ์šฉ, '|'๋Š” OR ์—ฐ์‚ฐ์ž

4๏ธโƒฃ ํŒจํ„ด ๊ฐœ์ˆ˜ ์„ธ๊ธฐ ๊ณต์‹

  • ๊ฐœ์ˆ˜ = split(regex, -1).length - 1
  • limit=-1์ด๋ฉด ์•ž๋’ค ํŒจํ„ด์ด ์žˆ์–ด๋„ ๋นˆ ๋ฌธ์ž์—ด์ด ์ œ๊ฑฐ๋˜์ง€ ์•Š์•„ ์ •ํ™•ํ•œ ๊ฐœ์ˆ˜ ๊ณ„์‚ฐ ๊ฐ€๋Šฅ

5๏ธโƒฃ withDelimiters์˜ ์—ญํ• 

1. ๋”œ๋ฆฌ๋ฏธํ„ฐ์˜ ์˜๋ฏธ

  • split("EW", ...)๋ผ๊ณ  ํ•˜๋ฉด "EW"๊ฐ€ ๋”œ๋ฆฌ๋ฏธํ„ฐ์ด๋‹ค.
  • ๋ฌธ์ž์—ด์„ ์ž˜๋ผ๋‚ผ ๋•Œ "EW"๊ฐ€ ๋‚˜ํƒ€๋‚˜๋Š” ์œ„์น˜๋ฅผ ๊ฒฝ๊ณ„๋กœ ๋‚˜๋ˆ•๋‹ˆ๋‹ค"๋ผ๋Š” ๋œป์ด๋‹ค.

2. withDelimiters์˜ ์—ญํ• 

Java ํ‘œ์ค€ String.split()์—๋Š” withDelimiters ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์ง€๋งŒ,
์ด๊ฑด ์‚ฌ์šฉ์ž ์ •์˜ ๋ฉ”์„œ๋“œ๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ตฌํ˜„์—์„œ ์ถ”๊ฐ€ํ•œ ์˜ต์…˜์ผ ๊ฐ€๋Šฅ์„ฑ์ด ํฌ๋‹ค.

withDelimiters = true
→ ๊ฒฐ๊ณผ ๋ฐฐ์—ด์— ๊ตฌ๋ถ„์ž(๋”œ๋ฆฌ๋ฏธํ„ฐ)๋„ ํฌํ•จ.

withDelimiters = false
→ ๊ฒฐ๊ณผ ๋ฐฐ์—ด์—๋Š” ๊ตฌ๋ถ„์ž ์—†์ด ์ž˜๋ฆฐ ๋‚ด์šฉ๋งŒ ํฌํ•จ.
(ํ‘œ์ค€ String.split()์ด ๋ฐ”๋กœ ์ด ๋ฐฉ์‹)


์˜ˆ์‹œ (withDelimiters ๊ฐœ๋… ์‹œ๋ฎฌ๋ ˆ์ด์…˜)

String s = "EWEWE";
s.split("EW", -1) → ["", "", "E"]
s.splitWithDelimiters("EW", -1) → ["", "EW", "", "EW", "E"]
  • withDelimiters=true์ธ ๊ฒฝ์šฐ "EW"๋ผ๋Š” ๊ตฌ๋ถ„์ž ์ž์ฒด๋„ ๋ฐฐ์—ด์— ๋“ค์–ด๊ฐ„๋‹ค.
  • ์ •๊ทœ์‹ ๋งค์นญ์„ ์บก์ฒ˜ ๊ทธ๋ฃน์œผ๋กœ ์žก๊ณ  ๊ฒฐ๊ณผ์— ํฌํ•จ์‹œํ‚ค๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ ๊ฐ€๋Šฅ.
  • split์„ ์‚ฌ์šฉ ์‹œ private splitWithDelimiters๋ฅผ false๋กœ ํ˜ธ์ถœํ•˜๊ณ , public splitWithDelimiters ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์•ผ private splitWithDelimiters๋ฅผ true๋กœ ํ˜ธ์ถœ๋œ๋‹ค.
    • ๋ฉ”์„œ๋“œ๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅด๋‹ค!