카테고리 없음

스파르타 AI-8기 TIL(11/27) -> 코드 공부....

kimjunki-8 2024. 11. 27. 22:04

나도 솔직히 맘 놓고 공부하고 싶지만.....팀과제가 그걸 허락하지 않는걸....

        folder = os.listdir('C:/Users/kevinkim/Desktop/results/')
        for index, folder_list in enumerate(folder, start = 1):
            print(f'질문: {index} 대답:{folder_list}')
        choose = input('혹시 다시 보고 싶은 답변이 있으시나요? 원하는 번호를 선택해 주세요!: ')
        for index, file_name in enumerate(folder, start = 1):
            new_file = os.path.join('C:/Users/kevinkim/Desktop/results/' + file_name) 
            if index == int(choose):
                with open(new_file, 'r', encoding= 'utf-8') as file:
                    file_content = file.read()
                    file_name = file_name.split('_')[0]
                    print(f"\n질문 : {file_name} \n대답 : {file_content}")
                break
        decision = input('''답변이 마음에 드셨나요?
            1. 주제 다시 고르기
            2. 나가기(quit)
            3. 답변 삭제하기
            ''')
        if decision in ['1', '주제 다시 고르기']:
            print('주제 고르기로 넘어갑니다')
            continue
        
        elif decision in ['2', 'quit',  'exit',  'out', '나가기']:
            print('즐거운 시간 되셨길 바랍니다!')
            break
            
        elif decision in ['3', '답변 삭제하기', '답변삭제하기']:
            folder = os.listdir('C:/Users/kevinkim/Desktop/results/')
            for index, file_name in enumerate(folder, start = 1):
                print(f'질문: {index} 대답:{file_name}')
            choose_file = input('삭제할 파일을 선택하세요!')
            for index, file_name in enumerate(folder, start = 1):
                if index == int(choose_file):
                    new_file = os.path.join('C:/Users/kevinkim/Desktop/results/' + file_name)
                    file_name = file_name.split('_')[0]
                    os.remove(new_file)
                    print('해당 답변은 삭제되었습니다')
                break
            
    else:
        print('정확한 주제를 골라주세요!')
        time.sleep(2)
        print('프로세스 다시 가동 중...')
        time.sleep(1)
        print('프로세스 가동완료...')
        time.sleep(1)
        continue
    
    query = input('질문을 입력하세요 : ')
    query = filename_preprocessing(query)
    if query.lower() in ['10', 'quit',  'exit',  'out', '나가기', '끄기']:
        print('이용해 주셔서 감사합니다.')
        break
    if query.lower() in ['back']:
        continue
    chat_history.add_user_message(query)

    duplicate_question = os.listdir('C:/Users/kevinkim/Desktop/prompt/')
    pattern = r'_\d{4}-\d{2}-d{2}_\d{2}_\d{2}$'
    duplicate_folder = []
    for list in duplicate_folder:
        preprocessing_file = re.sub(pattern, '', duplicate_question)
        preprocessing_file = [file.replace('.txt', '') for file in preprocessing_file if file.endswith('.txt')]
        duplicate_folder.append(preprocessing_file)
        for text in duplicate_folder:
            try:
                if query.lower() in text:
                    print('이미 물어본 질문입니다. 다른 질문을 해주세요')
                    continue
            except Exception as e:
                print(f'에러발생: {e}')

하지만 팀 과제를 적을때도 배우는 것은 항상 있는 법.

re.sub에 대해 조금 더 알아가는 시간을 가졌다.

re.sub(pattern, repl, string, count=0, flags=0)
pattern
치환할 대상을 지정하는 정규 표현식 패턴입니다.
예: "a.b"는 "a"와 "b" 사이에 아무 문자 하나가 오는 문자열을 의미합니다.

repl
치환할 문자열 또는 함수입니다.
문자열일 경우: 패턴에 매칭된 부분이 이 문자열로 대체됩니다.
함수일 경우: 매칭된 객체를 입력으로 받아 대체 문자열을 반환합니다.

string
치환을 수행할 대상 문자열입니다.

count (기본값: 0)
치환할 최대 횟수를 지정합니다.
0일 경우: 문자열 전체에서 패턴을 찾고 모두 치환합니다.

flags
정규 표현식에서 추가적인 플래그를 지정합니다.
예: re.IGNORECASE(대소문자 무시), re.MULTILINE(여러 줄 매칭), re.DOTALL(줄바꿈 문자 포함 매칭) 등.
flags 사용법
기본
import re

text = "apple banana apple"
result = re.sub(r"apple", "orange", text)
print(result)  # orange banana orange


대소문자 무시

text = "Apple apple APPLE"
result = re.sub(r"apple", "fruit", text, flags=re.IGNORECASE)
print(result)  # fruit fruit fruit


함수 사용

def replace_func(match):
    return match.group(0).upper()

text = "hello world"
result = re.sub(r"\w+", replace_func, text)
print(result)  # HELLO WORLD


치환 횟수 제한

text = "one two three one two three"
result = re.sub(r"one", "1", text, count=1)
print(result)  # 1 two three one two three


여러 줄 치환

text = """Line1
Line2
Line3"""
result = re.sub(r"^Line", "Row", text, flags=re.MULTILINE)
print(result)
# Row1
# Row2
# Row3

 

정규 표현식 기능
주요 메타 문자와 패턴 기호
1. 문자 관련 메타 문자
\w
단어 문자를 나타냅니다.
알파벳 대소문자, 숫자, 밑줄(_)을 포함합니다.
[a-zA-Z0-9_]와 동일한 의미.
예: "Hello_123"에서 \w+는 "Hello_123"과 매칭.

