카테고리 없음

✂️ 루비 문자열 분리(split)와 치환(gsub/sub) 마스터하기: 데이터 가공의 핵심!

프로그래밍 멘토 2025. 3. 31. 20:01

🎯 이번 시간 학습 목표

지난 시간에는 문자열 안에서 특정 내용을 찾거나(include?, start_with?, end_with?) 원하는 위치의 글자를 가져오는([]) 방법을 익혔습니다. 이번 시간에는 문자열을 자유자재로 편집하는, 그야말로 '문자열 마법' 같은 기술들을 배워볼 거예요! ✨

  • split: 하나의 문자열을 특정 기준에 따라 여러 조각으로 분리하여 배열(Array) 만들기
  • gsub: 문자열 안에서 특정 패턴과 일치하는 모든 부분을 찾아 다른 내용으로 치환하기
  • sub: 문자열 안에서 특정 패턴과 일치하는 첫 번째 부분만 찾아 다른 내용으로 치환하기

이 세 가지 메소드는 데이터를 원하는 형태로 가공하거나 정리할 때 정말 정말 많이 사용되는 핵심 기능입니다. CSV 데이터 처리, 로그 분석, 텍스트 정제 등 활용 분야가 무궁무진하죠! 자, 이제 강력한 문자열 편집 도구를 손에 넣어볼까요? 🚀

✨ 오늘 배울 내용 미리보기

함수/메소드 설명 간단 예시
split(pattern = nil, limit = 0) 문자열을 pattern 기준으로 조각내어 배열(Array)로 반환합니다. limit으로 조각 개수를 제한할 수 있습니다. "a,b,c".split(",")["a", "b", "c"]
gsub(pattern, replacement)
gsub(pattern) { |match| block }
문자열 내에서 pattern과 일치하는 모든 부분을 replacement 또는 블록 실행 결과로 치환합니다. "hello".gsub("l", "*")"he**o"
sub(pattern, replacement)
sub(pattern) { |match| block }
문자열 내에서 pattern과 일치하는 첫 번째 부분만 replacement 또는 블록 실행 결과로 치환합니다. "hello".sub("l", "*")"he*lo"

📌 pattern은 문자열 또는 정규표현식(Regexp)이 될 수 있습니다. 아래에서 더 다양한 활용법을 살펴볼게요!


✂️ 문자열 쪼개기 대작전! `split`

split 메소드는 마치 잘 드는 가위처럼, 문자열을 지정된 구분자(delimiter)를 기준으로 여러 조각으로 나누어 배열(Array)에 담아줍니다. 💥

기본 사용법: 공백 기준 분리

아무런 인자 없이 split을 호출하면, 기본적으로 공백(스페이스, 탭, 줄바꿈 등)을 기준으로 문자열을 나눕니다. 연속된 공백은 하나의 구분자로 취급하며, 앞뒤 공백은 무시됩니다.

sentence = "  Ruby   is \n fun!  "
words = sentence.split
p words # 출력 결과: ["Ruby", "is", "fun!"]

구분자(Delimiter) 지정하기

가장 흔하게 사용되는 방법은 특정 문자열(예: 콤마,, 하이픈- 등)을 구분자로 직접 지정하는 것입니다.

csv_data = "apple,banana,cherry"
fruits = csv_data.split(",")
p fruits # 출력 결과: ["apple", "banana", "cherry"]

phone_number = "010-1234-5678"
parts = phone_number.split("-")
p parts # 출력 결과: ["010", "1234", "5678"]

# 구분자가 연속으로 나오면 빈 문자열("")이 포함될 수 있습니다.
data = "a,,b,c"
p data.split(",") # 출력 결과: ["a", "", "b", "c"]

정규표현식 활용하기 🧠

더 복잡한 규칙으로 문자열을 나누고 싶다면 정규표현식(Regexp)을 사용할 수 있습니다. 예를 들어, 콤마(,) 또는 세미콜론(;)을 모두 구분자로 사용하고 싶을 때 유용합니다.

mixed_data = "one,two;three four"
# 콤마, 세미콜론, 공백 중 하나를 기준으로 분리
items = mixed_data.split(/[,;\s]+/) # 정규표현식 /[,;\s]+/ 사용
p items # 출력 결과: ["one", "two", "three", "four"]

(정규표현식은 매우 강력하지만 별도의 학습이 필요합니다. 여기서는 간단한 예시만 보여드릴게요!)

분할 개수 제한하기 (`limit`)

두 번째 인자로 limit 값을 주면, 최대 몇 개의 조각으로 나눌지 제한할 수 있습니다.

  • limit > 0: 최대 limit 개의 조각으로 나눕니다. 마지막 조각에는 나머지 모든 부분이 포함됩니다.
  • limit = 0 (기본값): 제한 없이 모든 조각으로 나눕니다. 단, 마지막에 빈 문자열이 있으면 제거됩니다.
  • limit < 0: 제한 없이 모든 조각으로 나누며, 마지막에 빈 문자열이 있어도 제거하지 않습니다.
data = "a,b,c,d,e"

p data.split(",", 3)  # 출력 결과: ["a", "b", "c,d,e"] (최대 3개)
p data.split(",", 0)  # 출력 결과: ["a", "b", "c", "d", "e"] (기본 동작)

