정규식 (Regular Expression) updated_at: 2023-05-17 16:48

Php 정규식 패턴(Regular Expression)

패턴 기호

정규식 패턴(Regular Expression) 기호
패턴 기호 설명
위치지정 ^ 문자열의 시작
$ 문자열의 끝
단일문자 . 임의 한 문자 (줄바꿈 문자를 제외한 모든 단일 문자)
반복성 ? 0 또는 1회 만 매치 (아예 없거나 1회 만 나타남, 최대 1회)
* 최소 0회 이상 반복 매치
+ 최소 1회 이상 반복 매치
{n} 정확히 n개 존재
{n,m} n개이상 m개 이하 존재
{n, } 적어도 n개 이상 존재
() 그룹으로 식
선택(or) (a|b) a 이거나 b 임
(.*) 어떤 문자든, 몇개든 올수 있슴(0개 혹은 그 이상의 어떤 글자)
문자 클래스 [0-9] 또는 d 모든 숫자
[^0-9] 또는 D 숫자가 아닌 모든 문자
[1-6] 1에서 6사이의 숫자
[1-6] 1에서 6사이의 숫자
[c-h] 소문자 c 에서 h 사이의 문자
[D-M] 대문자 D에서 M 사이의 문자
[^a-z] 소문자 a 에서 z 사이의 어떤 문자도 없슴
[_a-zA-Z] _(언더바) 이거나 혹은 대,소문자의 어떤 문자
[_4^a-zA-Z] 언더바이거나 숫자사이거나 혹은 ^ 이거나 a에서 z의 소문자이거나 A에서 Z의 대문자

패턴 변경자(Pattern Modifiers)

패턴 구분 문자인 슬래시(/) 뒤에서 지정

패턴 변경자
패턴 변경자 설명
i 대소문자 구분 안함
m 줄 단위 매칭
s `.`을 줄바꿈 문자에도 매칭
x 이스케이프 또는 문자 클래스 내부를 제외하고, 패턴의 공백문자를 무시
u 정규표현식(패턴 문자열)을 UTF-8 인코딩으로 취급

특수문자 이스케이프

  • 특수문자 : ., ,, ?, *, +, ^, $, [, ], (, )
  • 이스케이프 처리 : 특수문자 앞에 역슬래시 를 붙임
  • 만일, 단일 역슬래시와의 매치하려면, 역슬래시를 4번 씀(\\\\)
  • 특수 문자 이스케이프 전용 함수 : preg_quote()

예제

^.{2}[a-z]{1,2}_?[0-9]*([1-6]|[a-f])[^1-9]{2}a+$

^.{2}: 어떤 두자의 문자로 시작하고
[a-z]{1,2} : 소문자a에서 z중 어떤 문자가 1자 내지 2자이고
_?: 언더바가 있거나 없을 수 있고
[0-9]* : 0에서 9까지의 숫자가 0개 혹은 그 이상개 존재하며
([1-6]|[a-f]): 1에서 6사이의 어떤 숫자 혹은 a에서 f 사이의 어떤 소문자가 오며
[^1-9]{2}: 1에서 9사이의 어떤 숫자가 아닌 2자의 글자가오며
a+: a가 한개 혹은 그 이상개 존재한다.

^[1-9]{1}[0-9]*[.]{1}[0-9]{2}$

^[1-9]{1}: 1에서 9사이의 어떤 1개의 숫자로 시작하고
[0-9]*: 0에서 9까지의 숫자가 0개 혹은 그 이상개 존재하며
[.]{1}: 어떤 특정문자가 1개 오고
[0-9]{2}: 0에서 9까지의 숫자가 2개존재

정규표현식 관련 PHP 함수

preg_match

preg_match(pattern, subject)
최초 매치에서 멈춤
패턴에 맞는 문자가 있으면 true 반환

$subject = "Go To School";
$pattern = "/to/i";
if (preg_match($pattern, $subject, $matches))
   echo "맞는 패턴이 있습니다.(".$matches[0].")";   //맞는 패턴이 있습니다. (To) 가 출력됨.
else
   echo "맞는 패턴이 없습니다.";

/to/i to와 맞는 패턴(i는 대소문자 구분 안함 표시)

/[abc]/ a, b, c 중 어느 한 문자와 맞는 패턴