\W
단어 문자가 아닌 것을 나타냅니다.
[^a-zA-Z0-9_]와 동일한 의미.
예: "Hello, World!"에서 \W+는 ", " 및 "!"와 매칭.

\d
숫자를 나타냅니다.
[0-9]와 동일한 의미.
예: "abc123"에서 \d+는 "123"과 매칭.

\D
숫자가 아닌 것을 나타냅니다.
[^0-9]와 동일한 의미.
예: "abc123"에서 \D+는 "abc"와 매칭.

\s
공백 문자를 나타냅니다.
공백, 탭(\t), 줄바꿈(\n), 캐리지 리턴(\r) 등을 포함.
예: "a b\tc\nd"에서 \s는 " "와 "\t" 및 "\n"에 매칭.

\S
공백이 아닌 것을 나타냅니다.
예: "a b\tc\nd"에서 \S+는 "a", "b", "c", "d"에 매칭.

.
임의의 한 문자를 나타냅니다(줄바꿈 제외).
예: "a1 b2"에서 .는 각각 "a", "1", "b", "2"와 매칭.

2. 반복 패턴
*
0회 이상 반복을 나타냅니다.
예: "aaa"에서 a*는 "aaa"와 매칭.

+
1회 이상 반복을 나타냅니다.
예: "aaa"에서 a+는 "aaa"와 매칭.

?
0회 또는 1회 나타남을 의미합니다.
예: "abc"에서 ab?는 "ab"와 매칭.

{m,n}
반복 횟수를 지정합니다.
예: "aaa"에서 a{2,3}은 "aaa"와 매칭.
{m,}: 최소 m번 이상.
{,n}: 최대 n번까지.

주요 메타 문자와 패턴 기호
1. 문자 관련 메타 문자
\w
단어 문자를 나타냅니다.
알파벳 대소문자, 숫자, 밑줄(_)을 포함합니다.
[a-zA-Z0-9_]와 동일한 의미.
예: "Hello_123"에서 \w+는 "Hello_123"과 매칭.

\W
단어 문자가 아닌 것을 나타냅니다.
[^a-zA-Z0-9_]와 동일한 의미.
예: "Hello, World!"에서 \W+는 ", " 및 "!"와 매칭.

\d
숫자를 나타냅니다.
[0-9]와 동일한 의미.
예: "abc123"에서 \d+는 "123"과 매칭.

\D
숫자가 아닌 것을 나타냅니다.
[^0-9]와 동일한 의미.
예: "abc123"에서 \D+는 "abc"와 매칭.

\s
공백 문자를 나타냅니다.
공백, 탭(\t), 줄바꿈(\n), 캐리지 리턴(\r) 등을 포함.
예: "a b\tc\nd"에서 \s는 " "와 "\t" 및 "\n"에 매칭.

\S
공백이 아닌 것을 나타냅니다.
예: "a b\tc\nd"에서 \S+는 "a", "b", "c", "d"에 매칭.

.
임의의 한 문자를 나타냅니다(줄바꿈 제외).
예: "a1 b2"에서 .는 각각 "a", "1", "b", "2"와 매칭.

2. 반복 패턴
*
0회 이상 반복을 나타냅니다.
예: "aaa"에서 a*는 "aaa"와 매칭.

+
1회 이상 반복을 나타냅니다.
예: "aaa"에서 a+는 "aaa"와 매칭.

?
0회 또는 1회 나타남을 의미합니다.
예: "abc"에서 ab?는 "ab"와 매칭.

{m,n}
반복 횟수를 지정합니다.
예: "aaa"에서 a{2,3}은 "aaa"와 매칭.
{m,}: 최소 m번 이상.
{,n}: 최대 n번까지.

3. 위치 지정 패턴
^
문자열의 시작을 나타냅니다.
예: "Hello World"에서 ^Hello는 "Hello"와 매칭.

$
문자열의 끝을 나타냅니다.
예: "Hello World"에서 World$는 "World"와 매칭.

\b
단어 경계를 나타냅니다.
예: "Hello World"에서 \bWorld\b는 "World"와 매칭.
단어 경계는 알파벳과 공백 또는 특수 문자의 경계입니다.

\B
단어 경계가 아닌 부분을 나타냅니다.
예: "HelloWorld"에서 \BWorld는 "World"와 매칭.

4. 그룹화와 선택
()
하위 그룹을 지정합니다.
예: "abc123"에서 (abc)(123)는 두 그룹으로 매칭됩니다.
각 그룹은 .group(1), .group(2) 등으로 접근할 수 있습니다.

|
OR(또는)을 나타냅니다.
예: "cat", "dog" 중 하나를 매칭하려면 cat|dog를 사용합니다.

(?:...)
비캡처 그룹(결과 저장 안 함)을 만듭니다.
예: (?:abc)는 "abc"를 매칭하지만 결과에 저장되지 않음.

5. 특수 문자 이스케이프
\
메타 문자를 일반 문자로 취급하도록 이스케이프합니다.
예: .은 임의 문자지만 \.은 실제 점 문자로 인식됩니다.

6. 플래그 옵션
re.IGNORECASE (i): 대소문자 무시.
re.MULTILINE (m): ^와 $가 여러 줄에서 각각 작동.
re.DOTALL (s): .이 줄바꿈 문자까지 매칭.

이렇게 보니까 진짜 너무 많다.

pattern = r'_\d{4}-\d{2}-d{2}_\d{2}_\d{2}$' 이렇도 이렇게 각 안 숫자들에 맞게 없애주는 역할도 가능하다는것이 나는 솔직히 놀랐다. 게다가 os.path.join을 더 실감나게 쓸 수 있는 기회가 되기도 했다.(참고로 내일부터 조금 여유로워지 때문에 streamlit을 전체적으로 복습 시작!!)

 

오늘은 여기까지.....