XMLHTTP로 웹 페이지를 받아 오거나 게시판 본문을 엑셀로 옮기다 보면 <p>, <br>, <span style=...> 같은 태그가 잔뜩 섞인 문자열을 받게 됩니다. 셀에 그대로 넣으면 읽을 수가 없으니 태그만 걷어 내야 하는데, InStr로 <와 >를 찾아 가며 자르면 코드가 길어지고 빠지는 경우도 생깁니다. 정규식을 쓰면 함수 몇 줄로 끝납니다.

Public Function HTMLDEL(ByRef T As String) As String
    Dim regEx As Object
'    Set regEx = New RegExp
    Set regEx = CreateObject("vbscript.regexp")

    regEx.Pattern = "<[^>]+>"  '--- html tag match를 위한 정규식
    regEx.IgnoreCase = True
    regEx.Global = True
    HTMLDEL = regEx.Replace$(T, "")
End Function

패턴 <[^>]+>의 의미

<로 시작해서, >가 아닌 문자([^>])가 하나 이상(+) 이어지다가, >로 끝나는 부분을 찾습니다. 여는 태그, 닫는 태그, 속성이 붙은 태그, <br/> 같은 빈 태그가 전부 이 모양이라 한 패턴으로 다 걸립니다. Global = True가 있어야 첫 번째 태그만이 아니라 문자열 안의 모든 태그를 바꿉니다. 이걸 빠뜨리면 첫 태그 하나만 지워지고 끝나서 "왜 안 되지" 하게 되는 단골 실수입니다.

광고

CreateObject("vbscript.regexp")로 만드는 지연 바인딩 방식이라 참조 설정 없이 바로 쓸 수 있습니다. 주석 처리된 New RegExp 줄은 VBE에서 "Microsoft VBScript Regular Expressions 5.5" 참조를 추가했을 때 쓰는 방법이고, 이쪽은 자동 완성이 되는 대신 파일을 다른 PC로 옮길 때 참조가 깨질 수 있습니다. 배포할 파일이라면 지금처럼 CreateObject가 편합니다.

사용은 이렇게 합니다.

Debug.Print HTMLDEL("<p>안녕<b>하세요</b></p>")   ' 결과: 안녕하세요

태그를 지운 뒤에 남는 것들

태그만 지우면 &nbsp;, &lt;, &amp; 같은 HTML 엔티티가 그대로 남습니다. 자주 나오는 몇 개는 Replace로 추가 치환해 주는 게 좋습니다. 특히 &amp;는 다른 엔티티를 먼저 바꾼 뒤 마지막에 바꿔야 두 번 해석되는 일이 없습니다.

또 <br>이나 </p>가 사라지면서 줄바꿈 정보도 같이 없어져 문장이 한 줄로 붙어 버립니다. 줄 구분이 필요하면 이 함수를 부르기 전에 <br>, </p>, </div> 를 vbCrLf로 먼저 바꿔 두세요. <script>나 <style> 블록은 태그만 지워지고 안쪽 자바스크립트·CSS 코드는 남으니, 페이지 전체를 다룰 때는 그 블록을 먼저 통째로 제거하는 처리를 앞에 두면 결과가 훨씬 깨끗합니다.

엔티티 정리 함수와 같이 쓰기

위에서 말한 엔티티 치환을 함수로 묶어 두면 태그 제거와 짝으로 부르기 편합니다. &amp; 를 맨 마지막에 두는 이유는 &amp;lt; 같은 문자열이 &lt; 를 거쳐 < 까지 두 번 풀리는 걸 막기 위해서입니다.

Public Function HTMLDECODE(ByVal T As String) As String
    T = Replace(T, "&nbsp;", " ")
    T = Replace(T, "&lt;", "<")
    T = Replace(T, "&gt;", ">")
    T = Replace(T, "&quot;", """")
    T = Replace(T, "&#39;", "'")
    T = Replace(T, "&amp;", "&")
    HTMLDECODE = T
End Function

부를 때는 태그를 먼저 지우고 엔티티를 나중에 풉니다. 순서가 반대면 본문에 글자로 적혀 있던 &lt;b&gt; 가 먼저 <b> 로 바뀐 뒤 태그로 오인돼 지워집니다.

Range("A1").Value = HTMLDECODE(HTMLDEL(T))

엑셀 셀에서 줄바꿈과 오탐

셀 안 줄바꿈은 vbLf(Chr(10)) 하나면 충분합니다. vbCrLf 를 넣으면 셀에 따라 줄 끝에 보이지 않는 문자가 남아 나중에 비교할 때 값이 달라지니, 셀에 넣을 목적이라면 <br> 을 vbLf 로 바꾸는 편이 깔끔합니다. 그리고 셀에서 실제로 줄이 바뀌어 보이려면 해당 셀의 "텍스트 줄 바꿈" 서식이 켜져 있어야 합니다.

패턴이 < 와 > 사이를 통째로 지우는 방식이라, 본문에 a<b 이고 c>d 처럼 부등호가 섞여 있으면 그 사이 글자도 같이 사라집니다. 정상적인 HTML이라면 본문의 부등호는 &lt;, &gt; 로 들어오니 문제가 없지만, 사람이 손으로 쓴 HTML 조각을 다룰 때는 결과를 한 번 눈으로 확인해 보는 게 좋습니다.