[php] 정규식 (Regular Expression)
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 목차
- Php 정규식 패턴(Regular Expression)
- 패턴 변경자(Pattern Modifiers)
- 서브패턴 ()
- Repetition(반복)
- Assertions (어설션)
- 정규표현식 관련 PHP 함수
- 예제