[php] 정규식 (Regular Expression)

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

Php 정규식 패턴(Regular Expression)

  • 참조 : https://www.php.net/manual/en/reference.pcre.pattern.syntax.php
  • 참조(한글번역) https://blog.asamaru.net/2017/01/07/php-regex-prolog/ 에 한글로 설명이 잘되어 있었어 참조로 남깁니다.

두가지 이상의 의미를 가지는 것

아래에서 자세히 설명되겠지만 몇몇 기호는 2가지 이상의 의미를 가진다.

  • ^ : 패턴의 시작을 알리거나 케릭터클래스 내에서는 반전(부정)의 의미를 가진다.
  • . : 케릭터클래스 밖에서는 임의의 한 문자를 의미하지만 케릭터클래스내에서는 다른 의미를 가지지 않는다.
  • ? : 0 또는 1회의 한정자이지만 서브패턴내에서는 greedy의 의미로 사용된다.

패턴 구분자(Delimiters)

정규식의 시작과 끝을 알릴때는 통상 /(슬래쉬)을 사용하나 PHP에서는 | (파이프) 혹은 @ 등을 사용합니다.(기타 다양한 특수문자 #, &, !, ~,등 정규식 패턴등에 사용하지 않는 문자는 적용가능.)
동일하게 사용되지만 가장 큰 차이점은 / 가 문장중에 나올때, 가령 url을 정규식으로 처리할때 역슬래쉬()를 넣어주어서 정규식가 다르다는 것을 인식 시켜주어야 하지만
|(파이프 혹은 기타 특수문자)를 사용하면 그러지 않아도 된다는 장접이 있습니다.(다른 언어의 정규식 패턴과의 호환을 생각하면 / 을 사용하는 것을 추천드림)

$pattern = '|<[^>]+>(.*)</[^>]+>|U';
$pattern = '/<[^>]+>(.*)<\/[^>]+>/U'; // '/' 로 정규식을 표현할때는 </[ 을 <\/[ 이렇게 역슬래쉬를 추가하여야 정상적으로 동작합니다.

메타 케릭터

메타 케릭터는 크게 대괄호(squqre brackets []) 안에 사용되는 것과 밖에 사용되는 것으로 구문 가능하다.

대괄호 밖에서 사용하는 메타케릭터

  • \ : escape character
  • ^ : 반전(이 이후의 글자가 아닌.)
  • $ : 문자열의 끝
  • . : 임의 한 문자 (줄바꿈 문자(개행문자)를 제외한 모든 단일 문자)
  • [] : 케릭터클래스의 시작과 종료
  • | : start of alternative branch
  • () : 서브패턴의 시작과 종료
  • ? : {0, 1} 0 또는 1회 만 매치 (아예 없거나 1회 만 나타남, 최대 1회), greedy의 반전에도 사용
  • * : {0,} 선행 패턴을 만족하는 문자(열)가 최소 0회 이상 반복 매치
  • + : {1,} 선행 패턴을 만족하는 문자(열)가 최소 1회 이상
  • {} : 최소/최대 한정자의 시작과 종료

대괄호 안에서 사용하는 메타케릭터

  • \ : escape character(특수문자를 이스케이프 하는 문자)
  • ^ : 부정문자(첫번째 캐릭터 앞에 사용)
  • - : 문자의 범위

사용예제

  • [\d] 또는 [0-9] : 모든 숫자

  • [\D] 또는 [^0-9] : 숫자가 아닌 모든 문자

  • [\w] : 모든 일반 문자 (a-z, A-Z, 0-9, including _ (underscore))

  • [\W] : 일반 문자가 아닌 모든 문자

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

  • [^a-z] : 소문자 a 에서 z 사이의 어떤 문자도 없슴

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

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

  • [_a-zA-Z] : _(언더바) 이거나 혹은 대,소문자의 어떤 문자

  • [_4^a-zA-Z] : 언더바이거나 숫자사이거나 혹은 ^ 이거나 a에서 z의 소문자이거나 A에서 Z의 대문자

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

  • [^abc] : a, b, c 중 어느 한 문자와 도 맞지 않는 패턴

  • [1-6] : 1에서 6사이의 숫자

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

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

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

  • [c-h] : 소문자 c 에서 h 사이의 문자

  • [D-M] : 대문자 D에서 M 사이의 문자

  • [\dABCDEF] : 16진수

반복성(Repetition)

  • ? : {0, 1} 0 또는 1회 만 매치 (아예 없거나 1회 만 나타남, 최대 1회), greedy의 반전에도 사용
  • * : {0,} 선행 패턴을 만족하는 문자(열)가 최소 0회 이상 반복 매치
  • + : {1,} 선행 패턴을 만족하는 문자(열)가 최소 1회 이상
  • {n} : 정확히 n개 존재
  • {n,m} : n개이상 m개 이하 존재
  • {n,} : 적어도 n개 이상 존재(표기시 m 자리에 공백이 존재 하지 말아야 한다.)

이스케이프 시퀀스 \

이스케이프 시퀀스는 각각의 아래 용도로 사용된다.

특수문자 이스케이프

특수문자의 속성을 일반문자로 변경한다.

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

패턴의 비인쇄 문자를 인코딩

앞에 언급드린 특수문자 이스케이프 는 특수문자 앞에 역슬래쉬를 둚으로서 일반문자화 했다면 여기서는 일반문자(영문자나 숫자) 앞에 역슬래쉬를 둚으로서 특정한 역활을 부여한다.

  • \r : new line
  • \r : return 문자
  • \t : tab 문자
  • \1 ~ \9 : 1부터 9까지는 역참조를 의미한다.

일반문자지정

  • \d : 임의의 10진수
  • \D : 10진수가 아닌 문자
  • \h : 모든 수평 공백 문자 (PHP 5.2.4 이후)
  • \H : 수평 공백 문자가 아닌 모든 문자 (PHP 5.2.4 이후)
  • \s : 공백 문자
  • \S : 공백이 아닌 모든 문자
  • \v : 모든 수직 공백 문자 (PHP 5.2.4 이후)
  • \V : 수직 공백 문자가 아닌 모든 문자 (PHP 5.2.4 이후)
  • \w : 모든 "word" 문자
  • \W : 모든 "non-word" 문자

특정 Alternation

  • `\b : 단어(word) 경계
  • `\B : 단어(not a word) 경계가 아님
  • `\A : 목표 문자열 시작 (다중 행 모드와 무관)
  • `\Z : 목표 문자열 끝 또는 마지막 줄바꿈 (다중 행 모드와 무관)
  • `\z : 목표 문자열 끝 (다중 행 모드와 무관)
  • `\G : 주제어에서 첫 번째로 일치하는 위치

Word Boundaries

word boundaries는 \b 로 표시되며 워드로만 표시되는 것에 한정된다. 즉 특수문자등을 제외하고 하나의 워드와 매치되는 것이다.

$str = 'PHP is awesome. How is CakePHP?';

$pattern = '/PHP/';
preg_match_all($pattern, $str, $matches); // [[PHP, PHP]] : CakePHP 의  PHP도 추출

$pattern = '/\bPHP\b/';
preg_match_all($pattern, $str, $matches); // [ PHP]]  : CakePHP 의  PHP는 가져오지 않음

$str = 'PHP is awesome. How is Cake PHP?';
$pattern = '/\bPHP\b/';
preg_match_all($pattern, $str, $matches); // [[PHP, PHP]] 

앵커(Anchors)

  • ^ : 문자열의 시작, 문자클래스([])에서는 반전으로 사용
  • $ : 문자열의 끝

POSIX 표기법으로 지원되는 문자 클래스

아래는 [: :] 안에 표기함으로서 실행된다.
예로 [01[:alpha:]%]는 "0", "1", 모든 알파벳 문자 또는 "%"와 일치한다.

  • alnum : letters and digits
  • alpha : letters
  • ascii : character codes 0 - 127
  • blank : space or tab only
  • cntrl : control characters
  • digit : decimal digits (same as \d)
  • graph : printing characters, excluding space
  • lower : lower case letters
  • print : printing characters, including space
  • punct : printing characters, excluding letters and digits
  • space : white space (not quite the same as \s)
  • upper : upper case letters
  • word : "word" characters (same as \w)
  • xdigit : hexadecimal digits

패턴 변경자(Pattern Modifiers)

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

  • i : 대소문자 구분 안함
  • m : 줄 단위 매칭
  • s : .을 줄바꿈 문자에도 매칭
  • x : 이스케이프 또는 문자 클래스 내부를 제외하고, 패턴의 공백문자를 무시
  • e : preg_replace() 만 사용하는 변경자로 변경할 문자열을 PHP 코드로 처리하고, 그 결과를 검색된 문자열의 이용하여 일반적인 치환을 합니다.
  • A : 이 변경자를 지정하면, 패턴을 강제적으로 "고정"합니다
  • D : 이 변경자가 설정되면, 패턴의 달러($) 메타문자는 주어진 문자열의 마지막에만 대응합니다
  • S : 이 변경자를 지정하면, 추가 분석을 행합니다. 현 시점에서, 패턴의 분석은 하나의 고정된 시작 문자를 가지지 않는 비고정 패턴에만 유용합니다
  • U : 이 변경자는 수량 지시의 "greediness"를 뒤집습니다. 그리하여 기본값으로 not greedy하게 합니다. 하지만 "?"가 붙으면 greedy하게 됩니다.
  • X : 이 변경자는 펄과 호환되지 않는 PCRE의 추가 기능을 사용하게 합니다. 패턴의 문자와 결합된 백슬래시가 특별한 의미를 지니지 않을 경우에 에러를 발생시켜서, 차후에 추가 기능을 위해 예약해둡니다.
  • J : 내부 옵션 (?J) 설정은 영역의 PCRE_DUPNAMES 옵션을 변경합니다. 서브패턴에 동일한 이름을 허용합니다.
  • u : 정규표현식(패턴 문자열)을 UTF-8 인코딩으로 취급
  • ims 를 사용할 경우 광범위하게 패턴을 적용할 수 있다(대소문자 구분안하고 줄바꿈까지 매칭)

U

정규식은 기본적으로 greedy하게 처리된다. 이것은 매우 중요하다. 이것을 nongreedy하게 만드는 것이 /U 다.
greedy : maximal matching (대략적 매칭)
nongreedy(greediness) : minimal matching (세부적 매칭)

아래와 같은 문자열에서 href 안의 url('https://onstory.fun')만 가져오고 싶다고 한다면..

 $str = '<a href="https://onstory.fun" title="Go to the homepage">Home</a>';

U를 사용하지 않은 경우 (greedy: default)

$pattern = '|".+"|'; // " 로 문자가 시작하고 "로 문자가 끝나며 안의 내용이 어떤 문자이던 하나 이상인것.
preg_match_all($pattern, $str, $matches);
Array([0] => Array([0] => "https://onstory.fun" title="Go to the homepage"))

위의 결과에서 보듯이 맨처음(https앞)의 " 와 맨뒤(homepage)의 "을 하나의 묶음으로 처리한다.

U를 사용한 경우(nongreedy)

$pattern = '|".+"|U';
preg_match_all($pattern, $str, $matches);
Array([0] => Array(
    [0] => "https://onstory.fun"
    [1] => "Go to the homepage"
  )
)

위의 결과는 ? 을 사용하여도 같은 결과를 나타낸다.
주의 할 것은 ? 는 greediness로 단방향성만이 있는 것이아니라 그 반대의 역활(현재 greediness 이면 greedy로도 바꾼다. )

$pattern = '|".+?"|';
* -> *? (.*?)
+ -> +? (.+?)
? -> ?? (.??)

서브패턴 ()

서브패턴은 좀더 자세한 내용을 찾을때 중요하게 사용됩니다.

  • (a|b) : a 이거나 b 임
  • (.*) : 어떤 문자든, 몇개든 올수 있슴(0개 혹은 그 이상의 어떤 글자)
  • (.*?) : 어떤 문자든, 몇개든 올수 있슴(0개 혹은 그 이상의 어떤 글자) greedy 하게
  • (?i): 내부옵션처리 : i 외에도 다양한 내부옵션 문자 사용가능
  • (?:) : 출력제외
  • (?i:) : 옵션은 출력에서 제외: i 외에도 다야한 패턴 변경자 사용가능

선택

cat(aract|erpillar) // cataract | caterpillar 
cat(aract|erpillar|) // cat | cataract | caterpillar 
((red|white) (king|queen)) // 최외곽 괄호부터 매칭을 하고 안의 괄호를 좌측에서 우측으로 매칭을 한다.

내부옵션

(?) 사이에 넣어서 사용가능합니다.

  • i : PCRE_CASELESS
  • m : PCRE_MULTILINE
  • s : PCRE_DOTALL
  • x : PCRE_EXTENDED
  • U : PCRE_UNGREEDY
  • X : PCRE_EXTRA
  • J : PCRE_INFO_JCHANGED

출력제외

위와 같은 경우 필요없는 많은 데이타를 출력하므로 필요없는 부분은 출력에서 제외할 필요가 있다.
이때 사용하는 것이 ?: 이다.

((?:red|white) (king|queen)) // (red|white)는 출력에서 제외

non-capturing subpattern 에 옵션을 지정할경우는 ? 과 : 사이에 넣어둔다.

preg_match('/(?i:saturday|sunday)/','Saturday', $matches); // i : 대소문자 구분을 하지 않는다.
preg_match('/(?:(?i)saturday|sunday)/','Saturday', $matches); // ?i 대소문자 구분을 하지 않는 것을 ?:출력하지 않겠다. 위와 같은 구문
$str = 'It is Sunday';
$str = 'It is Saturday';

(?:(Sat)ur|(Sun))day : 2 혹은 3의 backreference number 가 생성
(?|(Sat)ur|(Sun))day : 2  backreference number 만 생성

조건부 서브패턴

(?(condition)yes-pattern)
(?(condition)yes-pattern|no-pattern)

Repetition(반복)

앞서 설명한 케릭터 한정자(quantifiers)들은 반복 문에 포함된다.
캡쳐된 서브 패턴이 반복되면 캡처된 문자열은 마지막 반복에 일치한다

Assertions (어설션)

Look-ahead sssertions

(?= 긍정 어설션, (?!은 부정 어설션을 나타낸다. 예를 들어, \w+(?=;)는 단어 뒤에 세미콜론이 있는 단어를 일치하지만 세미콜론은 포함하지 않는다.

  • foo(?!bar)는 "bar"가 뒤에 붙지 않는 "foo"로 시작하는 string을 찾는다.
  • (?!foo)bar는 "foo"로 시작되지 않는 "bar" 항목을 찾지 않는다

Look-behind sssertions

(?<= 긍정 어설션, (?<!은 부정 어설션을 나타낸다. 예를 들어, (?<!foo)bar는 "foo"가 앞에 붙지 않는 "bar"의 항목을 찾는다

정규표현식 관련 PHP 함수

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

ereg_replace()와 eregi_replace()

PHP 5.3.0 이후로 ereg_replace(), eregi_replace() 는 사라졌다(Deprecated).
대신 preg_replace 를 이용하여 처리할 수 있다

$subject = "abcdef";
$pattern = '/^ABC/i'; 
$subject = preg_replace($pattern, '', $subject); 

preg_match vs preg_match_all

두 함수의 사용법은 거의 동일하다. 단 결과에서 preg_match 는 최조 매치된 결과만을 출력하는 반면 preg_match_all은 매치된 모든 결과를 출력한다.
따라서 preg_match_all 은 주로 U modifier 와 함께 사용된다. 또한 결과값으로는 매치된 카운트를 return 하며 매채내요을 볼경우는 3번째 인자값(matches)을 호출한다. $matches 첫번째 배열은 전체 패턴에 매치되는 내용을 나열하고 두번째 부터는 서브패턴() 로 묶인 첫번째 하위 패턴과 일치하는 문자열 배열입니다.

$str = 'urls: https://onstory.fun https://naver.com  https://google.com';
$pattern = '|(https?://)([^/\s]+)|'; // ^ 가 없을 경우
$mach_count = preg_match($pattern, $str, $matches);

preg_match

위에서 처음 match 되는 https://onstory.fun 에 대한 정보만 디스플레이 한다.

[
  [0] => https://onstory.fun
  [1] => https://
  [2] => onstory.fun
]

preg_match_all

[
  [0] => ['https://onstory.fun', https://naver.com', 'https://google.com']
  [1] => ['https://', 'https://, 'https://']
  [2] => ['onstory.fun', 'naver.com', 'google.com']
]

예제

패턴을 사용할때 모든 조건은 화이트 리스트 입니다. 즉 조건이 주어지지 않으면 모두가 출력됩니다.

패턴읽기 연습

<[^>]+>(.*)</[^>]+

<[^>]+> : < 문자와 > 문자 (태그열리고 닫힘) 가 나온 후
(.*) : 다음 태그(<)를 만날때까지의 모든 문자를 ovector 인수에 저장하고
</[^>]+ : 태그가 닫힐때까지 처리

^[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개존재

^.{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가 한개 혹은 그 이상개 존재한다. 

(https?://)?(www.)?[a-zA-Z0-9-]+(.[a-z]{2,})+(/[^\s]*)?

(https?://)?:  (http 이후 s 가 올수도 있으며 이후 ://가 나오는 문장) 이 있을 수 있고  
(www.)?: ( www 및 임의의 한 문자) 가 있을 수 있고
 [a-zA-Z0-9-]+ : - 및 영문자, 숫자가 한 자 이상 나오고 
 (.[a-z]{2,})+ : . 이후에 영문자 2자 이상 이 나오고 /나 공백이 아닌 문자가 나오는 것 있을 수도 있다.
 (/[^\s]*)?: 공백이 나올때까지 찾는다.

url 분리하기

url을 분리하여 프로토콜 및 호스트를 찾는다.

$str = "<a href='http://www.onstory.fun/index.html'>my home</a>";
$pattern = "|(https?://)([^/\s]+)|i";
preg_match($pattern, $str, $matches);
[
  [0] => http://www.onstory.fun 
  [1] => http:// <-- 프로토콜
  [2] => www.onstory.fun <!-- host
]

검색엔진의 특정 검색어를 찾아내기

$str = "http://search.naver.com/search.naver?where=nexearch&query=홈페이지제작&hw=1";
$pattern = "|/?query=(.*)&|i"; // ?는 특수문자이므로 앞에 이스케이프 시퀀스(/)를 붙인다.
preg_match($pattern, $str, $matches);
[
  [0] => query=홈페이지제작&
  [1] => 홈페이지제작
]

태그안의 text 가져오기

$str = "<a href='#'>my home</a>";
$pattern = '|<[^>]+>(.*)</[^>]+>|i';
preg_match($pattern, $str, $matches);

// 문장중 여러 개가 존재할 경우 U 패턴모디파이어와 preg_match_all 을 각각 이용한다.
$str = "<a href='#'>my home</a> <a href='#'>my home2</a>";
$pattern = '|<[^>]+>(.*)</[^>]+>|iU';
preg_match_all($pattern, $str, $matches);

숫자만 찾기

문자에 포함된 숫자만을 찾는 간단한 예제입니다.

$str = '나는 3학년 5반이고 나이는 17세입니다.';
$pattern = '/\d+/'; //숫자로 시작하고 취소 1회이상 매치
$counts = preg_match_all($pattern, $str, $matches);
  • 결과
$counts: 3
$matches
Array
(
  [0] => Array
   (
    [0] => 3
    [1] => 5
    [2] => 17
   )
)

이메일 찾기

$str = '문의는 [email protected] 또는 [email protected]으로 연락 주시기 바랍니다.';
$pattern = '/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}/';
preg_match_all($pattern, $str, $matches);
  • 결과
Array
(
  [0] => Array
   (
    [0] => [email protected]
    [1] => [email protected]
   )
)

핸드폰번호 검사

$str = '문의는 010-1111-2222 또는 02-333-4444 연락 주세요.';
$pattern = '/\d{2,3}-\d{3,4}-\d{4}/';
preg_match_all($pattern, $str, $matches);
  • 결과
Array
(
  [0] => Array
  (
    [0] => 010-1111-2222
    [1] => 02-333-4444
  )
)

URL 검사

본문중에서 url만 추축하는 경우로 다양한 경우의 수를 고려하여 한번 제작해 보았습니다.

$str = '더 많은 정보는 https://www.onstory.fun에서 확인하세요.';
$pattern = '|(https?://)?(www.)?([\w-]+)(\.[\w]+){1,}|'; //only schema and domain 분리
$pattern = '|(https?://)?(www.)?([\w-]+)(\.[\w]+){1,}([/]?([-.\w]*))*|';   // 최종 실행파일까지 분리
$pattern = '|(https?://)?(www.)?([\w-]+)(\.[\w]+){1,}([/]?([-.\w]*))*([?]?[\=\-.\&\w])*|';  // 파라미터 까지분리
preg_match_all($pattern, $str, $matches);
// 위와 유사한 다른 패턴
$pattern = '|(https?://)?([-\w]+\\.[-\w.]+)+\w(:\d+)?(/([-\w/_\.]*(\?\S+)?)?)*|'; // 아래 3가지 패턴은 모두 유사한 패턴을 가진다.
$pattern = '|(https?://)?(www\.)?[a-zA-Z0-9-]+(\.[a-z]{2,})+(/[^\s]*)?|';
$pattern = '|(?:https?://)?(?:www.)?[a-zA-Z0-9-]+(?:.[a-z]{2,})+(?:/[^\s]*)?|'; // 서브패튼을 출력안함
  • 결과
Array
(
  [0] => Array
  (
    [0] => https://www.onstory.fun
  )
)

a 태그에서 href 추출

$str = '더 많은 정보는 <a href="https://www.onstory.fun">온스토리</a>에서 확인하세요.';
$pattern ='/href=(\'|\")?([^<>\s\'\"]*)(\'|\"|\s|)/i';
preg_match_all($pattern, $str, $matches);
  • 결과
Array
(
  [0] => Array
    (
      [0] => href="https://www.onstory.fun"
    )

  [1] => Array
    (
      [0] => "
    )

  [2] => Array
    (
      [0] => https://www.onstory.fun
    )

  [3] => Array
    (
      [0] => "
    )
)

img 태그 추출 src 추출

$str = '아름다운 이미지 <img src="https://www.onstory.fun/image.png">를 보셔요';
$pattern ='/<img[^>]*src=["\']?([^>"\']+)["\']?[^>]*>/i';
preg_match_all($pattern, $str, $matches);
  • 결과
Array
(
  [0] => Array
    (
      [0] => <img src="https://www.onstory.fun/image.png">
    )

  [1] => Array
    (
      [0] => https://www.onstory.fun/image.png
    )
)

태그 및 태그내용 추출

$str = '<b>bold text</b><a href=onstory.html>click me</a>';
$pattern = '/(<([\w]+)[^>]*>)(.*)(<\/\\2>)/';
preg_match_all($pattern, $str, $matches);
  • 결과
Array
(
  [0] => Array
    (
      [0] => <b>bold text</b>
      [1] => <a href=onstory.html>click me</a>
    )
  [1] => Array
    (
      [0] => <b>
      [1] => <a href=onstory.html>
    )
  [2] => Array
    (
      [0] => b
      [1] => a
    )
  [3] => Array
    (
      [0] => bold text
      [1] => click me
    )
  [4] => Array
    (
      [0] => </b>
      [1] => </a>
    )
)

태그내용 추출

$str = "<b>bold text</b><a href=onstory.html>click me</a>";
$pattern = '|<[^>]+>(.*)<[^>]+>|U';
preg_match_all($pattern, $str, $matches);
  • 결과
Array
(
  [0] => Array
    (
      [0] => <b>bold text</b>
      [1] => <a href=onstory.html>click me</a>
    )
  [1] => Array
    (
      [0] => bold text
      [1] => click me
    )
)

날짜 추출

$str = "오늘은 20230517일 입니다.";
$pattern = '/([0-9]{4})([0-9]{2})([0-9]{2})/';
preg_match_all($pattern, $str, $matches);
  • 결과
Array
(
  [0] => Array
    (
      [0] => 20230517
    )

  [1] => Array
    (
      [0] => 2023
    )

  [2] => Array
    (
      [0] => 05
    )

  [3] => Array
    (
      [0] => 17
    )
)

preg_replace

preg_replace 는 패턴으로 찾은 문자를 치환할때 자주 사용한다.

ereg_replace()

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

Replacement 표기법

replacement를 표기할때는 아래처럼 3가지 모두 가능하다.
${num} $num \num

$str = 'April 15, 2023';
$pattern = '/(\w+) (\d+), (\d+)/i';
$replacement = '${1}, \\2, $3'; 
echo preg_replace($pattern, $replacement, $str);// April, 15, 2023

영문자, 숫자, _, . 이외 모든 문자 제거

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

특정 태그 제거 정규식

tag 만제거
$str = preg_replace("/<tag[^>]*>/ims", '', $str);
$str = preg_replace("/<\/tag>/ims", '', $str);
$str = '나는 <a href="https://onstory.fun">프로그래머</a> 입니다.';
$str = preg_replace("/<a[^>]*>/i", '', $str);
$str = preg_replace("/<\/a>/i", '', $str); // 나는 프로그래머 입니다.
tag 및 tag 안의 내용 제거
$str = preg_replace("/<tag(.*?)<\/tag>/ims", '', $str);
$str = '나는 <a href="https://onstory.fun">프로그래머</a> 입니다.';
$str = preg_replace("/<a(.*?)<\/a>/is", '', $str); // 나는  입니다.
tag 중 닫힘없는 테그 제거
$str = preg_replace("|<tag[^>]*>(.*?)|ims", "", $str);
$str = '이름 : <input type="text" name="adf">';
$str = preg_replace("|<input[^>]*>(.*?)|ims", "", $str); // 이름 :
attribute 제거
$str = preg_replace("|attribute=([^\s^>]+)|ims", '', $str);
$str = '나는 <div onclick="javascript:abc()" class="none"> 프로그래머</div> 입니다.';
$str = preg_replace("|onclick=([^\s^>]+)|ims", '', $str); // 나는 <div  class="none"> 프로그래머</div> 입니다.
특정 attribute 를 가진 태그 및 내용제거

$str = preg_replace('/(<div class="my-class"\>.*?<\/div>)/ims', '', $str); // 특정클래스(my-class) 가 있으면 안의 내용 까지 제거
$str = preg_replace('~<a([^>]*)(class\\s*=\\s*["\']my-class["\'])([^>]*)>(.*?)</a>~i', '', $str); // 특정클래스(my-class) 가 있으면 안의 내용 까지 제거


$str = preg_replace('!<center>-(.*?)\/center>!is', "", $str); // 특정 태그 제거 

$str = preg_replace('/\[[^]]*\]/','',$str); //[] 삭제및 안의 내용 삭제
모든 개행문자 제거
$str = preg_replace('/\v+/', ' ', $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";
html tag 제거 정규식
$content = preg_replace("(\<(/?[^\>]+)\>)", "", $content);

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

preg_match('/<div id="my2">(.*?)<\/div>/is', $contents, $html);
preg_match("/\<span id=\"moonseller\"\>[^>]\<\/span\>/", $contents, $html);

Table of contents 목차

평점을 남겨주세요
평점 : 5.0
총 투표수 : 1

질문 및 답글