PHP 정규 표현식의 캡처 그룹
캡처 그룹의 내용은 치환 문자열뿐만 아니라 정규 표현식 내부에서도 사용할 수 있습니다: 무언가를 캡처 그룹에 넣은 다음, 정규 표현식 내에서 바로 "여기에 이 캡처 그룹의 내용이 와야 한다"고 지정할 수 있습니다.
캡처 그룹의 내용은 번호 앞에 역슬래시를 붙여 접근할 수 있습니다.
예를 들어, 0번 캡처 그룹은 이렇게 접근합니다: \0,
첫 번째 캡처 그룹은 이렇게 - \1, 두 번째
- \2 등등.
위에서 설명한 내용이 아직은 다소 모호하게 느껴질 거라고 확신합니다. 이것은 당연한 일입니다. 왜냐하면 캡처 그룹은 정규 표현식에서 가장 이해하기 어려운 부분 중 하나이기 때문입니다. 예제를 통해 하나씩 알아가 보겠습니다.
예제
다음과 같은 문자열이 있다고 가정해 봅시다:
<?php
$str = 'aa bb cd ef';
?>
이 문자열에서 연속으로 두 번 나오는 같은 글자가 있는 모든 위치를 찾아봅시다. 문제를 해결하기 위해 어떤 글자든 찾아서 캡처 그룹에 넣은 다음, 다음 문자가 그 캡처 그룹의 내용인지 확인하는 패턴을 사용하겠습니다:
<?php
$res = preg_replace('#([a-z])\1#', '!', $str);
?>
결과 변수에는 다음과 같은 값이 저장됩니다:
'! ! cd ef'
예제
다음과 같은 문자열이 있다고 가정해 봅시다:
<?php
$str = 'asxca buzxb csgd';
?>
첫 글자와 마지막 글자가 같은 모든 단어를 찾아봅시다. 문제를 해결하기 위해 다음과 같은 패턴을 작성하겠습니다: 글자 하나, 그 뒤에 하나 이상의 글자, 그리고 첫 번째 글자와 같은 글자:
<?php
$res = preg_replace('#([a-z])[a-z]+\1#', '!', $str);
?>
결과 변수에는 다음과 같은 값이 저장됩니다:
'! ! csgd'
예제
\1 대신 \g1를 쓸 수 있습니다:
<?php
$res = preg_replace('#([a-z])[a-z]+\g1#', '!', $str);
?>
예제
\g{1}라고 쓸 수도 있습니다:
<?php
$res = preg_replace('#([a-z])[a-z]+\g{1}#', '!', $str);
?>
예제
중괄호 안에 음수를 지정할 수 있습니다. 이 경우 캡처 그룹은 끝에서부터 역순으로 계산됩니다:
<?php
$res = preg_replace('#([a-z])([a-z])\g{-2}#', '!', $str);
?>
실습 문제
다음 문자열이 주어집니다:
<?php
$str = 'aaa bbb ccc xyz';
?>
같은 글자가 세 번 연속으로 나오는 모든 부분 문자열을 찾으세요.
다음 문자열이 주어집니다:
<?php
$str = 'a aa aaa abab bbbb';
?>
같은 글자가 두 번 이상 연속으로 나오는 모든 부분 문자열을 찾으세요.
다음 문자열이 주어집니다:
<?php
$str = 'aaa aaa bbb bbb ccc ddd';
?>
같은 단어가 두 번 연속으로 나오는 모든 부분 문자열을 찾으세요.