Design/Python

파이썬으로 문자열 수정(찾기, 바꾸기, 지우기, 공백제거, 합치기)

공밀레의 재료 2024. 1. 18. 22:29
반응형

필자는 C언어를 처음 배웠고, 그 다음에는 verilog HDL을 공부하면서 SW언어와는 거리가 먼 길을 다녀왔다.

오히려 이전 C의 불편한 문자열 처리 방법이 익숙했고, verilog에서 bit 단위로 제어로직을 만들면서 사실 더더욱 하나하나 작게 보는 습관을 들였었는데, 자동화 작업을 위해 파이썬을 공부하다보니 문자열을 다루는 것이 웬걸, 세상 너무 편한 작업이었다.

여기, 이 포스팅에서는 자동화 스크립트를 위해 사용했던 여러 함수들을 정리해서 보기 편하게 쓸 수 있도록 구성해볼 생각이다.

 

find()

내가 자동화 스크립트를 만들때에는 기존의 코드를 불러와서 정보들을 추출해야 했다. 때문에 코드를 불러와 파일을 read 하였을 때, line 별로 데이터를 찾아야했다. 필요한 데이터를 추출하기 위해서 사용한 메서드가 find였다.

txt = "Happy New Years"
print(txt.find("Happy"))
print(txt.find("New"))
print(txt.find("Years"))
print(txt.find("Name"))

위의 구문을 실행하면 어떻게 될까?

txt에 저장된 Happy New Years는 아래와 같은 array index를 가진다. 따라서 각각의 find의 결과는 찾고자 하는 문자가 위치한 첫번째 Index의 값을 반환하게 된다.

반대로 찾지 못한 값은 -1을 반환하게 된다. 즉, find를 사용하면 반환값으로 (-1 ~ x)라는 범위를 갖는 정수를 갖게된다. 나는 이 함수를 이용해서 내가 필요한 keyword가 존재하는 line을 선별했다. (-1만 나오지 않으면 okay였다)

좀더 실력이 좋은 분들은 예외처리 (try, except)를 이용하는 방법을 이용 할 수도 있다. 이는 다른 검색 메서드를 사용하면 error를 띄우는데 이를 이용해서 할 수 있을 것으로 추측된다.

H a p p y   N e w   Y e a r s \n
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

 

0
6
10
-1

<결과물>

 

strip()

strip은 한 문자열에 대해서 왼쪽 오른쪽에서 공백 혹은 특정 패턴을 삭제하는 기능이다. 보통 인자가 없이 strip()을 사용하면 공백을 제거하고, 내부에 다른 문자 등을 이용하면 다른 패턴들을 삭제한다.

아래는 3가지 case를 다루었는데 보이는 바와 같이 정말 문자열의 양 옆을 다루는 메서드이다. 문자열 전체를 기반으로 제거하는 메서드가 아니기 때문에 세번째 케이스를 살펴보면 H,I와 같이 가운데 ,가 남아있는 모습을 볼 수 있다.

>>> txt = "    Hi   "
>>> txt.strip()
'Hi'
>>> txt = "  ,  Hi .  "
>>> txt.strip(" ,.")
'Hi'
>>> txt = "  ,  H,i .  "
>>> txt.strip(" ,.")
'H,i'

replace()

replace는 strip과는 다르게 특정한 패턴을 치환하는 작업이다. 이를 응용하면 필요없는 문자를 제거할 수도 있고, 공백으로 바꿔서 나중에 list로 나누는데 도움이 되게 할 수 있다. replace의 다른 인자에는 몇번 바꿀 것인지도 지정 할 수 있지만 자세한건 python 문서를 참고하길 바란다.

>>> txt = "Good morning sir."
>>> txt.replace("oo", "")
'Gd morning sir.'

sub()

sub는 re를 import 해야 사용 할 수 있다. sub의 가장 큰 장점은 정규표현식을 사용 할 수 있다는 점인데, 정규표현식은 차차 설명하기로 하고, 여기에서는 필자가 찾아 헤맸던 기능을 적으려고 한다. 우선, 정규표현식에는 []가 많이 사용된다. 때문에 만약에 내가 기준점으로 삼는 문자가 [ 라면 퍽 난감한 상황이 될 수 있다.

정규표현식에서 \s 는 공백문자이다. \t, \s, \n 등을 포함하는 것들로서 space 뿐만 아니라 \t 등을 포함하기 때문에 유익하게 사용된다. 하지만 \s는 단 1개만 삭제되기 때문에 만약 반복된 \s를 그것도 몇개가 나올지 모르는 상황이라면 정규표현식의 *를 사용할 수 있다.

아래 예제를 보면 *의 위치에 따라서 공백이 제거되는 것이 달라지는 결과를 볼 수 있다.

[를 문자로 인식하려면 escape 문자인 \가 2개가 필요하다. 즉, \\[ 혹은 \\]를 하면 [와 ]를 문자로 인식할 수 있다. 이는 나중에 설명할 정규표현식에서 알겠지만 []는 정규표현식을 표현하는 하나의 표현식이기 때문이다.

>>> txt = "      [   10-1:0  ]"
>>> re.sub("\s\\[","[",txt)
'     [   10-1:0  ]'
>>> re.sub("\s*\\[","[",txt)
'[   10-1:0  ]'
>>> re.sub("\\[\s","[",txt)
'      [  10-1:0  ]'
>>> re.sub("\\[\s*","[",txt)
'      [10-1:0  ]'

split()

split()은 보통 가장 많이 쓰이는 메서드로, 문자열을 list type으로 만들어준다. 아무것도 없이 split()을 한다면 공백을 기준으로 나눠지게 되고, 원하는 특정 패턴이 있으면 해당 패턴을 기준으로 문자열을 쪼개주게 된다. 이는 굉장히 유용한 기능으로, 앞으로 많은 기능을 사용하게 될 것으로 보인다. split()을 사용하면 가장 좋은 점은, pandas같은 패키지를 쓰지 않고도 excel과 유사한 csv file을 편집하기 쉽다는 점이다. csv는 excel로 열면 표처럼 볼 수 있을 뿐만 아니라, vim 으로 열면 ,로 구분된 txt로 보이기 때문이다. 이는 split으로 구분자를 ','로 지정한다면 excel의 형태를 list로 받을 수 있다는 점이 된다.

>>> txt = "Hi My name is Jame"
>>> txt.split()
['Hi', 'My', 'name', 'is', 'Jame']
>>> txt.split("m")
['Hi My na', 'e is Ja', 'e']

join()

마지막은 split으로 쪼개져서 list가 된 type을 다시 문자열로 만드는 방법이다. 이는 join()을 이용하는 방법으로 ' '.join() 처럼 표현되는데 ' ' 안에 들어가는 패턴이 연결자로서 문자열로 완성된다. 즉 ' '으로 실행하면 리스트의 인덱스 사이에 공백이 들어가며 문자열이 되고 '-'을 사용하면 -으로 연결되는 문자열이 완성된다.

>>> txt = "Hi My name is Jame"
>>> txt = txt.split()
>>> txt
['Hi', 'My', 'name', 'is', 'Jame']
>>> ' '.join(txt)
'Hi My name is Jame'
>>> '-'.join(txt)
'Hi-My-name-is-Jame'
반응형