Java programming

String ํด๋ž˜์Šค์˜ replace() ์™€ replaceAll() ์ฐจ์ด (feat. replaceFirst())

ํ”„๋กœ๊ทธ๋ž˜๋จธ ์˜ค์›” 2024. 7. 7.

๊ฐœ์š”

์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ ์Šคํ„ฐ๋””๋ฅผ ํ•˜๋‹ค๊ฐ€ String ํด๋ž˜์Šค์˜ replace() ๋ฉ”์†Œ๋“œ์™€ replaceAll() ์„ ์ฐฉ๊ฐํ•ด์„œ ๊ธ€์„ ์“ฐ๊ฒŒ ๋๋‹ค.

 

https://school.programmers.co.kr/learn/courses/30/lessons/17683

 

ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค

์ฝ”๋“œ ์ค‘์‹ฌ์˜ ๊ฐœ๋ฐœ์ž ์ฑ„์šฉ. ์Šคํƒ ๊ธฐ๋ฐ˜์˜ ํฌ์ง€์…˜ ๋งค์นญ. ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค์˜ ๊ฐœ๋ฐœ์ž ๋งž์ถคํ˜• ํ”„๋กœํ•„์„ ๋“ฑ๋กํ•˜๊ณ , ๋‚˜์™€ ๊ธฐ์ˆ  ๊ถํ•ฉ์ด ์ž˜ ๋งž๋Š” ๊ธฐ์—…๋“ค์„ ๋งค์นญ ๋ฐ›์œผ์„ธ์š”.

programmers.co.kr

 

ํ•ด๋‹น ๋ฌธ์ œ์—์„œ ๊ธ€์ž๋ฅผ ๋‹ค๋ฅธ ๊ธ€์ž๋กœ ๋ฐ”๊ฟ”์•ผํ•˜๋Š” ์ผ์ด ์žˆ์—ˆ๋Š”๋ฐ, ํ•ด๋‹นํ•˜๋Š” ๋ชจ๋“  ๊ธ€์ž๋ฅผ ๋‹ค๋ฅธ ๊ธ€์ž๋กœ ๋ฐ”๊ฟ”์•ผํ–ˆ๋‹ค. ๋‹น์—ฐํžˆ replace ๊ด€๋ จ ํ•จ์ˆ˜๋ฅผ ์•Œ๊ธฐ์— replaceAll() ์„ ์จ์„œ ํƒ€์ผ“ ๋ฌธ์ž์—ด์„ ์ƒˆ๋กœ์šด ๋ฌธ์ž์—ด๋กœ ๋ฐ”๊ฟ”์ฃผ๋ ค๊ณ  ํ–ˆ๋‹ค.

 

ํŒ€์›๊ณผ ํ’€์ด ๊ณต์œ ๋ฅผ ํ•˜๋Š”๋ฐ, ํŒ€์›์€ replaceAll() ์„ ์“ฐ์ง€ ์•Š๊ณ  replace() ์„ ์‚ฌ์šฉํ–ˆ๋‹ค.

replace() ํ•จ์ˆ˜๋Š” ํƒ€๊ฒŸ์— ํ•ด๋‹นํ•˜๋Š” ์ฒซ๋ฒˆ ์งธ ๋“ฑ์žฅํ•˜๋Š” ๋ฌธ์ž์—ด๋งŒ ์ƒˆ๋กœ์šด ๋ฌธ์ž์—ด๋กœ ๋ฐ”๊ฟ”์ฃผ๋Š” ์ค„ ์•Œ์•˜๊ณ , ๋˜ ๋‹ค๋ฅธ ํŒ€์› ๋˜ํ•œ ๋‚˜์™€ ๊ฐ™์ด ์ƒ๊ฐํ•˜๊ณ  ์žˆ์—ˆ๋‹ค.
ํ•˜์ง€๋งŒ, replace() ํ•จ์ˆ˜๋„ ํƒ€์ผ“์— ํ•ด๋‹นํ•˜๋Š” ๋ฌธ์ž์—ด์„ ๋ชจ๋‘ ์ƒˆ๋กœ์šด ๋ฌธ์ž์—ด๋กœ ๋ฐ”๊ฟ”์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ํ–ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ๋‹ค๋ฅธ ์ ์€ ๋ฌด์—‡์ผ๊นŒ? 

 

