이 세상에 하나는 남기고 가자

세상에 필요한 소스코드 한줄 남기고 가자

PHP 정규식(PCRE)의 모든 것 - 에필로그

유영재

앞선 글들에서 PCRE에 대한 전반적인 내용을 소개 했다. 일부는 내용이 이해하기 어려울 수 있다. 나름 이해가 어려운 부분은 예시를 추가해서 이해를 돕고자 했으나 부족할 것으로 보인다. PCRE를 익히는 가장 좋은 방법은 직접 패턴을 만들어 보면서 학습하는 것이다.

PCRE에 대한 소개를 마치며 학습 및 활용에 도움이 될 수 있는 몇가지 사이트와 예시들을 남겨둔다.


정규식을 웹 상에서 테스트해 볼 수 있는 사이트를 소개한다(검색해보면 더 많은 사이트들이 존재하니 자신에게 맞는 사이트를 사용하면 된다).

  • regular xpressions 101 : PHP, PCRE, Python, Golang, JavaScript 정규식을 테스트 할 수 있다. 그리고 입력한 정규식 패턴에 대한 설명과 매칭 결과를 상세히 보여줘서 상당히 유용하다.
  • PHP Live Regex : PHP 정규식(PCRE)만 지원하지만 preg_match, preg_replace 등의 함수 등의 실행 결과를 바로 확인 할 수 있어 편리하다.
  • REGEXPER : 정규식을 Railroad Diagrams으로 보여준다. 단, PCRE와 완전히 호환되지 않기 때문에 PCRE 문법이 포함된 정규식은 오류가 난다.

다음은 정규식 사용 예시를 몇가지 남겨둔다. 웹 상에서 공개되어 있는 예시들도 있고 직접 만들어 사용했던 정규식도 포함되어 있다.

유니코드 공백 문자들을 일반 공백 문자(0x20)로 치환

<?php
$result = trim(preg_replace('/[\\pZ\\pC]+/u', ' ', $str));

이와 관련된 유사한 내용은 htmlspecialchars_decode와 html_entity_decode의 문자열 처리의 다른 점을 참고하자.

한글 추출 / 제외

<?php
// http://phpschool.com/link/tipntech/77239
$text = '!@#$%^&*()_+ 가나다라 1234567890 abcdefgh';
echo preg_replace('/\p{Hangul}/u', '', $text) . "\n";   // 한글 제외
echo preg_replace('/\P{Hangul}/u', '', $text) . "\n";   // 한글만 남김

// !@#$%^&*()_+  1234567890 abcdefgh
// 가나다라

// 한글 범위
// [\x{ac00}-\x{d7a3}] 가-힣
// [\x{3131}-\x{314e}] ㄱ-ㅎ
// [\x{314f}-\x{3163}] ㅏ-ㅣ

// 무슨 문자가 더 있나 찍어보기
// for($i = 0x31; $i < 0xff; $i ++) {
//     echo iconv('UCS-2BE', 'UTF-8', pack('H*', '31'.strtolower(dechex($i))));
// }

대상 내에서 문자열로 정의된 영역을 추출하는 예시

<?php
$string = <<<STR
\$a = "123test-string";
"test-string\"test-string"
'test-string"test-string\'test-string'

'test-string"
        test-string\'test-string'

sample

""
'"'
''
STR;

$regex = '/(?P<string>(["\'])(?s:(?=(\\\\?))\g{-1}.)*?\g{-2})/';
preg_match_all($regex, $string, $matches);
print_r($matches['string']);

위 예시를 응용해서 html에서 이미지 url만 추출하는 예시다.

<?php
$string = <<<STR
<img src="test url" />
<img alt="ver" src="http://test/\"'url" />
<img alt="v\"er" src="test url" />
STR;

$regex = '/<img\s+[^>]*src\s*=\s*(?P<images>(["\'])(?s:(?=(\\\\?))\g{-1}.)*?\g{-2})/';
preg_match_all($regex, $string, $matches);
print_r($matches['images']);

더 간단히 아래와 같이 해도 상관없다(url 내에 ' 또는 " 가 나올 수 없으므로).

<?php
preg_match_all('/<img\s+[^>]*src\s*=\s*[\'"]([^\'"]+)[\'"][^>]*>/', $string, $matches);

기타 간단한 정규식

이하 내용은 예시로 웹 상에 공개된 정규식들로 검증을 거치지 않았으니 참고만 하자.

  • 숫자만 체크 정규식

    • /^[0-9]+$/
  • 이메일 체크 정규식

    • /^[0-9A-Z]([-_\.]?[0-9A-Z])*@[0-9A-Z]([-_\.]?[0-9A-Z])*\.[A-Z]{2,20}$/i
  • 전화번호 정규식

    • /^\d{3}-\d{3,4}-\d{4}$/ : 휴대전화
    • /^01([0|1|6|7|8|9]?)-?([0-9]{3,4})-?([0-9]{4})$/ : 휴대전화
    • /^\d{2,3}-\d{3,4}-\d{4}$/ : 일반 전화번호
  • 아이디나 비밀번호 정규식

    • /^[a-z0-9_]{4,20}$/ : 4자 이상 20자 이하 영소문자/숫자/_ 허용
  • 태그(#) / 맨션(@) 추출

    • /(?:@|#)[^\s\t\n\r]+/ : @#으로 시작되는 문자열 추출

Comment