티스토리 뷰

문자열 중에서 한글/한자/일어 찾는 정규식

정규식으로 이런 문자열을 체크하기 위해서는 유니코드 UTF-8로 인코딩 되어야 합니다.
인코딩 되어있지 않다면 iconv 를 통해 UTF-8로 변경하면 됩니다.
 
예제를 위해 한글/한자/일어를 검색을 통해 랜덤으로 뽑아왔습니다. ;;
이 예제에서는 영어나 특수문자를 제외한, '한글', '한자', '일어' 만 추출하는 것을 보여줍니다.

한자는 한국, 중국, 일본 공통으로 사용하는 것을 모은 것이라 일본에서 사용하는 한자를 검출할때는 '한자'와 '일어'를 같이 사용하면 됩니다.
유니코드는 한,중,일 한자를 통합해서 정의해서 따로 구분하려면 유니코드 목록을 참고하셔서 직접 구분하셔야 합니다. -_-;

한가지 주의할 점은 유니코드 문자열을 체크할 경우 u 옵션을 반드시 줘야 합니다.

//  예제 문자열
$content = "test content☆漢字〓韓國外交部對外稱, 應美方要求,韓國貿易部長金宗塤和美國貿易代表施瓦布本週一下午還舉行了一個「非正式磋商」。end◆ 日語〓慰謝料としてフルハウス(Full House)をあげるというィヨンジェの言葉に,ジウンは寝ても寝る事ができないで悩む。end◆ 한글〓해쉬(Hash)값 필터링 시스템(Filtering system)은 디지털 파일에 고유의 키 값을 매겨서 등록, 관리하는 것으로 저작권 침해 신고가 접수됐을 경우 이 키 값을 기준으로 검색, 침해 여부를 판단할 수 있는 방식이다. end★";
echo '<pre>';// PRE
 
//  한글
preg_match_all('!['
    .'\x{1100}-\x{11FF}\x{3130}-\x{318F}\x{AC00}-\x{D7AF}'
    .']+!u', $content, $match);
print_r($match);
 
//  한자
preg_match_all('!['
    .'\x{2E80}-\x{2EFF}'// 한,중,일 부수 보충
    .'\x{31C0}-\x{31EF}\x{3200}-\x{32FF}'
    .'\x{3400}-\x{4DBF}\x{4E00}-\x{9FBF}\x{F900}-\x{FAFF}'
    .'\x{20000}-\x{2A6DF}\x{2F800}-\x{2FA1F}'// 한,중,일 호환한자
    .']+!u', $content, $match);
print_r($match);
 
//  일어
preg_match_all('!['
    .'\x{3040}-\x{309F}'// 히라가나
    .'\x{30A0}-\x{30FF}'// 가타카나
    .'\x{31F0}-\x{31FF}'// 가타카나 음성 확장
    .']+!u', $content, $match);
print_r($match);
echo '</pre>';

위키의 유니코드 문자열 범위 목록을 참고하였습니다.


nl2br 사용시 <table>,<ul>,<ol> 테그까지 처리되지 않도록 개행문자 삭제

글 내용을 <textarea> 로 받아서 nl2br 을 하게될때, <table>,<ul>,<ol> 등 테그 사이의 개행문자 모두 <BR>처리가 되어 글 내용이 이상하게 표시되는 경우 해당 테그의 공백이나 탭 및 개행문자를 제거 하는 정규식 입니다.

HTML 테그가 있는 내용에 nl2br() 실행한 경우.

<table cellpadding="0" border="0"><br />
<tr><td><br />test subject</td><br />
</tr><br />
</table><br />

위와 같이 <table> 테그 안에 <br /> 테그가 들어가게 됩니다. 이러한 문제를 위해 테이블 테그 안의 경우 개행문자는 삭제하고 그 외의 개행문자를 <br /> 테그로 만드는 정규식 입니다.

$content = <<<___HTML___
test content 
<table border="1">
<tr>
    <td>cell2</td>
         <td>
          <ul>
                 <li>list1
</li>
            </ul></td>
</tr></table>
test content
___HTML___;
 