replace() vs replaceAll()

String ํด๋ž˜์Šค์˜ replace ํ•จ์ˆ˜์™€ replaceAll ํ•จ์ˆ˜๋Š” ๋ชจ๋‘ ๋ฌธ์ž์—ด ๋‚ด์—์„œ ํŠน์ • ๋ฌธ์ž์—ด์„ ๋‹ค๋ฅธ ๋ฌธ์ž์—ด๋กœ ๋Œ€์ฒดํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‘ ํ•จ์ˆ˜ ์‚ฌ์ด์—๋Š” ์ค‘์š”ํ•œ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค.

๋จผ์ € ์˜ˆ์ œ๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด์„œ ๊ด€๋ จ ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ดํŽด ๋ณด์•˜๋‹ค.

 

 

replace() ๋ฉ”์†Œ๋“œ

  • replace(char oldChar, char newChar): ๋ฌธ์ž์—ด ๋‚ด์—์„œ ์ง€์ •๋œ ๋ฌธ์ž oldChar๋ฅผ ์ƒˆ๋กœ์šด ๋ฌธ์ž newChar๋กœ ๋Œ€์ฒดํ•œ๋‹ค.
  • replace(CharSequence target, CharSequence replacement): ๋ฌธ์ž์—ด ๋‚ด์—์„œ ์ง€์ •๋œ ๋ฌธ์ž ์‹œํ€€์Šค target์„ ์ƒˆ๋กœ์šด ๋ฌธ์ž ์‹œํ€€์Šค replacement๋กœ ๋Œ€์ฒดํ•œ๋‹ค.
  • ์ด ๋ฉ”์„œ๋“œ๋“ค์€ ์ •๊ทœ ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋‹จ์ˆœํžˆ ๋ฌธ์ž์—ด์„ ์ˆœํšŒํ•˜๋ฉด์„œ ํŠน์ • ๋ฌธ์ž๋‚˜ ๋ฌธ์ž์—ด์„ ๋‹ค๋ฅธ ๋ฌธ์ž๋‚˜ ๋ฌธ์ž์—ด๋กœ ๊ต์ฒดํ•œ๋‹ค.

 

์ž๋ฐ” 11 ๊ธฐ์ค€ ๋‚ด๋ถ€ ๊ตฌํ˜„

1
2
3
4
5
6
7
8
9
10
    public String replace(char oldChar, char newChar) {
        if (oldChar != newChar) {
            String ret = isLatin1() ? StringLatin1.replace(value, oldChar, newChar)
                                    : StringUTF16.replace(value, oldChar, newChar);
            if (ret != null) {
                return ret;
            }
        }
        return this;
    }
cs

๋‚ด๋ถ€์—์„œ ํ˜ธ์ถœํ•˜๋Š” replace ๋ฉ”์†Œ๋“œ๋Š” ๋ฐ”์ดํŠธ ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฌธ์ž์—ด ์กฐ์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ, ํŠน์ • ๋ฌธ์ž๋ฅผ ๋‹ค๋ฅธ ๋ฌธ์ž๋กœ ๊ต์ฒดํ•œ๋‹ค. ํŒŒ๋ผ๋ฏธํ„ฐ์— ์žˆ๋Š” value ๋ณ€์ˆ˜๊ฐ€ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜์ธ byte[] ์ด๋‹ค. 

