홈으로 | 무료회원가입 | 아이디/비번찾기
추천음악방송
PCRE 정규표현식 예제로 개념잡기.
8년 전
PCRE 정규표현식 예제로 개념잡기.

http://kr2.php.net/manual/en/ref.pcre.php
http://kr2.php.net/manual/en/reference.pcre.pattern.syntax.php
http://kr2.php.net/manual/en/reference.pcre.pattern.modifiers.php

위 링크가 이해가 안되어도 스크롤을 천천히 내려가며 한번 읽어주고 본문을 읽어주세요.
본문에 없는건 묻지 마세요. 모릅니다.


pattern syntax
1. [0-9] 는 \d 로 표현하는것이 편리하다.
글 수정시에 글번호를 체크해 보자.

<?php
if(!isset($_POST['seq']) || !preg_match('/^[1-9]\d*$/', $_POST['seq'])) { // 시퀀스는 1부터 시작하므로 처음은 1-9 이다.
    header('HTTP/1.1 400');
    echo str_repeat('해킹은 사절<br />', 200);
    exit;
}
?>


2. ' '(공백)은 알아보기 쉽도록 \s 로 써주면 좋다.

3. \(백슬래시) 를 표현할때 버그인지 \\ 로 하면 안된다.
\\\ \\\\\ 이런식으로 홀수가 되는데 그냥 \x5c 로 hex 표현해주면 편하다.
4. (?) 로 매칭결과에 표현되지 않고 조건만 표현할 수 있다.
문자는 *나 + 등의 가변길이를 지원하지 않는다.
(?=문자) (?!문자) : 문자열 길이 계산에 반영되지 않고 조건만 검사한다.

<?php
$text = 'abcd';
echo preg_replace('/(?=b)./', 'e', $text); // 조건에 맞는곳에서 한글자 가져오기.
?>


aecd

(?<=문자) (?<!문자) : 문자열 길이 계산에 반영된다.

<?php
$text = 'abcd';
echo preg_replace('/(?<=b)./', 'e', $text); // 조건이 맞는곳 다음 한글자 가져오기.
?>


abed

따옴표로 감싼 문자열에 \ 가 있어도 정확하게 뽑아내 보자.

<?php
$text = <<<TEXT
<script type="text/javascript">
document.body.innerHTML += "<div style="font-size:12px; color:white; background-color:black;\">";
document.body.innerHTML += '\'예제 만들기 귀찮네...\'';
document.body.innerHTML += "</div>";
TEXT;
$cnt = preg_match_all('@(?<!\x5c)([\'"])(.*?)(?<!\x5c)\1@', $text, $matches);
print_r($matches[2]);
?>


Array
(
     [0] => text/javascript
     [1] => <div style="font-size:12px; color:white; background-color:black;\">
     [2] => \'예제 만들기 귀찮네...\'
     [3] => </div>
)

5. 줄바꿈이 \r\n 인지 \n 인지 비교하기 귀찮으므로 [\r\n]+ 혹은(\r?\n) 으로 표현하자.

6. UTF-8 을 사용한다면 /u modifier 에서 \x{ac00} 같은 표현이 가능해진다.
[\x{ac00}-\x{d7af}] 이렇게 쓰면 [가-ㅎㅣㅎ] 이다.
가-ㅎㅣㅎ 만이라면 그냥 UTF-8 로 써도 동작하는데,
타 언어나 특수문자 같은 경우에 잘 안될수가 있다.
그럴때를 위해 기억해 두자. (코드는 UCS-2)

<?php
$text = 'abcd가나다라2345';
$cnt = preg_match_all('/./u', $text, $matches); // 글자 단위로 잘라 가져온다.
print_r($matches);
echo preg_replace('/[^\x{ac00}-\x{d7af}]+/u', '', $text); // 한국어만 남긴다.
?>


Array
(
    [0] => Array
        (
            [0] => a
            [1] => b
            [2] => c
            [3] => d
            [4] => 가
            [5] => 나
            [6] => 다
            [7] => 라
            [8] => 2
            [9] => 3
            [10] => 4
            [11] => 5
        )

)
가나다라


7. UTF-8 에서 한가지 더 이점이 있다. \p 가 그것이다.

<?php
$text = '가 나 다'; // 나와 다 사이는 묶음빈칸이다.
echo preg_replace('/\p{Zs}/u', '', $text);
?>


가나다