$content = preg_replace(
        Array(
            '!(\<(?:table|thead|tbody|tfoot|tr|td|ul|ol|li|dl).*?\>)[\s]+!is',
            '![\s]+(\<\/(?:thead|tbody|tfoot|tr|td|ul|ol|li|dt|dd)\>)!is'
        ), '\1', $content);
echo '<pre>'. htmlspecialchars($content) .'</pre>';

이 정규식은 2개로 나눠져 있는데, 오픈 테그와 클로즈 테그를 따로 처리하기 위한 것입니다.

예를들어 <table> 테그의 뒤에는 <tr> 테그가 오기 때문에, <table> 뒤에 오는 공백 및 개행문자는 지워야 하지만, 앞에 있는 공백 및 개행문자는 유저가 의도하는 것일 수 있기 때문에 삭제하면 안됩니다.
마찬가지로 </table> 도 같은 이유로 다르게 처리됩니다.

이 정규식은 단순히 nl2br() 을 사용하기 위한 것이고, 자신이 직접 위지윅 에디터를 구현하려고 할 경우에는 정규식을 다르게 적용 해야 합니다.


PHP에서 사용되는 'HEARDOC'(<<<_HTML_ _HTML_; 형태의 문자열) 입력 구문을 검출하기

PHP는 HEARDOC 이라는 독특한 문법을 지원합니다.
이를 사용할때 규칙은 아래와 같습니다.
  • 문법의 시작은 <<< 세개로 시작하며, 시작 이름 뒤에는 다른 문자가 오면 안됩니다.
  • 이름은 한글, 영문, 숫자, 언더바(_)와 특수문자(☆★◎● 등)로 이뤄질 수 있습니다. !, @, #, $, % 등의 특수문자는 허용되지 않습니다. 호환성을 위해 가급적 영문과 숫자, 언더바로만 작성하는게 좋습니다.
  • 이 이름은 <<< 와 ; 를 제외한 시작 이름과 마지막 이름이 같아야 합니다.
  • 또한 마지막 이름 앞에 공백이나 다른 문자가 오면 안됩니다. 즉, 마지막 이름은 문장의 가장 처음에 위치해야 합니다.

$content = <<<___HTML___
\$content = <<<__TEST__
test content 1
__TEST__;
\$content = <<<_한글_CON★TENT_
test content 2
test content
_한글_CON★TENT_;
echo \$content;
___HTML___;
 
// !, @, #, $ 등의 특수문자를 제외한 모든 문자 체크
preg_match_all(
        '!\<\<\<([^\x00-\x2E\x3A-\x40\x5B-\x5E\x60\x7B-\x7F]+).*?^\1\;!ism',
        $content, $match);
print_r($match);
 
// 영문, 숫자, 언더바만 체크
preg_match_all(
        '!\<\<\<([\w\d\_]+).*?^\1\;!ism',
        $content, $match);
print_r($match);


위에서 첫번째 정규식은 특수문자를 제외한 모든 문자열을 가능하게 체크하고 있습니다. 아래 정규식은 호환성에 중점을 두고 영문, 숫자, 언더바(_)만 체크하는 정규식입니다. 호환을 위해서는 가급적 아래 코드를 쓰는게 좋겠죠.


소스코드에서 주석 캡쳐

주석을 표현하는 세가지 형태를 검출하는 정규식입니다.

// 주석 1
# 주석 2
/* 멀티라인 주석 3
두번째라인 */

주석의 기본 규칙은, 단일 라인 주석일 경우 주석 시작코드와 함께 라인의 끝까지를 주석으로 포함하고, 멀티라인의 경우 해당 코드 사이를 주석으로 체크합니다.

그러나 이 정규식은 문자열 내에 포함된 경우라든가 PHP의 HEARDOC 문법에 포함된 경우는 체크하지 않습니다.

$content = <<<___HTML___
/* it's multiline-comment
   end */
$subject = 'test content';# perl-type comment
// display php info
phpinfo();// PHP info?
exit;
___HTML___;
 
preg_match_all('!(?:/\*.*?\*/|#.*?$|//.*?$)!sm', $content, $match);
print_r($match);
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함