본문 바로가기
PHP/생활코딩

5/27 생활코딩

by SKim입니다 2020. 5. 27.

* 오늘의 진도

 PHP

  정규표현식 - 검색, 치환

19. 정규표현식 - 검색

정규표현식에서 단어의 경계를 의미하는 word boundary 패턴을 이용해서 텍스트를 검사하는 예제를 살펴보자.

 

1) web이라는 단어를 검색하고 싶은데,

이 단어가 (2)의 website처럼) 다른 단어와 결합되어 있지 않은

web이라는 단어만 검색하고 싶다면

 

\b는 단어의 경계를 나타내는 것이기 때문에

\bweb\b를 사용하면 된다.

→ 결과: 1

 

2) 결과: 0

 

preg_match의 세번째 인자로 $match가 들어갔다.

이 변수의 이름은 꼭 match일 필요는 없고, 위에서 따로 선언할 필요도 없다.

여기에 적어주기만 하면 preg_match 함수가 내부적으로 그런 변수를 생성해서

그 변수에 우리가 검색한 결과를 채워넣어서 리턴하게 된다.

 

이 텍스트에서 도메인을 추출하고 싶다면?

 

 

방법1) escaping

방법2) 구분자를 / 대신 ~로 쓴다.

opentutorials까지 선택하려면 \w(알파벳, 숫자, _)를 사용하고, 1~多를 의미하는 +를 붙인다.

.은 \w에 포함되지 않기 때문에 여기까지만 검색되었다.

 

그냥 .을 써도 에러가 나지는 않지만,

정규표현식에서 .은 문자/공백/특수문자 등 모든 캐릭터를 의미하므로

.을 강제하려면 \.으로 해준다.

 

 

 

만약 우리가 좀더 많은 정보(홈페이지, 이메일, 전화번호)를 추출하고 싶다면

캡쳐링을 사용한다.

 

홈페이지 부분을 ( )로 감싸자 배열의 값이 두개가 됐다.

 

초록색 동그라미 부분을 인식시키기 위해서 \s로 공백을 넣었다.

 

이메일도 ( ) 쳐주면 다음과 같이 된다.

 

즉, ( ) 로 묶인 구간은 독립적으로 추출해낼 수 있다.

= 캡쳐링 = 역참조

 

밑에 echo로 앱을 만들었다.

 

 

 

 

 

preg_match는 검색 결과가 있는지 없는지 여부를 확인하는 것이 기본적인 용법인데,

세 번째 인자로 변수를 부여하게 되면,

그 변수 안에는 ( ) 를 통해서 캡쳐링한 데이터가 들어온다.

그리고 그 데이터를 이용해서 우리가 앱을 만들 수 있다.

 

 

 

url에서 도메인(php.net) 추출하기

 

3행에 @가 앞 뒤로 나왔다 = @가 구분자라는 뜻

 

i는 대소문자를 구분하지 않겠다는 뜻이다.

 

앞에 있는 ^는 경계(행의 시작점)를 의미한다.

즉, http://로 시작하는 것을 검사한다.

 

?:을 붙이게 되면 해당 ( ) 안에 있는 내용은 $matches라는 변수 안에 담기지 않게 된다.

즉, ^을 부분적으로 적용하려고 ( )를 쓴것이지, http://를 변수로 담고 싶은 것은 아니기 때문에

?:를 붙인 것이다.

 

우리가 원하는 것은 위의 것인데, ?:를 빼면 아래와 같이 나온다.

 

?는 앞에 있는 것이 0~1개라는 것을 의미하는 수량자이다.

 

? 뒤쪽을 보자.

^은 [ ] 밖에서 사용될 때는

먼저 나온 ^처럼 행의 시작점을 의미하는 경계 지정자이다.

 

그런데 [ ] 안에서는 not을 의미한다.

즉 /가 아닌 문자 전체들을 의미한다.

 

 

 

위에서 얻은 값을 $host에 넣었다.

뒤에 두 부분(php.net)만 추출해보자.

이번에는 구분자로 /를 사용하였다.

 

[ ] 안에서 ^의 의미는 부정이다.