/[a-z]/ a부터 z까지 문자중 한 문자와 맞는 패턴

/[a-zA-Z]/ a부터 z까지, A부터 Z까지 중 한 문자와 맞는 패턴

/[^0-9]/ 숫자가 아닌 다른 패턴

/[\w]{3}/ 일반 문자가 세 번 이상 연속으로 있는 패턴

/[\d]{1,5}/ 숫자가 1번 이상 5번 이하 연속으로 있는 패턴

//[\W]{3,}/ 일반 문자가 아닌 문자가 3번 이상 연속으로 있는 패턴

/?/ 문자가 없거나 임의의 한 문자

/./ 줄바꿈 문자가 아닌 임의의 문자

/+/ 선행 패턴을 만족하는 문자(열)가 1번 이상 반복

/*/ 선행 패턴을 만족하는 문자(열)가 1번 이상 반복

ereg(), eregi()

PHP 5.3.0 이후로 ereg(), eregi() 는 사라졌다(Deprecated).
대신 preg_match 를 이용하여 값의 존재 여부를 확인할 수 있다.

$pattern = 'abcd';
$str = 'abcdtest';

ereg($pattern, $str); // Bad
preg_match('/'.$pattern.'/', $str) // Good

eregi($pattern, $str); // Bad
preg_match('/'.$pattern.'/i', $str) // Good

'/'문장의 시작과 끝에'/' 를 사용한다.
/i 는 대소문자 구분을 하지 않는 경우 사용한다.
\b 는 단어의 바운드리를 지정한다.

if (preg_match("/\bweb\b/i", "PHP is the web scripting language of choice.")) {
    echo "A match was found."; // result
} else {
    echo "A match was not found.";
}

if (preg_match("/\bweb\b/i", "PHP is the website scripting language of choice.")) {
    echo "A match was found.";
} else {
    echo "A match was not found."; // result -> website는 존재하지만 web 이라는 특정단어가 존재 하지 않는다.
}
$text = 'My name is Tom';
preg_match('/\btom\b/i', $text, $matches);
var_dump($matches); // array(1) { [0]=> string(3) "Tom" }
// 시작인 http:// 이고 /이 아닌것이 계속되고 대소문자를 구별하지 않는다.
preg_match("/^(http:\/\/)?([^\/]+)/i", "http://www.onstory.fun/index.html", $matches);
print_r($matches);

Array ( 
   [0] => http://www.onstory.fun 
   [1] => http:// <-- 프로토콜
   [2] => www.onstory.fun <!-- host
)

$host = $matches[2]; // www.onstory.fun
preg_match("/[^\.\/]+\.[^\.\/]+$/", $host, $matches);
echo "도메인은 {$matches[0]}\n"; // 도메인은 onstory.fun
검색엔진의 특정 검색어를 찾아내기
preg_match("/^.*?query=(.*)&/i",
   "http://search.naver.com/search.naver?where=nexearch&query=홈페이지제작&hw=1...", $matches);
print_r($matches);

Array
(
    [0] => http://search.naver.com/search.naver?where=nexearch&query=홈페이지제작&
    [1] => 홈페이지제작
)
// 모든 문자로 시작하고 "query=" 이 있으며 &로 끝나는 값, 여기서는 "()"안의 값이 검색어가 됩니다. 

preg_match_all

preg_match_all(pattern, subject)
모든 매치를 찾음

$html = "<b>bold text</b><a href=howdy.html>click me</a>";

preg_match_all("/(<([\w]+)[^>]*>)(.*)(<\/\\2>)/", $html, $matches);
print_r($matches);

Array
(
    [0] => Array
        (
            [0] => <b>bold text</b>
            [1] => <a href=howdy.html>click me</a>
        )

    [1] => Array
        (
            [0] => <b>
            [1] => <a href=howdy.html>
        )

    [2] => Array
        (
            [0] => b
            [1] => a
        )

    [3] => Array
        (
            [0] => bold text
            [1] => click me
        )

    [4] => Array
        (
            [0] => </b>
            [1] => </a>
        )

)
$yyyymmdd = '20230517';
preg_match_all("/([0-9]{4})([0-9]{2})([0-9]{2})$/", $yyyymmdd, $date);
print_r($date); 

 Array ( 
   [0] => Array ( [0] => 20230517 ) 
   [1] => Array ( [0] => 2023 ) 
   [2] => Array ( [0] => 05 ) 
   [3] => Array ( [0] => 17 ) )

preg_match_all() 은 html문서에서 태그값을 제거할때 유용하게 사용될 수 있습니다.

preg_match_all ("&#124;<[^>]+>(.*)</[^>]+>&#124;U", 
    "<b>샘플 </b><div align=left>테스트 샘플입니다.</div>", 
    $out, PREG_PATTERN_ORDER);
print $out[0][0].", ".$out[0][1]."\n";
print $out[1][0].", ".$out[1][1]."\n";
?>

preg_repalce

ereg_replace()

php5.3부터 ereg_replace라는 함수가 deprecated 되었다.

$string = 'April 15, 2003';
$pattern = '/(\w+) (\d+), (\d+)/i';
$replacement = '${1}1,$3';
echo preg_replace($pattern, $replacement, $string); // April1,2003
preg_replace("/[^a-zA-Z0-9_\.]/","",string); // 영문자,_,숫자 이외 모든 문자 제거
연속된 날짜를 '-' 로 구분하기
$yyyymmdd = '20230517';
$date = preg_replace("/([0-9]{4})([0-9]{2})([0-9]{2})$/", "\\1-\\2-\\3", $yyyymmdd);
echo $date; // 2023-05-17

정규식을 이용한 태그 제거

특정 태그 제거 정규식

// a tag 제거
$contents = preg_replace("/<a[^>]*>/i", '', $contents);
$contents = preg_replace("/<\/a>/i", '', $contents);

// textarea 제거
$content = preg_replace("!<textarea(.*?)>!is", "[textarea]", $content);
$content = preg_replace("!</textarea(.*?)>!is", "[/textarea]", $content);

// script 제거​
$str=preg_replace("!<script(.*?)<\/script>!is","",$str);

// iframe 제거
$str=preg_replace("!<iframe(.*?)<\/iframe>!is","",$str);

// meta 제거
$str=preg_replace("!<meta(.*?)>!is","",$str);

// style
$str=preg_replace("!<style(.*?)<\/style>!is","",$str);

&nbsp; 를 공백으로 변환

$str=str_replace("&nbsp;"," ",$str);

연속된 공백 1개로

$str=preg_replace("/\s{2,}/"," ",$str);

태그안에 style= 속성 제거

$str=preg_replace("/ zzstyle=([^\"\']+) /"," ", $str); // style=border:0... 따옴표가 없을때
$str=preg_replace("/ style=(\"|\')?([^\"\']+)(\"|\')?/","", $str); // style="border:0..." 따옴표 있을때

태그안의 width=, height= 속성 제거

$str=preg_replace("/ width=(\"|\')?\d+(\"|\')?/", "", $str);
$str=preg_replace("/ height=(\"|\')?\d+(\"|\')?/", "", $str);

a 태그에서 title 추출

$pattern ="/<a[^>]*title=[\"']?([^>\"']+)[\"']?[^>]*>/i";

a 태그에서 href 추출하는데 특정 순서만

$pattern ='/(href=)(\'|\")?([^<>\s\'\"]*)(\'|\"|\s|)/i';
preg_match_all($pattern, $linkArea[1][$z], $tmpLink);
print_r('link:'.$tmpLink[3][5].'<br>');

a 태그에서 내용 텍스트 추출

$pattern = '/<a(.*?)>(.*?)<\/a>/i';
preg_match($pattern, $value, $tmpTitle);

html tag 제거 정규식

$content = preg_replace("(\<(/?[^\>]+)\>)", "", $content);

img 태그 추출 src 추출

preg_match("/<img[^>]*src=[\"']?([^>\"']+)[\"']?[^>]*>/i",$str,$RESULT);
preg_match_all("/<img[^>]*src=[\"']?([^>\"']+)[\"']?[^>]*>/i",$str,$RESULT);

이미지만 추출하는 정규식

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

특정 엘리멘트 밑에 추출 정규식

preg_match('/<div id="my2">(.*?)<\/div>/is', $contents, $html);
preg_match("/\<span id=\"moonseller\"\>[^>]\<\/span\>/", $contents, $html);
평점을 남겨주세요
평점 : 5.0
총 투표수 : 1