이렇듯 문자들을 속성에 따라 그룹으로 나누어 표기할 수 있다.
위의 예제는 Space separator 이고, /u 선언에 의해 UTF-8 로 정의되어 묶음빈칸도 함께 처리되었다.
공백이 아닌것을 매칭하려면 [^\p{Zs}] 로 해도 되겠지만 \P 라는 표현으로 쉽게 표현할 수도 있다.
\pZ 으로 한다면 엔터, 탭 등도 모조리 매칭될것이다.
메뉴얼에 사용된 명칭은 http://unicode.org 에서 확인할 수 있다.


pattern modifier
1. /m
여러 줄이 있고 ^ 나 $ 를 매 줄의 시작과 끝으로 하고자 한다면 /m 을 사용한다.

<?php
$text = <<<TEXT
1. 가
2. 나
3. 다
TEXT;
preg_match_all('/(^(\d+)|(.)$)/mu', $text, $matches); // 앞의 수와 뒤의 한글자를 가져온다.
print_r($matches[2]);
print_r($matches[3]);
?>


Array
(
     [0] => 1
     [1] =>
     [2] => 2
     [3] =>
     [4] => 3
     [5] =>
)
Array
(
     [0] =>
     [1] => 가
     [2] =>
     [3] => 나
     [4] =>
     [5] => 다
)

2. .* 로 여러줄을 다 매칭할 때는 /s 를 사용한다.
3. 태그를 표현할 때 처럼 / 가 많은 곳에서는 @ 처럼 잘 안나오는것으로 패턴구분자를 바꾼다.

<?php
$text = <<<TEXT
<a href="http://xenosi.de/" target="_blank" title="송효진의 홈페이지">
    아무것도
없어요.
</a>
TEXT;
preg_match('@<a\s.*?>(.*?)</a>@su', $text, $matches);
print_r($matches[1]);
?>



         아무것도
없어요.


4. 기본적으로 정규식은 매치되는 표현중 가장 큰 값을 가져온다.
가장 작은 값을 가져오는 방식은 3가지가 있다.

<?php
$text = <<<TEXT
<a href="http://xenosi.de/" target="_blank" title="송효진의 홈페이지">
     아무것도
없어요.
</a>
<a href="http://xenosi.de/" target="_blank" title="송효진의 홈페이지">
     아무것도
없어요.
</a>
TEXT;
echo "--1--\n";
preg_match('@<a.*?>(.*)</a>@su', $text, $matches); // 모두 다 가져올 것이다.
print_r($matches[1]);
echo "--2--\n";
preg_match('@<a.*?>(.*?)</a>@su', $text, $matches); // 가장 간편하고 알아보기 좋다. 추천.
print_r($matches[1]);
echo "--3--\n";
preg_match('@<a(?U).*>(?U)(.*)</a>@su', $text, $matches); // pattern modifier 식을 부분만 적용하는데 범위를 알아보기가 좋지 않다.
print_r($matches[1]);
echo "--4--\n";
preg_match('@<a.*>(.*)</a>@Usu', $text, $matches); // 식 전체에 적용된다.
print_r($matches[1]);
?>


--1--

     아무것도
없어요.
</a>
<a href="http://xenosi.de/" target="_blank" title="송효진의 홈페이지">
     아무것도
없어요.
--2--

     아무것도
없어요.
--3--

     아무것도
없어요.
--4--

     아무것도
없어요.


5. 대소문자 구별 없애는 /i 는 설명하면 손가락 아프다.


응용 예제.

<?php
$text = <<<TEXT
<a href="http://xenosi.de/" target="_blank" title ="송효진의 홈페이지">
     아무것도
없어요.
</a>
<a href="http://xenosi.de/?a=가&b=나&c=다&d&e" target="_blank" title = "송효진의 홈페이지">
     아무것도
없어요.
</a>
TEXT;

if(preg_match('@<a\s(.*?)>@s', $text, $matches)) {
     $cnt = preg_match_all('@([^\pZ=]+?)\pZ*=\pZ*([\'"])(.*?)\2@us', $matches[1], $matches2);
     print_r($matches2[1]);
     print_r($matches2[3]);
}
echo preg_replace_callback('@href=([\'"])((https?://[^\?]+\??)?(.*?))\1@', 'urlencode_callback', $text);

function urlencode_callback($matches)
{
     return 'href='.$matches[1].$matches[3].preg_replace_callback('/(.*?)=([^&]+)/', 'urlencode_value_callback', $matches[4]).$matches[1];
}

function urlencode_value_callback($matches)
{
     return $matches[1].'='.urlencode($matches[2]);
}

?>