trailing_empty = "a,b,"
p trailing_empty.split(",", 0) # 출력 결과: ["a", "b"] (마지막 빈 문자열 제거됨)
p trailing_empty.split(",", -1) # 출력 결과: ["a", "b", ""] (마지막 빈 문자열 유지됨)
🤔 어? 구분자로 지정한 문자가 결과에 포함되지 않아요!
네, 맞습니다! split은 기본적으로 구분자 자체는 결과 배열에 포함시키지 않고, 구분자를 기준으로 잘라진 '내용'들만 배열 요소로 만듭니다.

🔍 찾아서 바꿔줘! `gsub` & `sub`

gsubsub는 문자열 내에서 특정 패턴을 찾아 다른 내용으로 '치환'(바꾸기)하는 메소드입니다. 마치 문서 편집기의 '찾아 바꾸기' 기능과 비슷하죠! 😉

`gsub`: 일치하는 모든 것을 바꿔라! (Global Substitution)

gsub은 문자열 전체를 훑으면서 패턴과 일치하는 부분을 모두 찾아서 지정된 내용으로 바꿉니다.

text = "I love Ruby, Ruby is amazing!"

# "Ruby"를 "Python"으로 모두 바꾸기
new_text = text.gsub("Ruby", "Python")
puts new_text # 출력 결과: "I love Python, Python is amazing!"

# 정규표현식 사용: 모든 공백을 밑줄(_)로 바꾸기
spaced = "hello world wide"
puts spaced.gsub(/\s+/, "_") # 출력 결과: "hello_world_wide"

# 블록 사용: 찾은 숫자를 2배로 만들기
numbers = "Score: 100, Level: 5"
doubled = numbers.gsub(/\d+/) { |match| (match.to_i * 2).to_s }
puts doubled # 출력 결과: "Score: 200, Level: 10"

블록을 사용하면 찾은 내용(match)을 기반으로 동적인 치환 로직을 구현할 수 있어 매우 유용합니다!

`sub`: 딱 한 번만 바꿔줘! (Substitution)

subgsub과 비슷하지만, 패턴과 일치하는 부분을 찾으면 **가장 먼저 찾은 딱 한 군데만** 바꾸고 작업을 멈춥니다.

text = "I love Ruby, Ruby is amazing!"

# 첫 번째 "Ruby"만 "Python"으로 바꾸기
new_text = text.sub("Ruby", "Python")
puts new_text # 출력 결과: "I love Python, Ruby is amazing!"

# 정규표현식 사용: 첫 번째 공백만 밑줄(_)로 바꾸기
spaced = "hello world wide"
puts spaced.sub(/\s+/, "_") # 출력 결과: "hello_world wide"

❗ 원본 변경 버전: `gsub!` & `sub!`

split과 마찬가지로 gsubsub도 기본적으로는 원본 문자열을 변경하지 않고, 치환된 새로운 문자열을 반환합니다. 원본 문자열 자체를 변경하고 싶다면 gsub! 또는 sub! 메소드를 사용해야 합니다. (역시나 주의해서 사용하세요!)

my_string = "apple banana apple"
my_string.gsub!("apple", "orange") # 원본 변경!
puts my_string # 출력 결과: "orange banana orange"

my_string = "apple banana apple"
my_string.sub!("apple", "orange") # 원본 변경!
puts my_string # 출력 결과: "orange banana apple"
🤔 아무것도 안 바뀌는데요?
gsub이나 sub를 사용했는데 문자열에 변화가 없다면, 다음 경우들을 확인해보세요.
  • 패턴 불일치: 바꾸려는 패턴(문자열 또는 정규표현식)이 문자열 내에 존재하지 않는 경우.
  • 대소문자 구분: 패턴이 문자열일 경우, 대소문자가 정확히 일치해야 합니다. (정규표현식에서는 옵션으로 대소문자 무시 가능)
  • 정규표현식 오류: 정규표현식 패턴 자체에 오류가 있거나, 의도와 다른 패턴을 작성했을 수 있습니다.
특히 정규표현식의 특수 문자(., *, +, ?, [], {}, (), |, ^, $, \)는 특별한 의미를 가지므로, 이 문자 자체를 찾고 싶다면 백슬래시(\)를 이용해 이스케이프(escape) 처리해야 합니다. (예: .을 찾으려면 /\./)

✨ 문자열 편집 스킬 만렙 달성! ✨

축하드립니다! 🎉 여러분은 이제 루비 문자열을 원하는 대로 쪼개고(split), 필요한 부분을 쏙쏙 골라 바꾸는(gsub, sub) 강력한 편집 기술을 손에 넣었습니다! 그야말로 문자열 연금술사가 된 기분이 들지 않나요? 😉

이 기술들은 단순히 문자열을 보기 좋게 만드는 것을 넘어, 복잡한 데이터를 분석하고 가공하는 프로그래밍의 핵심적인 부분입니다. 예를 들어, 콤마로 구분된 데이터(CSV) 파일을 읽어 각 항목을 분리하거나, 웹 페이지에서 특정 정보만 추출하고 형식을 변경하는 등의 작업에 필수적으로 사용됩니다.

다음 시간에는 문자열의 특정 부분을 잘라내는 또 다른 방법(slice), 문자열을 숫자로 변환하는 방법(to_i, to_f), 그리고 문자열을 원본에서 직접 이어 붙이는(concat) 기술들을 배우며 루비 문자열 다루기의 여정을 마무리할 예정입니다. 마지막까지 함께 힘내봅시다! 💪