PCRE 정규표현식 예제로 개념잡기.
http://kr2.php.net/manual/en/ref.pcre.phphttp://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 로 써주면 좋다.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;
}
?>
3. \(백슬래시) 를 표현할때 버그인지 \\ 로 하면 안된다.
\\\ \\\\\ 이런식으로 홀수가 되는데 그냥 \x5c 로 hex 표현해주면 편하다.
4. (?) 로 매칭결과에 표현되지 않고 조건만 표현할 수 있다.
문자는 *나 + 등의 가변길이를 지원하지 않는다.
(?=문자) (?!문자) : 문자열 길이 계산에 반영되지 않고 조건만 검사한다.
<?php
$text = 'abcd';
echo preg_replace('/(?=b)./', 'e', $text); // 조건에 맞는곳에서 한글자 가져오기.
?>
$text = 'abcd';
echo preg_replace('/(?=b)./', 'e', $text); // 조건에 맞는곳에서 한글자 가져오기.
?>
aecd
(?<=문자) (?<!문자) : 문자열 길이 계산에 반영된다.<?php
$text = 'abcd';
echo preg_replace('/(?<=b)./', 'e', $text); // 조건이 맞는곳 다음 한글자 가져오기.
?>
$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]);
?>
$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]+ 으로 표현하자.(
[0] => text/javascript
[1] => <div style=\"font-size:12px; color:white; background-color:black;\">
[2] => \'예제 만들기 귀찮네...\'
[3] => </div>
)
6. UTF-8 을 사용한다면 /u modifier 에서 \x{ac00} 같은 표현이 가능해진다.
[\x{ac00}-\x{d7af}] 이렇게 쓰면 [가-ㅤㅎㅣㅎ] 이다.
가-ㅤㅎㅣㅎ 만이라면 그냥 UTF-8 로 써도 동작하는데,
타 언어나 특수문자 같은 경우에 잘 안될수가 있다.
그럴때를 위해 기억해 두자. (코드는 UCS-2)
7. UTF-8 에서 한가지 더 이점이 있다. \p 가 그것이다.
<?php
$text = '가 나 다'; // 나와 다 사이는 묶음빈칸이다.
echo preg_replace('/\p{Zs}/u', '', $text);
?>
$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]);
?>
$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 를 사용한다.(
[0] => 1
[1] =>
[2] => 2
[3] =>
[4] => 3
[5] =>
)
Array
(
[0] =>
[1] => 가
[2] =>
[3] => 나
[4] =>
[5] => 다
)
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]);
?>
$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]);
?>
$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 는 설명하면 손가락 아프다.아무것도
없어요.
</a>
<a href="http://xenosi.de/" target="_blank" title="송효진의 홈페이지">
아무것도
없어요.
--2--
아무것도
없어요.
--3--
아무것도
없어요.
--4--
아무것도
없어요.
응용 예제.
<?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]);
}
?>
$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>
(
[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;
?>
$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
큰 텍스트에 적용할 경우 아무 오류없이 안되어버리는 현상이 있으면,
이 값을 의심하자.
pcre.backtrack_limit integer
pcre.recursion_limit integer
출처:http://www.phpschool.com/gnuboard4/bbs/board.php?bo_table=tipntech&wr_id=58121&page=1
반응형
'유용한정보' 카테고리의 다른 글
동지팥죽의 유래 (0) | 2007.12.22 |
---|---|
동지팥죽의 유래 (0) | 2007.12.22 |
암탉이 울면 집안이 망한다는 말의 유래 (0) | 2007.12.22 |
암탉이 울면 집안이 망한다는 말의 유래 (0) | 2007.12.22 |
PCRE 정규표현식 예제로 개념잡기.v2 (0) | 2007.12.22 |
세계에서 가장 먼저 해뜨는 곳은? 우리나라는? (0) | 2007.12.22 |
세계에서 가장 먼저 해뜨는 곳은? 우리나라는? (0) | 2007.12.22 |
교통사고후 속 메스꺼우면 위험 (0) | 2007.12.22 |
교통사고후 속 메스꺼우면 위험 (0) | 2007.12.22 |
잘못 알고 있는 의학 상식 (0) | 2007.12.22 |