정규표현식
정규표현식(Regular Expression)은 컴퓨터 프로그래밍 과정 중 특정한 규칙을 가진 문자열의 집합을 표현하는 형식 언어입니다. 많은 프로그래밍 언어에서 정규표현식을 사용할 수 있는 환경을 제공하고 있으며 이를 활용하면 상당히 효율적으로 문자열을 처리(관리)할 수 있습니다. 캣툴에서는 비번역 처리가 필요한 문자열을 검색하는 용도로 정규표현식을 활용합니다. 비번역 처리는 번역의 효율성을 높이기 위해 반드시 필요한 과정입니다. 비번역 처리 방법을 학습하기 전에 정규표현식 관련 기초 과정을 학습하여 기본적인 활용 방법을 익혀 두시기 바랍니다.
정규표현식, 왜 알아야 하는가?
솔직히 저도 정규표현식을 잘 모를 때는 크게 신경을 쓰지 않았고 왜 배워야 하는지에 대한 생각조차 하지 않았습니다. 그리고 2차 벤더(vendor)에서 일하다 보면 바로 번역할 수 있도록 가공을 마친 번역용 파일을 제공받기 때문에 정규표현식의 필요성을 전혀 느끼지 못합니다. 하지만 언제까지 2차 벤더에서만 일을 할까요? 언젠가는 1차 벤더로 이직을 하거나 내가 속해있는 회사가 1차 벤더로 성장하게 될 수도 있지 않을까요? 이런 가능성이 있고 스스로도 업무와 관련된 스펙을 좀 더 쌓고 싶은 분이라면 정규표현식을 배우라고 권장하고 싶습니다.
정규표현식은 결국 번역할 문장 외의 나머지 부분을 편집할 수 없도록 만들어 인간이 번역하는 중에 의도치 않게 만들어낼 수 있는 오류를 줄이는 방법 중 하나입니다. ‘아니, 그럼 처음부터 번역할 내용만 받아서 번역하면 되지 뭣 때문에 필요 없는 부분까지 받아서 그걸 또 편집 못하게 만들고 파일을 가공하고… 하면서 시간과 비용을 낭비하는 건가요?’라고 말씀하시는 분 있을 것 같습니다. 그렇게 번역할 내용만 추리는 것도 가능한 일이긴 하지만 정규표현식을 활용하는 것에 비해 오히려 시간과 비용이 더 들어갈 수 있습니다. 또한 비번역 처리하는 부분은 ‘번역을 하면 안 되는 부분’이긴 하지만 번역에 도움이 될 수 있는 정보를 담고 있는 경우가 많습니다. 이런 정보까지 삭제한 채로 번역을 진행한다면 아무래도 오역이나 정보 부족으로 인한 수준 낮은 번역이 발생할 확률을 높이지 않을까요? 그래서 정규표현식 학습을 추천합니다. 그리고 우리가 배워야 할 수준은 그렇게 깊지 않습니다. 약간은 발만 담갔다 빼는 느낌으로 꼭 필요한 내용만 배워도 번역 과정에서 충분히 효율적으로 활용할 수 있습니다.
정규표현식 연습 사이트: https://regexr.com/
정규표현식을 직접 구성하여 내가 생각했던 대표 패턴 적용이 가능한지 확인해 볼 수 있는 사이트입니다. 위 그림처럼 하단에 검색하고자 하는 텍스트를 복사해 넣고 빨간색 사각형으로 표시된 부분에 정규표현식을 작성합니다. 아래 텍스트에서 내가 원하는 부분만 선택이 된다면 정규표현식이 완성된 것입니다.
정규표현식 사용하기
대소문자 구분
정규표현식은 대문자와 소문자를 구분합니다. 한글에는 적용되지 않는 부분이지만 영어 등 알파벳으로 이루어진 언어를 다룰 때는 꼭 필요한 기능입니다.
앞서 말씀드린 정규표현식 연습 사이트에 [Hello, world!]라는 내용을 3회 입력 후 정규표현식 입력란에 [Hello]라고 입력하면 이에 해당하는 [Hello]가 파란색으로 모두 선택되는 것을 볼 수 있습니다.
하지만 대문자로 시작하는 [Hello] 대신 소문자로 시작하는 [hello]를 입력하니 선택이 이루어지지 않았습니다. 이처럼 정규표현식은 내용이 정확히 일치(대소문자 포함)하지 않으면 해당 내용을 검색하지 않습니다.
이스케이핑(Escaping)
정규표현식에서 [, {, *, ^, ?, $과 같은 특수 문자들은 문법적인 역할을 수행합니다. 즉, 정규표현식 안에서는 ?를 입력해서 물음표(?)를 찾아내지 않고 다른 역할을 수행한다는 의미입니다. 하지만 문장 내에 등장하는 특수 문자를 찾아야 할 경우도 반드시 있을 겁니다. 예로 든 ?(물음표) 같은 경우에도 번역을 하다보면 무수히 많이 만날 수 있는 특수 문자 중 하나니까요. 문법에 해당하는 특수 문자들을 검색하는 목적으로 사용하려면 이스케이핑(escaping) 기법을 사용해야 합니다. 말이 좀 거창하긴 하지만 검색하고 싶은 특수문자의 앞에 역슬래시(\)를 붙이면 해당 특수 문자를 검색할 수 있습니다.
그림에서 보이는 것처럼 물음표(?)로만 검색하면 문장에 있는 ?가 검색되지 않습니다. 하지만 역슬래시(\)를 사용하면 아래 그림처럼 문장의 ?를 검색할 수 있습니다.
문법 요소 살펴보기 - .(마침표)
갑자기 제목에 마침표 하나만 있어서 당황하셨나요? 마침표는 정규표현식에서 모든 문자열(공백과 특수 문자도 포함)에 대응하는 역할을 합니다. 점 하나만 찍어도 모든 문자열을 선택하게 되는 거죠. 나중에 다른 표현식과 결합해서 사용하면 굉장히 강력한 문자열 탐색 능력을 보여줍니다.
문법 요소 살펴보기 - [ ](대괄호)
대괄호는 검색하는 1개의 문자를 가리킵니다. 예를 들어 [love]라는 정규표현식을 만들었다면 이 식으로는 l, o, v, e 중 하나에만 해당하면 검색할 수 있습니다.
위 그림처럼 대괄호 안에 love를 입력하여 식을 구성하면 검색하는 문장 안에 있는 모든 l, o, v, e 글자가 검색됩니다. 실제로 문장 안의 love도 각각의 글자로 검색된 것을 확인할 수 있습니다.
Tip. 대괄호는 1개의 문자에 해당합니다. 즉, 대괄호 안에 많은 글자를 넣어서 검색해도 각각 하나의 글자를 기준으로 검색하는 것이지 입력한 글자의 조합을 찾아내는 것이 아니라는 의미입니다. 따라서 2개의 글자 조합을 검색하려면 대괄호를 2번 사용해서 식을 작성해야 합니다. 예를 들어 첫 번째 글자는 l, o, v, e 중에 한 글자가 오고 두 번째 글자는 m, e 중 한 글자가 오는 문자열을 검색하는 식은 [love][me]입니다. 여기에서 대괄호 안 문자의 순서는 관계 없습니다.
문법 요소 살펴보기 - [ - ](하이픈)
하이픈은 대괄호 안에서 검색할 문자의 범위를 지정합니다. 예를 들어 [a-k]를 입력하면 알파벳 a에서부터 k까지의 문자를 검색합니다. 즉, [a-k]는 [abcdefghijk]와 동일한 검색 결과를 확인할 수 있습니다. 검색할 문자열을 범위로 지정하면 식을 간단하게 만들어 보다 직관적인 정규표현식 구성이 가능합니다.
문법 요소 살펴보기 - ( | | ) (서브패턴)
서브패턴은 특정 부분만 일치하는 문자열을 한 번에 검색할 때 사용하면 좋습니다. 예를 들어 이름은 같고 성만 다른 인물의 이름이 여러 개 있다고 가정해 보겠습니다. 이 인물의 이름이 [영수]라고 가정하고 텍스트 데이터 속에서 [심영수], [조영수], [최영수] 이렇게 세 사람의 이름만 검색한다면 정규표현식을 다음과 같이 작성합니다.
(심|조|최)영수
이 식에서 파이프(|) 기호는 키보드의 역슬래시(\) 기호가 있는 자판을 Shift를 누른 상태로 누르면 출력됩니다. 정규표현식의 결과는 다음 그림과 같습니다.
문법 요소 살펴보기 - *, +, ?(수량자)
수량자는 수효와 분량을 아울러서 이르는 말로 등장하는 문자의 숫자나 양을 조절하는 기호라고 생각해 주십시오. 수량자로 쓰이는 기호는 별표(*), 더하기(+), 물음표(?) 이렇게 세 가지입니다.
별표(*) - 별표는 0개 이상의 문자 또는 문자열에 대응합니다. 즉, 별표를 사용하면 해당하는 문자가 없거나, 1개이거나 2개 이상이거나 상관 없이, 있으면 있는대로 문자열을 검색한다는 의미입니다. 예를 들어 aabc abc bc라는 문장에서 a*b라는 정규표현식을 사용하면 a로 시작하면서 b로 끝이 나는 모든 문자열이 검색됩니다. 이 식은 b를 기준으로 앞에 a가 있는 문자열을 검색하되 b 앞에 a는 없거나 1개이거나 2개 이상이어도 상관 없다는 의미입니다. 그래서 aabc에서는 aab까지 선택되고 abc는 ab가, bc는 b가 선택됩니다.
더하기(+) - 더하기는 1개 이상의 문자 또는 문자열에 대응합니다. 따라서 더하기를 사용하면 1개 이상의 문자열을 검색하지만 1개도 없으면 검색에서 제외됩니다. 별표는 아무 것도 없어도 검색되는 것에 비해 더하기는 반드시 1개 이상 존재해야 합니다.
위 그림을 보시면 b를 기준으로 a가 1개 이상인 문자열만 검색되었습니다. 별표를 사용했을 때와 달리 bc는 검색되지 않은 것을 확인할 수 있습니다. 이 부분이 별표와 더하기의 다른 점입니다.
물음표(?) - 물음표는 0개 또는 1개의 문자에 대응합니다. 앞선 두 가지 수량자에 비해 숫자의 제약이 정확히 명시되기 때문에 어떻게 활용하느냐에 따라 검색 결과를 다양하게 만들 수 있습니다.
물음표를 사용하면 b를 기준으로 바로 앞에 있는 a만(a가 1개), 또는 a가 없는(a가 0개) 경우만 검색합니다.
문법 요소 살펴보기 - 수량자 뒤에 추가하는 물음표(탐욕적인 수량자와 게으른 수량자)
수량자는 다수의 문자열을 효과적으로 제어하기 위해 반드시 필요한 문법 요소 중 하나입니다. 예를 들어 아래와 같은 문장에서 번역할 요소를 제외한 나머지를 검색해야 한다면 어떻게 해야 할까요? 번역을 하면 안 되는 부분은 알아보기 쉽도록 빨간색으로 표시하겠습니다.
<p>Visit the Dragon site</a> for information on how to sign up for a chance to get beta access.</p>
위 예시에서 비번역 대상의 특징은 모두 html에서 사용하는 태그이며 왼쪽 꺾쇠(<) 기호로 시작해서 오른쪽 꺾쇠(>)기호로 끝난다는 것입니다. 아! 그러면 왼쪽 꺾쇠와 모든 문자를 표현하는 마침표( . ), 0~여러 개의 문자를 의미하는 수량자인 별표( * )를 사용하고 마지막에 다시 오른쪽 꺾쇠를 사용하면 이 문장의 태그를 모두 검색할 수 있을 것 같습니다. 즉, <.*>이라는 정규표현식을 사용하는 것입니다. 이 정규표현식의 결과는 아래 그림과 같습니다.
예상했던 것과는 달리 각 태그 부분만 검색해 주는 대신 문장 전체를 검색해 버리고 말았네요. 정규표현식에서는 이런 상황에 사용한 별표( * )를 탐욕적인 수량자(greedy quantifier)라고 부릅니다. 가장 처음에 나온 오른쪽 꺾쇠에서 멈추길 바랐지만 수량자의 탐욕을 제어하지 못해 문장의 가장 마지막에 있는 오른쪽 꺾쇠를 만나고서야 멈추게 된 것입니다.
그럼, 어떻게 해야 이 수량자의 탐욕을 멈추게 만들고 우리가 원하는 결과를 얻을 수 있을까요? 답은 바로 물음표(?)입니다. 물음표는 그 자체로 0~1개의 수량을 표현하는 수량자 역할을 하지만 별표( * )나 더하기(+) 기호 등의 수량자 바로 다음에 놓으면 그 앞에 있는 수량자를 제어하는 역할을 합니다. 그럼 정말 그런 제어가 가능한지 테스트해 볼까요? 방금 만들었던 식에 물음표를 추가해서 <.*?>와 같이 만들고 다시 검색해 보겠습니다.
물음표를 하나 추가하니 처음 원했던 대로 html 태그 부분만 검색이 가능해졌습니다. 탐욕적인 수량자의 폭주(?)를 제어하는 물음표를 게으른 수량자(lazy quantifier)라고 부릅니다. 물음표를 추가하면 해당 조건에 충족하는 첫 번째 문자열을 찾고, 그 다음 문자열을 시작점부터 다시 찾고, 이것을 문장의 마지막 부분까지 반복하게 됩니다. 결과적으로 원하는 부분만 걸러낼 수 있게 되었으니 탐욕적인 수량자와 게으른 수량자에 대해서는 확실히 알아두시는 것이 좋겠습니다.
지금까지 말씀드린 정규표현식 문법은 컴퓨터 관련 전문 강사이신 이고잉 님의 강의 자료를 바탕으로 하여 게임 현지화에 필요하다고 생각한 가장 기초적인 내용만 추린 것입니다. 좀 더 깊은 내용을 학습하고 싶은 분들은 이고잉 님이 운영하는 온라인 강의 사이트 [생활코딩]을 이용해 보시길 권해 드립니다.
'번역이야기' 카테고리의 다른 글
memoQ의 Run QA 기능: 번역 품질을 높이는 필수 도구 (25) | 2024.10.05 |
---|---|
memoQ로 단일 언어 프로젝트 생성 및 비번역 처리하기 (28) | 2024.10.04 |
번역가를 위한 필수 가이드: 캣툴 지원 파일 형식 (29) | 2024.10.02 |
매치레이트와 TM: 번역가를 위한 필수 도구 이해하기 (20) | 2024.10.01 |
효율적인 번역 비용 절감을 위한 로그 분석 방법 (12) | 2024.09.28 |
댓글