카테고리 없음

[swift] 정규식을 활용하여 process 항목 추출하기

jin_j_i_n 2021. 11. 26. 13:30

블로그를 자주 안하니 참 일기장 들여다보는기분.......

 

정규식이 항상 어려워서 피하다가 결국에 이번에 끝장을 보려고 공부해서 정리하겠다...

 정규식과 나

정규식

정규표현식 또는 정규식이라고 불리며 문자열에서 특정한 규칙을 가진 문자열의 집합을 표현하는 식이다.

특정 문자열에 원하는 규칙을 세운 정규식을 적용하면 원하는 문자열을 도출한다거나, 해당 문자열 안에 원하는 문자가 있는지 판별할 수 있다.

식이라고 생각하면된다. 처음엔 정규식 자체가 너무 외계어 같아 외면해왔으나....자주자주 마주하다보면 좀 친해지는 느낌을 받을 수 있을것이다.

그동안 정규식을 쓰기 싫어 spilit, contains같은 스위프트 문자열 함수만 즐겨 사용했으나 이번엔 해당 함수로만 처리할 수 없는 부분들이 많아 정규식을 사용하였다.

나도 아직 친해지는 중이니... 좀더 알아보도록 하자

 

일단 오늘 처리할 문자열은 

ahnlab@Ahnlabui-MacBookAir-2 ~ % ps auxc -o ppid
USER               PID  %CPU %MEM      VSZ    RSS   TT  STAT STARTED      TIME COMMAND           PPID
ahnlab             484   6.6  1.6 409759680 275024   ??  S    화09AM  83:01.54 syncdefaultsd        1
_windowserver      140   6.5  1.0 410307552 161760   ??  Ss   화09AM 260:29.28 WindowServer         1
ahnlab             685   1.4  0.5 409231104  84080   ??  S    화09AM  40:45.72 NuoRDS Agent       665
root               342   1.2  0.0 409153024   6720   ??  Ss   화09AM  43:41.96 sysmond              1
_mdnsresponder     156   1.1  0.0 408511904   7584   ??  Ss   화09AM  15:01.88 mDNSResponder        1
_driverkit         275   1.1  0.0 408555584   7696   ??  Ss   화09AM  19:53.44 com.apple.Driver     1
ahnlab             490   1.0  4.1 412638352 691456   ??  S    화09AM  32:12.82 Xcode                1
root             33439   0.9  0.1 409428288  19088   ??  Ss    6:29PM   0:00.42 CFNetworkAgent       1
ahnlab            2748   0.5  1.6 411617376 274944   ??  S    화11AM  17:23.43 Microsoft Outloo     1
_networkd          214   0.4  0.1 408636352  12480   ??  Ss   화09AM   7:07.06 symptomsd            1
root                79   0.4  0.1 408796048  10080   ??  Ss   화09AM   5:06.98 configd              1
root                87   0.3  0.2 408873120  30800   ??  Ss   화09AM   6:31.29 logd                 1
ahnlab             516   0.3  1.0 410083952 176000   ??  S    화09AM   1:17.03 Terminal             1
root                 1   0.1  0.1 408636240  22208   ??  Ss   화09AM   8:46.10 launchd              0
ahnlab             652   0.1 12.9 14720924 2164032   ??  S    화09AM  19:36.40 Microsoft Teams    479
root                97   0.1  0.4 409294144  65312   ??  Ss   화09AM   2:23.16 mds                  1
ahnlab           28559   0.1  4.7 14533548 784208   ??  S     1:33PM   1:03.37 HRS_AhnLab Helpe 28555
ahnlab           33393   0.1  0.1 408605392  23904   ??  S     6:25PM   0:00.14 mdworker_shared      1
ahnlab           33351   0.1  0.1 408668144  13600   ??  S     6:23PM   0:01.83 debugserver       7478

위와같은 터미널에서 ps명령어를 쳤을때 나오는 프로세스 정보이다.

각 줄의 문장에서 user, pid, cpu, mem등 항목별로 얻을것이고, 그에 따른 규칙을 찾아 정규식을 적용한다.

 

정규식을 세우면서 자주 나오는 문법들을 먼저 짚고 넘어가겠다.

 

1. ^

문자열의 시작이다.

^ 하나만 쓰는것이 아닌 문자열 규칙이 붙는데, 해당 규칙으로 시작하는 문자열을 판별하겠다는 의미이다.

예를들어 ^숫자로만 이루어진 규칙 이 하나의 식이면, 문자열이 숫자로만 이루어진 문자로 시작하는 문자에 한해서 판별, 도출한다.

 

"안녕하세요 제이름은 나무발발이이고요, 나이는 883725573 8 002 1 0  0 0 입니다. 집은 제주도에 있어요 "

 가 하나의 문자열이라고 해보자. 여기서 위에 언급한 규칙을 적용한다면, 도출되는 문자열은 없다.

