Powershell 에서의 정규 표현식 (Regular Expressions)

Powershell 에서도 쉽게 Regex(정규 표현식)을 사용할 수 있다. shell 환경인 만큼 그 활용 범위가 매우 크며 여러 상황에서 응용이 가능하다.

Regex를 사용하는 경우를 크게 2가지로 보면 검색(일치 확인) 과 치환작업으로 볼 수 있는데 Powershell은 두가지를 연산자 -match 와 -replace로 제공한다.

기본적으로 대소문자를 구분하지 않는 Powershell 환경이기 때문에 -match와 -replace도 대소문자를 구분 하지 않는다. 대소문자를 구분하기 위해서는 다른 연산자들과 같이 앞에 ‘c’를 붙혀 -cmatch, -creplace를 사용 하면 된다. (‘i’ 를 붙혀 -imatch -ireplace 도 있는데 이것은 -match -replace와 동일 하다.)


-match

[Source] -replace [Find Target] 형식으로 찾을 수 있다.

$text = "Windows PowerShell is a task-based command-line shell and scripting language designed especially for system administration."

$text -match "powershell"		# true

$text -cmatch "powershell"		# false

$text -cmatch "PowerShell"		# true

-match 연산자를 사용한 뒤에는 $Matches 라는 변수가 새로 생성 되는데 이 변수는 -match 연산자가 true를 반환 했을때 생성되며 match로 찾은 대상들이 Collection으로 담겨 있다.

현 상태에서 $Matches를 확인 해 보자.

PS C:> $Matches
Name                           Value
----                           -----
0                              PowerShell

PowerShell이라는 문자열을 찾았으니 당연히 PowerShell 이 들어 있다.

그렇다면 이번엔 g로 끝나는 단어를 찾아 보자.

$text -match "w+g"

결과는 True로 이지만 어떤 문자열이 match 되었는지는 알 수 없다. 이때 $Matches를 이용해 확인 해 보자.

PS C:> $Matches
Name                           Value
----                           -----
0                              scripting

scripting 이라는 문자열이 match 됨을 확인 할 수 있다.

추가 적으로 Group 을 이용하여 검색 할때 다음과 같이 활용 할 수 있다.

$text -match '(w+)-(w+)'

문자열 중앙에 – 이 들어간 문자열을 찾을 것이다.

PS C:> $Matches

Name                           Value
----                           -----
2                              based
1                              task
0                              task-based

Group으로 검색된 결과와 전체 결과까지 같이 포함된다.
$Matches[0] 이 전체 문자열이고 $Matches[1] 번부터 Group 1번이다.

위에서 눈여겨 볼 점은 “command-line” 문자열도 발견될 조건인데 “task-based” 만 발견 되었다. 이유는 -match 연산자는 bool 값을 리턴하기 때문에 전체 문자열을 앞에서 부터 탐색하여 한번이라도 발견 되면 즉시 True를 리턴하고 종료 하기 때문이다.


이번에는 -replace 연산자로 치환을 해 보자. “Powershell” 이라는 문자열을 줄임 말인 “Posh” 로 바꿔보자.

[Source] -replace [Find Target], [Replace What] 형식이다.

$text = "Windows PowerShell is a task-based command-line shell and scripting language designed especially for system administration."

$text -replace "Powershell", "Posh"

즉시 다음과 같은 치환이 이루어진 문자열이 보일 것이다.

Windows Posh is a task-based command-line shell and scripting language designed especially for system administration.

문자열이 출력 되었다는 것은 -replace 연산자가 문자열을 return 했다는 뜻이다. 원본 문자열인 $text는 아무 변화가 없고 오로지 치환된 문자열이 return 될뿐이다.

이번에는 Group을 이용한 -replace를 해 보자.

$text -replace "(w+)-(w+)", "$2-$1"
Windows PowerShell is a - - shell and scripting language designed especially for system administration.

잠시 놀랄 것이다. 기대 했던 것은 -양쪽의 문자열을 서로 바꾸는 동작인데 결과는 빈칸이 들어가 버렸다. 이유는 특수문자 $는 Powershell 에서 변수 앞에 붙힌다. 그런데 이것은 “(쌍따옴표)로 감싼 문자열에서도 유효하다. 문자열에서 Powershell 특수문자를 일반 문자로 인식 시키기 위해서는 2가지 방법이 있다.

  • “(쌍따옴표) 대신 ‘(따옴표)로 감싸기
  • 특수문자 앞에 escape 문자인 `(GRAVE ACCENT)를 붙히기 (한글 이름을 잘 모르겠고 키보드 상에서 1(!) 키 왼쪽에 있는 것)
  • 그러면 이제 다음 예를 보자.

    나쁜 예

    $text -replace "(w+)-(w+)", "$2-$1" 	 	# " 안에서는 $ 는 문자가 아니다.
    $text -replace "(w+)-(w+)", '`$2-`$1' 	# ' 안에서는 `로 $를 escape 할 필요 없다.
    

    좋은 예

    $text -replace "(w+)-(w+)", '$2-$1' 	 	# ' 를 이용해 $가 일반 문자로 취급됨
    $text -replace "(w+)-(w+)", "`$2-`$1" 	# " 안에서 `로 $를 적절히 escape 하였다.
    

    올바르게 치환 되면 다음과 같은 결과를 얻을 수 있다.

    Windows PowerShell is a based-task line-command shell and scripting language designed especially for system administration.
    

    답글 남기기

    이메일 주소는 공개되지 않습니다.

    You may use these HTML tags and attributes:

    <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> 

    이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.