주어진 문자열에는 숫자와 알파벳이 뒤섞여 있는 경우가 많습니다. 이번 글에서는 문자열 안에서 알파벳 또는 숫자가 연속으로 이어지는 부분 문자열(Substring) 중 가장 긴 것을 찾는 두 가지 방법을 살펴보겠습니다.
방법 1: re 모듈 활용하기
정규표현식(regular expression)을 다루는 re 모듈을 사용하면 매우 간결하게 문제를 해결할 수 있습니다. findall 함수로 알파벳(\D+)과 숫자(\d+)가 연속된 모든 부분 문자열을 추출한 뒤, max 함수에 len을 기준 키로 지정하여 그중 길이가 가장 긴 부분 문자열만 선택하는 방식입니다.
예제 코드
import re
def longSubstring(str):
letter = max(re.findall(r'\D+', str), key=len)
digit = max(re.findall(r'\d+', str), key=len)
return letter, digit
str = 'Hello 459 Congratulations! 234'
print(longSubstring(str))
실행 결과
위 코드를 실행하면 아래와 같은 결과가 출력됩니다.
(' Congratulations! ', '459')
참고: 정규표현식의 \D+는 '숫자가 아닌 모든 문자'를 의미하기 때문에 공백과 특수문자까지 함께 포함되어, 앞뒤 공백이 포함된 ' Congratulations! '가 반환됩니다. 순수하게 알파벳만 필요하다면 후처리 과정이 필요합니다.
방법 2: len() 함수와 while 반복문 활용하기
이 방법은 직관적이지만 상대적으로 느린 접근 방식입니다. while 반복문으로 문자열을 한 글자씩 순회하면서 알파벳 구간과 숫자 구간의 길이를 각각 측정하고, 지금까지 발견한 최대 길이와 비교하여 더 긴 부분 문자열로 계속 갱신하는 원리입니다. 알파벳도 아니고 숫자도 아닌 문자(공백, 특수문자 등)는 건너뛰어 처리합니다.
예제 코드
def longSubstring(s):
max_letterSeq = ''
max_digitSeq = ''
i = 0
while (i < len(s)):
current_letterSeq = ''
current_digitSeq = ''
# 알파벳 구간 탐색
while (i < len(s) and s[i].isalpha()):
current_letterSeq += s[i]
i += 1
# 숫자 구간 탐색
while (i < len(s) and s[i].isdigit()):
current_digitSeq += s[i]
i += 1
# 알파벳도 숫자도 아닌 경우 건너뛰기
if (i < len(s) and not (s[i].isdigit())
and not (s[i].isalpha())):
i += 1
# 최대 길이 갱신
if (len(current_letterSeq) > len(max_letterSeq)):
max_letterSeq = current_letterSeq
if (len(current_digitSeq) > len(max_digitSeq)):
max_digitSeq = current_digitSeq
return max_letterSeq, max_digitSeq
str = 'Hello 459 Congratulations! 234'
print(longSubstring(str))
실행 결과
위 코드를 실행하면 아래와 같은 결과가 출력됩니다.
('Congratulations', '459')
두 방법의 차이: while 반복문 방식은 isalpha()를 사용해 순수한 알파벳만 판별하므로 공백이 제외된 'Congratulations'가 반환됩니다. 반면 re 모듈 방식은 더 짧은 코드로 빠르게 구현할 수 있다는 장점이 있습니다. 상황과 요구 사항에 맞게 적절한 방법을 선택하시면 됩니다.