반대로 ^문자로만 이루어진 규칙 을 적용하게 된다면, 도출되는 문자열은 "안녕하세요" 가 될것이다.

 

2. []

대괄호안에 문자열 규칙을 넣는것으로, 대괄호하나가 문자의 단위가 된다. 규칙은 0~9 사이의 문자인지 , 소문자로 이루어진 문자인지, 대문자로 이루어진문자인지 또는 특수문자인지에 대한 여부를 넣으면된다.

표기는 숫자는 0-9 (0에서 9 사이의 문자) 소문자는 a-z (a~z사이의 문자) 대문자는 A-Z 이런식으로 표기하면 된다. 

예시로 숫자로만 이루어진 문자를 찾는다고 하자, 규칙은 [0-9]가 될 것이다. 또는 숫자, 소문자로 이루어진 문자열과 같이 여러규칙이 있어야 한다면 [0-9a-z] 로 이어서 표기한다.

위에 예시로 나온 문자열에 적용한다면, 

8,8,3,7,2,5,5,7,3,8,0,0,2,1,0,0,0 로 나올것이다. 883725573, 8, 002, 1, 0, 0, 0 을 예상했을텐데 말이다. 이는 문자열에 길이 규칙을 지정해주지 않아서이다.

 

또한 대괄호 안에도 ^를 넣을 수 있는데, 이때 대괄호안의 ^는 부정의(not) 의미를 갖게된다.

예를 들어 [^0-9]는 0-9로 이루어지지 않은 문자열을 의미하게 된다.

 

3. {,}

길이를 지정해주는 규칙이다. 콤마 기준으로 왼쪽은 최소길이, 오른쪽은 최대길이를 지정한다.

오른쪽은 지정해주지 않아도 된다. 다만 최대길이를 지정하지 않으면 최대길에 제한이 없다는 뜻이 된다.

예를 들어 {2,8} 은 2~8길이의 문자열이 되고, {1,} 는 최소 1길이 이상의 문자열을 의미한다

 

그럼 2번 예시에서 883725573, 8, 002, 1, 0, 0, 0 과 같이 도출하려면 어떻게 해야할까?

구하려는 문자열 길이가 전부 1이상이니 {1,}을 해주어도 되고, 최대 길이가 9이니 {1,9} 로 표기해주어도 같은 결과가 나온다.

 

4. +

특정한 규칙을 지키는 형태로 문자열이 이루어져있다면, +를 사용해 문자열의 형식을 지정할 수 있다.

[규칙]+[규칙]+[규칙] 과 같은 형식으로 특정한 문자열의 형태를 지정할 수 있다. 이는 이메일의 정규식에서도 많이 활용되는데, 이메일은 @가 필수적으로 들어가야 하므로

[규칙]+@[규칙]+\\.[규칙] 과 같이 나타낼 수 있다.

 

이제 맨 위에서 언급한 프로세스를 각 항목마다 출력해보자. 해당 항목을 오류없이 도출하려면 규칙을 잘 알아야하고 그에 맞는 정규식을 세워야 한다. 내가 세운 정규식은 다음과 같다.

 

- user : 소문자로 이루어져있고, _ 기호가 포함될 수 있다. 길이는 1이상

- PID , VSZ , RSS , PPID : 숫자로만 이루어져있음. 길이는 1이상

- CPU ,MEM : 소수점 ( . )이 포함되어있고, 점 앞뒤로 숫자로 이루어져있다. 길이는 1 이상

- TT : ??또는 소문자,숫자로 이루어져있는 문자열이다.

- STARTED : 화 9:30PM 또는 11:39AM 와 같이 두가지 형태로 존재하며, 한글+공백+숫자+:+숫자+대문자영어 또는 숫자+:+숫자+대문자영어와 같은 형태로 이루어져있다.

- TIME : 숫자 + : + 숫자 + . + 숫자 형태

- COMMAND : 대소문자, 공백 , _ 기호로 이루어져있다.

 

위에 따른 세운 규칙은 다음과 같다.

        static let text = "[a-zA-Z_?]{1,}" //USER또는 STAT 형식 

        static let command = "[a-zA-Z_ ]{1,}" //COMMAND

        static let number = "[^A-Za-z ?_]{1,}" //숫자로만 이루어진 항목들

        static let krDate = "[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]+[ ]+[0-9]+[A-Z]{1,}" //화 9:30AM 과 같은 형식 

        static let date = "[0-9]+[:]+[0-9]+[A-Z]{1,}" // 11:09AM과 같은 형식

        static let time = "[0-9]+[:]+[0-9]+[.]+[0-9]{1,}" // 11:22.22 과 같은 형식

 

정규식은 차차 추가할거니 빠진 부분에 대해선 이후에 수정하겠다.