.이 [ ] 안에 들어가면 임의의 문자를 의미하는 특수한 패턴이 아니라, 그냥 문자 .이 된다.

 

뒤에 +이 붙어있으므로, .이 아닌 문자가 1개 이상이라는 뜻이 된다.

 

\. escaping

 

$는 문자열의 끝을 의미한다.

 

 

 

 

우리가 검사하려고 하는 foobar: 2008이다.

 

최종결과:

 

foobar는 \w+에 의해서 정의된다.

즉, 문자가 하나보다 많다면.

 

name은 배열 중의 key값을 의미한다.

 

:은 :을 의미한다.

 

\d는 숫자를 의미하고, +는 하나 이상을 의미한다.

 

각각의 덩어리는 서브 패턴 ( ) 으로 감싸주었다.

서브 패턴의 초입에 ?P< >는 key값을 의미한다.

 

이런 것을 Back reference라고 한다.

php에서는 입력한 순차적으로 서브 패턴의 값을 알려주는데,

조금더 정확하게 하기 위해서,

인덱스 대신에 연관 배열의 key값을 사용해서 그 패턴의 이름을 지정할 수 있다는 것이 이번 예제의 핵심이다.

 

 

 

19. 정규표현식 - 치환

정규표현식을 사용하는 목표 ① 검색 ② 치환

 

https://www.php.net/manual/en/function.preg-replace.php

 

PHP: preg_replace - Manual

Post slug generator, for creating clean urls from titles. It works with many languages.

pattern으로 들어온 값을 선택하고, 그 값을 replacement로 변경하고, subjrct는 변경하려는 대상이 되는 정보이다.

 

 

 

네모친 \w+는 April이고, 첫 번째 등장하는 1번 하위표현식이다.

${ 번호 }는 하위표현식 상에서 이 번호에 해당되는 하위표현식을 의미한다.

 

 

그래서 ${1}1은 April1이 된다.

 

 

$3은 세 번째 서브패턴의 값(2003)이다.

 

 

 

이전 예제와 비슷하지만,

patterns와 replacements가 배열이라는 것이 차이점이다.

 

quick → slow

brown → black

fox → bear

 

preg_replace의 세번째 인자(subject)는 subject 즉, 우리가 변경하려고 하는 문자열이다.

이것을 초록색 주석으로 변경하는 것이 이 예제의 목표이다.

 

preg_replace의 첫번째 인자($patterns)는 0, 1 두 개의 값을 갖고 있는 배열이다.

 

preg_replace의 두번째 인자($replace)또한 0, 1 두 개의 값을 갖고 있는 배열이다.

 

1) subject에서, $patterns 배열의 0번 값에 해당되는 부분을 찾아서, $replace 배열의 0번 값으로 바꾼다.

 

그럼 이것이 어떻게 변경되는가?

$\1 = 은 패턴이 아니다. 정규표현식의 문법이 아니다.

먼저 $가 들어오고, \1은 첫번째 서브패턴의 값(startDate)이다.

→ 주석과 같은 결과가 나온다.

 

 

 

2) subject에서, $patterns 배열의 1번 값에 해당되는 부분을 찾아서, $replace 배열의 1번 값으로 바꾼다.

 

^은 제일 처음이라는 뜻이다.

즉, {start 부분에서 시작한다는 뜻이다.

 

\s는 공백을 의미한다.

*는 0~多이므로 공백이 있을 수도 있고, 없을 수도 있다는 뜻이다.

 

\w+ = startDate이고, ( )로 묶여있으므로 첫 번째 서브패턴이 된다.

 

그럼 이것이 어떻게 변경되는가?

빨간 색으로 각각의 서브패턴이 몇 번째 서브패턴에 해당하는지 써보았다.

 

$1 = \1

→ 주석과 같은 결과가 나온다.

'PHP > 생활코딩' 카테고리의 다른 글

5/28 생활코딩  (0) 2020.05.28
5/27(2) 생활코딩  (0) 2020.05.27
5/26 생활코딩  (0) 2020.05.27
5/25(3) 생활코딩  (0) 2020.05.25
5/25(2) 생활코딩  (0) 2020.05.25

댓글