LATIN1 ์ธ์ฝ”๋”ฉ๊ณผ UTF-16 ์ธ์ฝ”๋”ฉ์„ ๋ชจ๋‘ ๊ณ ๋ คํ•˜์—ฌ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•จ์œผ๋กœ ๋ฌธ์ž์—ด์„ ๋ฐ”์ดํŠธ ๋ฐ์ดํ„ฐ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๋ฌธ์ž์—ด ์กฐ์ž‘์„ ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. ์ธ์ฝ”๋”ฉ ๋ฐฉ์‹์—๋„ ์—ฌ๋Ÿฌ ๋ฐฉ์‹์ด ์žˆ๋“ฏ์ด ์ธ์ฝ”๋”ฉ ๋ฐฉ์‹์— ๋งž์ถฐ ๋ฌธ์ž์—ด์„ ๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•จ์ด๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    public String replace(CharSequence target, CharSequence replacement) {
        String tgtStr = target.toString();
        String replStr = replacement.toString();
        int j = indexOf(tgtStr);
        if (j < 0) {
            return this;
        }
        int tgtLen = tgtStr.length();
        int tgtLen1 = Math.max(tgtLen, 1);
        int thisLen = length();
 
        int newLenHint = thisLen - tgtLen + replStr.length();
        if (newLenHint < 0) {
            throw new OutOfMemoryError();
        }
        StringBuilder sb = new StringBuilder(newLenHint);
        int i = 0;
        do {
            sb.append(this, i, j).append(replStr);
            i = j + tgtLen;
        } while (j < thisLen && (j = indexOf(tgtStr, j + tgtLen1)) > 0);
        return sb.append(this, i, thisLen).toString();
    }
cs

 

์‚ฌ์šฉ ์˜ˆ์‹œ

class Main {
    public static void main(String[] args) {
        String str = "hello world";
        String result = str.replace('o', 'a');
        System.out.println(result); // "hella warld"

        String str2 = "hello world";
        String result2 = str2.replace("world", "Java");
        System.out.println(result2); // "hello Java"
    }
}

 

replaceAll() ๋ฉ”์†Œ๋“œ

  • replaceAll(String regex, String replacement): ๋ฌธ์ž์—ด ๋‚ด์—์„œ ์ง€์ •๋œ ์ •๊ทœ ํ‘œํ˜„์‹ regex์— ์ผ์น˜ํ•˜๋Š” ๋ชจ๋“  ๋ถ€๋ถ„์„ ์ƒˆ๋กœ์šด ๋ฌธ์ž์—ด replacement๋กœ ๋Œ€์ฒดํ•œ๋‹ค.
  • ์ด ๋ฉ”์„œ๋“œ๋Š” ์ •๊ทœ ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ๋” ๋ณต์žกํ•œ ๋Œ€์ฒด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ž๋ฐ” 11 ๊ธฐ์ค€ ๋‚ด๋ถ€ ๊ตฌํ˜„

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    public String replaceAll(String regex, String replacement) {
        return Pattern.compile(regex).matcher(this).replaceAll(replacement);
    }
 
    public String replaceAll(String replacement) { //์œ„์—์„œ ํ˜ธ์ถœํ•œ replaceAll() 
        reset();
        boolean result = find();
        if (result) {
            StringBuilder sb = new StringBuilder();
            do {
                appendReplacement(sb, replacement);
                result = find();
            } while (result);
            appendTail(sb);
            return sb.toString();
        }
        return text.toString();
    }
cs

 

์œ„ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด replaceAll์€ Pattern.compile(regex)๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ •๊ทœ ํ‘œํ˜„์‹์„ ์ปดํŒŒ์ผํ•œ ํ›„, Matcher ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ replaceAll ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. replaceAll ๋ฉ”์„œ๋“œ๋Š” ์ •๊ทœ ํ‘œํ˜„์‹๊ณผ ์ผ์น˜ํ•˜๋Š” ๋ชจ๋“  ๋ถ€๋ถ„์„ ๋Œ€์ฒด ๋ฌธ์ž์—ด๋กœ ๋ฐ”๊พผ๋‹ค.

 

์‚ฌ์šฉ์˜ˆ์‹œ

class Main {
    public static void main(String[] args) {
        String str = "hello world";
        String result = str.replaceAll("o", "a");
        System.out.println(result); // "hella warld"

        String str2 = "hello123world";
        String result2 = str2.replaceAll("\\d", "X"); // ์ •๊ทœ ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ์ˆซ์ž๋ฅผ ๋Œ€์ฒด
        System.out.println(result2); // "helloXXXworld"
    }
}

 

 