Array
(
     [0] => href
     [1] => target
     [2] => title
)
Array
(
     [0] => http://xenosi.de/
     [1] => _blank
     [2] => 송효진의 홈페이지
)
<a href="http://xenosi.de/" target="_blank" title ="송효진의 홈페이지">
         아무것도
없어요.
</a>
<a href="http://xenosi.de/?a=%EA%B0%80&b=%EB%82%98&c=%EB%8B%A4&d&e" target="_blank" title = "송효진의 홈페이지">
         아무것도
없어요.
</a>


인덱싱을 위한 단어 추출 예제
http://www.phpschool.com/gnuboard4/bbs/board.php?bo_table=tipntech&wr_id=50824&sca=&sfl=wr_name%7C%7Csubject&stx=%BC%DB%C8%BF%C1%F8&sop=and&page=2


끝으로 이 문서를 하일라이팅 하기 위한 소스를 붙이고 마친다.
원본글은 첨부파일로 올린다.

<?php

$pattern[] = '/&/';
$replacement[] = '&';
$pattern[] = '/</';
$replacement[] = '<';
$pattern[] = '/>/';
$replacement[] = '>';
$pattern[] = '/(\r?\n)/';
$replacement[] = "<br />\n";
$pattern[] = '/\s{4}|\t/';
$replacement[] = '    ';
$pattern[] = '@^\*\*(.*)<br />@m';
$replacement[] = '<h3>\1</h3>';
$pattern[] = '@^\*(.*)<br />@m';
$replacement[] = '<h2>\1</h2>';
$pattern[] = '@(https?://[^\s<"]+)@';
$replacement[] = '<a href="\1" target="_blank">\1</a>';
$pattern[] = '@(<\?php<br />.*?\?><br />)@s';
$replacement[] = '<div style="background-color:black; color:white; padding:10px; font-family:GungSuhChe,MonoSpace;">\1</div>';
$pattern[] = '@<-<br />(.*?)-><br />@s';
$replacement[] = '<div style="background-color:#003300; color:white; padding:10px; font-family:GungSuhChe,MonoSpace;">\1</div>';
$pattern[] = '@<#<br />(.*?)#><br />@s';
$replacement[] = '<div style="background-color:#330000; color:white; padding:10px; font-weight:bold; font-family:GungSuhChe,MonoSpace;">\1</div>';

echo preg_replace($pattern, $replacement, $_POST['code']);
exit;

?>


최신 php 는 메모리 관리를 위해 아래와 같은 설정이 포함되었다.
큰 텍스트에 적용할 경우 아무 오류없이 안되어버리는 현상이 있으면,
이 값을 의심하자.
pcre.backtrack_limit integer
pcre.recursion_limit integer


추천추천 : 443 추천 목록
번호 제목
3,025
 윈도우10 시스템파일 손상 (초간단 오류 복구방법!!)
3,024
 PHP 파일 존재 여부 파악하기(로컬 파일 존재 및 원격지 파일 존재)
3,023
 [CSS] 박스 세로 가운데 중앙 정렬 6가지
3,022
 CSS Layout 수평 & 수직 정렬
3,021
 여러 도메인들 간 쿠키 공유하기
3,020
 태그 사이에 있는 텍스트를 추출
3,019
 [JQuery] textbox focus on off일때 숫자 콤마 보여주기
3,018
 쿠키 생성,가져오기,삭제
3,017
 사용자 함수 모음
3,016
 마우스,키보드 제한 ( 오른쪽클릭,드래그,영역선택등..)
3,015
 [HTML5] <video> - DOM으로 제어하기
3,014
 HTML5 video 태그에서 영상 좌우반전
3,013
 PHP - 특정 태그 및 문자열 추출, 제거
3,012
 [PHP] define과 defined의 차이
3,011
 우클릭 완벽차단 스크립트
3,010
 iframe 높이 100% 맞추기
3,009
 curl 함수를 이용한 HTTP REFERER 변경
3,008
 윈도우10 시스템 파일 및 Dism 검사
3,007
 텍스트 줄바꿈, 글자자르기 CSS
3,006
 jQuery Mobile에서 유용한 코드 10가지.
3,005
 [PHP] dirname()함수와 $_SERVER 관련 상수들
3,004
 [PHP] 파일 크기, 사이즈 불러오는 함수, filesize()
3,003
 [jQuery] jQuery Quick API
3,002
 [ transition ] 링크 hover 색상 변화 속도 조절
3,001
 PHP 5.3.0 에서 사라진 함수들 대체
목록
뮤직트로트 부산광역시 부산진구 가야동 ㅣ 개인정보취급방침
Copyright (C) musictrot All rights reserved.