코딩짜는 일상

[PHP] 문자열에 특수문자 또는 일부 문자열이 포함되어 있는지 확인 - strpos(), preg_match() 본문

IT/PHP

[PHP] 문자열에 특수문자 또는 일부 문자열이 포함되어 있는지 확인 - strpos(), preg_match()

Remily 2023. 9. 13. 14:38
반응형

함께 읽어보면 좋은 글

https://weavingcoding.tistory.com/32

 

[PHP] strpos() 사용시 주의사항! - PHP 버전 7.3 미만인 경우

서론 사용자가 선택한 값에 부분 문자열이 포함되어 있는가 아닌가의 여부로 서버 종류를 판별하고 각자에 맞는 저장 쿼리를 실행하는 코드를 작성하였습니다. // $type = 'user_board' - 사용자 게시

weavingcoding.tistory.com

 

 

 


서론

저희 회사엔 각 시도별로 다양한 이벤트를 진행합니다.

그리고 이 쿠폰들 사용내역을 매주 각 지자체에 보고해야 합니다.

쿠폰이 30개쯤 되니까 일일이 DB조회해주기 번거로워서 자동화를 했습니다.



  1. 조회하고자 하는 기간 내에 선택한 시도에서 시행되는 쿠폰들의 목록을 만들고
  2. 같은 종류(①또는②)에 같은 이벤트인, 시군구만 다른 쿠폰끼리 묶어준 다음
  3. foreach로 쿠폰마다 사용내역을 조회해 엑셀로 export

이렇게 시스템을 짰는데 2번 단계에서 쿠폰들이 그룹화하지 못하는 문제가 발생했습니다.

원인은 쿠폰명에 쿠폰종류를 구분하기위해 들어간 ①과 ② 같은 특수문자 때문이었습니다.





strpos()

구글에서 PHP 같은 문자열같은 키워드로 검색하면 가장먼저 나오는 예제가

strpos()에 대한 예제입니다.



사용방법은 다음과 같습니다.

 

strpos($원본문자열, $비교문자열, $offset)

 

     
변수명           필수여부    설명                                                                                                                                                    
$원본문자열 필수 비교할 원본 문자열입니다. $비교문자열을 포함하는지 확인합니다.
$비교문자열 필수 비교 기준이 되는 일부 문자열입니다. $원본문자열에 포함되는지 확인합니다.
$offset   비교를 시작할 위치를 지정합니다. 만약 음수라면 $원본문자열의 끝에서 n번째부터 비교를 시작합니다.



하지만 strpos('① [지역명] OO 이벤트 쿠폰', '① [')을 실행했을 때 false를 응답받았습니다.

 

특수문자 ①의 포함여부를 판단하지 못합니다.





preg_match()

이 함수는 정규식을 사용하여 문자열 포함여부를 판단합니다.

그중 /u를 이용하면 유니코드로 문자열을 변환해 비교할 수 있게 되죠.

 

유니코드로 비교하면 특수문자로 비교할 수 있게 됩니다!



사용법은 다음과 같습니다.

 

preg_match($패턴(비교문자열), $원본문자열, $일치결과저장변수, $플래그, $offset)

 

     
변수명                            필수여부    설명

$패턴(비교문자열) 필수 비교 기준이 되는 일부 문자열을 정규식을 이용해 패턴화 합니다. $원본문자열에 포함되는지 확인합니다.
$원본문자열 필수 비교할 원본 문자열입니다. $비교문자열을 포함하는지 확인합니다.
$일치결과저장변수   일치한 결과를 배열로 저장합니다.
$플래그   PREG_OFFSET_CAPTUREPREG_UNMATCHED_AS_NULL 두 가지 플래그가 있습니다.
$offset   비교를 시작할 위치를 지정합니다. 만약 음수라면 $원본문자열의 끝에서 n번째부터 비교를 시작합니다.




이제 위에서 실패했던 쿠폰명 비교를 해봅시다!

 

정규식은... Chat GPT의 도움을 받았습니다. ;ㅅ;



preg_match('/① \[(?=[^\]]*] OO 이벤트 쿠폰)/u', '① [성남] OO 이벤트 쿠폰')

 

 

 

이처럼 정규식을 이용하면 특수문자 뿐만 아니라 양끝 문자열을 동시에 비교할 수 있게 됩니다.

 

혹시나 해서 strpos()에 동일한 정규식을 넣어도 동작하지 않네요...ㅠ





결론

일반적으로 부분 문자열을 포함하는지 여부를 strpos()로 확인합니다.

하지만 특수문자가 부분 문자열에 포함된 경우 이를 유니코드로 변환해 비교해야하므로,

preg_match()를 써야 합니다.




물론 정규식은 가독성도 낮고

특수문자를 비교할 경우도 적을테지만...

 

그리고 차라리 특수문자 입력을 막는게 더 나을 수 있지만...!



저처럼 레거시 코드를 최대한 이용해야하는 경우라면

유용한 글이 되셨으면 좋겠습니다. 0ㅅ<

반응형