์„ฑ๋Šฅ์ฐจ์ด

  • replace ๋ฉ”์„œ๋“œ์˜ ์„ฑ๋Šฅ
    • ๋‹จ์ˆœํžˆ ๋ฌธ์ž์—ด์„ ์ˆœํšŒํ•˜๋ฉด์„œ ํŠน์ • ๋ฌธ์ž๋‚˜ ๋ฌธ์ž์—ด์„ ๋‹ค๋ฅธ ๋ฌธ์ž๋‚˜ ๋ฌธ์ž์—ด๋กœ ๊ต์ฒดํ•œ๋‹ค.
    • ์ •๊ทœ ํ‘œํ˜„์‹์„ ์ปดํŒŒ์ผํ•˜๊ฑฐ๋‚˜ ๋งค์นญํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฏ€๋กœ, ๋งค์šฐ ํšจ์œจ์ ์ด๋‹ค.
    • ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(n)์ด๋‹ค.
  • replaceAll ๋ฉ”์„œ๋“œ์˜ ์„ฑ๋Šฅ
    • ์ •๊ทœ ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฌธ์ž์—ด์„ ๋งค์นญํ•˜๊ณ  ๋Œ€์ฒดํ•œ๋‹ค.
    • ์ •๊ทœ ํ‘œํ˜„์‹์„ ์ปดํŒŒ์ผํ•˜๊ณ  ๋งค์นญํ•˜๋Š” ๊ณผ์ •์ด ์ถ”๊ฐ€๋˜๋ฏ€๋กœ, ์ผ๋ฐ˜์ ์œผ๋กœ ๋” ๋งŽ์€ ์‹œ๊ฐ„์ด ์†Œ์š”๋œ๋‹ค.
    • ์ •๊ทœ ํ‘œํ˜„์‹์„ ๋งค์นญํ•˜๋Š” ๊ณผ์ •์€ ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ๋ณต์žก๋„๊ฐ€ ๋‹ค๋ฅด๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ O(n) ์ด์ƒ์˜ ๋ณต์žก๋„๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.

 

 

+ ) replaceFirst()

replaceFirst(String regex, String replacement): ๋ฌธ์ž์—ด ๋‚ด์—์„œ ์ง€์ •๋œ ์ •๊ทœ ํ‘œํ˜„์‹ regex์— ์ผ์น˜ํ•˜๋Š” ์ฒซ ๋ฒˆ์งธ ๋ถ€๋ถ„์„ ์ƒˆ๋กœ์šด ๋ฌธ์ž์—ด replacement๋กœ ๋Œ€์ฒดํ•œ๋‹ค. replaceAll๊ณผ ์œ ์‚ฌํ•˜์ง€๋งŒ ์ฒซ ๋ฒˆ์งธ ์ผ์น˜๋งŒ ๋Œ€์ฒดํ•œ๋‹ค๋Š” ์ ์ด ๋‹ค๋ฅด๋‹ค.

 

์ž๋ฐ” 11 ๊ธฐ์ค€ ๋‚ด๋ถ€ ๊ตฌํ˜„

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    public String replaceFirst(String regex, String replacement) {
        return Pattern.compile(regex).matcher(this).replaceFirst(replacement);
    }
 
    public String replaceFirst(String replacement) { // ํ˜ธ์ถœํ•œ replaceFirst() ๋ฉ”์†Œ๋“œ์ด๋‹ค.
        if (replacement == null)
            throw new NullPointerException("replacement");
        reset();
        if (!find())
            return text.toString();
        StringBuilder sb = new StringBuilder();
        appendReplacement(sb, replacement);
        appendTail(sb);
        return sb.toString();
    }
cs

 

์‚ฌ์šฉ์˜ˆ์‹œ

public class Main {
    public static void main(String[] args) {
        String str = "hello123world456";
        String result = str.replaceFirst("\\d", "X"); // ์ •๊ทœ ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฒซ ๋ฒˆ์งธ ์ˆซ์ž๋งŒ ๋Œ€์ฒด
        System.out.println(result); // "helloX23world456"
    }
}

 

๋Œ“๊ธ€