웹 프로그래밍

[PHP] 4장 문자열 연산과 정규 표현식(1)

토픽 웹 프로그래밍 > PHP

문자열 다루기

앞 뒤 공백 제거하기 : trim()

string trim ( string $str [, string $charlist = " \t\n\r\0\x0B" ] )

<?php
$name = trim($_POST['name']);
?>
  • trim() : 문자열의 앞 뒤 공백을 모두 제거
  • ltrim() : 문자열의 왼쪽 공백을 제거
  • rtrim(), chop() : 문자열의 오른쪽 공백을 제거

이 함수들은 공백을 제거한 새로운 문자열을 리턴하는 형식이기 때문에 새로 사용할 값(또는 기존값)에 다시 대입해 주어야 사용할 수 있다.

줄바꿈 문자(\n, \r), 세로 탭, 가로 탭(\t, \x0B), 문자열의 끝을 나타내는 \0, 스페이스 등을 제거한다.
추가로 지우고 싶은 문자가 있으면 두 번째 파라미터로 입력해 줄 수도 있다. 

 

문자열 정돈 : nl2br()

string nl2br ( string $string [, bool $is_xhtml=true ] )

<?php
echo nl2br($_POST('content'));
?>

HTML은 줄바꿈 문자(\n)를 인식하지 못한다. 따라서 이 문자를 XHTML에서의 줄바꾸기 태그인 <br />로 바꾸어 주어야 하는데, 함수 nl2br이 이 역할을 수행한다.

게시판 같은 곳에서 본문 내용을 입력받고 nl2br로 출력을 해 주면 줄바꿈을 모두 표현해 줄 수 있다.

두 번째 인자는 XHTML 호환 줄바꿈 여부이다. 기본값은 true이고 이 경우 <br />가 삽입된다. false값을 주면 <br>로 삽입된다. 크게 신경쓰지 않아도 된다. 

 

문자열 출력 : printf()

PHP에서도 C언어에서 자주 사용했던 printf() 함수를 지원한다. 사용법은 C언어와 거의 동일하기 때문에 설명은 생략한다.

PHP는 추가적으로 sprintf(), vprintf(), vsprintf() 등을 지원한다.
기능적으로 sprintf()printf()와 동일하고 vsprintf()vprintf()와 동일한데, sprintf()vsprintf()는 브라우저에 바로 출력하는 것이 아닌 문자열을 리턴한다는 차이점이 있다.

vprintf()는 파라미터를 두 개만 받도록 되어있는데 printf()의 두 번째 이후의 인자들을, 배열이라는 한 가지 인자로 받는 다는 점에서 차이가 있다. 아래 예제를 보면 이해가 될 것이다.

int vprintf ( string $format , array $args )

<?php
vprintf("d-d-d", explode('-', '1988-8-1')); // 1988-08-01
// explode('-', '1988-8-1')은 {'1988', '8', '1'}과 동일하다.
?>
"d-d-d"에서 d와 같은 부분을 변환 명세라고 한다. 변환 명세의 형식은 아래와 같다.
%['padding_character][-][width][.precision]type 
printf() 함수를 변환 형 코드와 함께 사용할 경우 인자 번호를 사용할 수 있다.
printf("a: %2\$d, b: %1\$d", $b, $a);
2\$의 의미가 두 번째 인자를 사용하겠다는 의미가 된다.

 

대소문자 바꾸기 : strtoupper()

함수 설명 사용 예 리턴값
기본값 $www World wide web
strtoupper() 모두 대문자 strtoupper($www) WORLD WIDE WEB
strtolower() 모두 소문자 strtolower($www) world wide web
ucfirst() 문장의 처음만 대문자 ucfirst($www) World wide web
ucwords() 단어의 처음만 대문자 ucwords($www) World Wide Web

 

이스케이프(데이터베이스) : addslashes()

데이터베이스에 문장을 저장하기 위해서도 문자열을 다듬어야 한다. 일부 특수문자들은 데이터베이스에 입력할 때 문제를 일으키기도 한다. 따옴표('), 큰따옴표("), 역슬래시(\), NULL 등의 문자를 "자료"가 아닌 "제어"용으로 잘못 간주하기 때문이다.

이들 문자에 역슬래시(\)를 앞에 추가하여 이스케이프시켜 MySQL과 같은 데이터베이스가 제어 문자가 아니라는 것을 인식할 수 있도록 해야 한다. 이와 관련된 PHP 함수가 바로 addslashes()이고 반대 기능을 하는 함수가 stripslashes()이다.

string addslashes ( string $str )
string stripslashes ( string $str )

<?php
$content = addslashes(trim($_POST['content']));
?>
만약 함수 addslashes()를 사용하지 않았는데도 자동으로 역슬래시(\)가 추가되었다면 PHP의 설정을 확인해 보아야 한다. magic_quotes_gpc에 의해 GET, POST, COOKIE를 통해 들어온 변수에 자동으로 \를 추가 혹은 제거하도록 되어 있을 수 있다. 새 버전에서는 기본적으로 활성화 되어 있다. 이는 함수 get_magic_quotes_gpc()를 통해 확인할 수 있다. 아래 예제를 확인하자.
// DB에 저장할때 역슬래시 추가
if(get_magic_quotes_gpc()) {
    $content = $_POST['content'];
}
else {
    $content = addslashes($_POST['content']);
}
/*  get_magic_quotes_gpc()기능이 켜져있다면
    POST로 전달받은 값에 자동으로 역슬래시가 추가되어 있을 것이다.
    그러면 그 문자열을 그대로 사용하면 된다.
    반면, 기능이 꺼져있는경우 사용자가 직접
    함수 addslashes()를 이용하여 역슬래시를 추가해 주어야한다.
*/

// DB에서 값을 가져올 때(참고)
// $row['content']는 데이터베이스에서 가져온 content값이라고 생각하자.
$content = nl2br(htmlspecialchars($row['content']));
/*  만약 DB에서 사용자가 입력했던 값을 그대로 가져오고 싶다면
    위와 같이 사용한다.
    함수 nl2br()은 \n에 <br />을 추가하여 HTML에서 줄바꿈을 표현하고
    함수 htmlspecialchars()는 HTML에서 특별한 기능을 하는 제어문자
    예를들어 <, >, & 등이 그대로 표현되도록 한다.(태그실행을 막는다.)
*/

위와 같은 예제는 게시판과 같이 사용자 입력을 받는 곳에서 유용하게 사용할 수 있다. 첫 번째 예제는 글쓰기 기능, 두 번째 예제는 게시글 보기와 같이 사용하면 된다. 만약 두 번째 예제에서 $content를 textarea 태그 안에서 보여주고 싶다면(게시글 수정과 같은 기능에서 활용된다.) nl2br함수만 제외해주면 된다.

 

문자열 합치고 나누기

explode(), implode()

array explode ( string $delimiter , string $string [, int $limit ] )

string 문자열을 delimiter에 대하여 분리하고 그 결과를 배열로 반환한다. 이 때 limit을 통해 분리된 개수를 제한할 수도 있다.

// Example 1
$pizza  = "piece1 piece2 piece3 piece4 piece5 piece6";
$pieces = explode(" ", $pizza);
echo $pieces[0]; // piece1
echo $pieces[1]; // piece2

// Example 2
$data = "foo:*:1023:1000::/home/foo:/bin/sh";
list($user, $pass, $uid, $gid, $gecos, $home, $shell) = explode(":", $data);
echo $user; // foo
echo $pass; // *
//여기서 $gecos는 :: 사이이므로 값을 갖지 못한다.
implode : explode()와 반대 기능을 수행한다.
join : implode의 별칭
string implode ( string $glue , array $pieces )
string implode ( array $pieces )
delimiter에 2자 이상의 문자열이 올 경우 각 글자 하나하나에 대해서 개별적으로 다 쪼개어지는 것이지 delimiter 문자열 전체를 기준으로 쪼개지는 것이 아니다. 이는 strtok()에서도 마찬가지이므로 반드시 명심하자.

 

strtok()

string strtok ( string $str , string $token )   // 첫 번째 사용시
string strtok ( string $token )                 // 두 번째 이후 사용시

<?php
$string = "This is\tan example\nstring";
/* Use tab and newline as tokenizing characters as well  */
$tok = strtok($string, " \n\t");

while ($tok !== false) {
    echo "Word=$tok<br />";
    $tok = strtok(" \n\t");
}
/* 출력 결과
Word=This
Word=is
Word=an
Word=example
Word=string
*/
?>

함수 strtok()는 token으로 문자열을 자르고 그 결과를 하나씩 리턴한다. 즉 처음에는 인자를 str, token 두 개 전달하여 첫 결과값을 리턴하고 그 이후에는 token 하나만 계속 인자로 전달해 하나씩 결과값을 얻어낸다. 마지막에는 false를 리턴한다.

 

substr()

string substr ( string $string , int $start [, int $length ] )

<?php
$rest = substr("abcdef", -1);    // returns "f"
$rest = substr("abcdef", -2);    // returns "ef"
$rest = substr("abcdef", -3, 1); // returns "d"
?>
<?php
$rest = substr("abcdef", 0, -1);  // returns "abcde"
$rest = substr("abcdef", 2, -1);  // returns "cde"
$rest = substr("abcdef", 4, -4);  // returns false
$rest = substr("abcdef", -3, -1); // returns "de"
?>

함수 substr()은 고정된 형식의 문자열을 부분적으로 잘라내고 싶을 때 유용하다. string을 start부터 시작해 length(없으면 끝까지)만큼 잘라낸 값을 리턴하는 함수이다. start에 음수를 입력하면 뒤에서부터 start의 크기만큼의 문자열을 리턴하고 length에 음수를 입력하면 뒤에서부터 length의 크기만큼까지의 문자열을 리턴한다.
말로 설명하는 것이 더 헷갈린다. 위의 예제를 통해서 이해하자.

 

문자열 비교 및 탐색

문자열의 순서 : strcmp()

int strcmp(string str1, string str2)

str1과 str2을 사전순으로 비교하여 str1이 앞서면 음수를, str1이 뒷서면 양수를, 서로 같으면 0을 리턴한다.
이 때, 대소문자를 구별한다. 아래와 같은 비슷한 함수들이 있다.

  • strcasecmp() : strcmp()와 동일하나 대소문자를 구별하지 않는다.
  • strnatcmp() : 문자열을 좀 더 자연스러운 기준 또는 사람이 사용할 법한 기준을 통해 비교한다.
  • strnatcasecmp() : strnatcmp()와 동일하나 대소문자를 구별하지 않는다.
strnatcmp()의 예를 들면 "2"는 "12"보다 사전상 뒷서지만, 사람이 보기에는 "2"보다 "12"가 작으므로 "12'가 뒷선다고 할 수도 있다. strnatcmp() 함수에 대해서 자세히 알고 싶으면 http://www.naturalordersort.org 에서 자세히 확인할 수 있다.

 

문자열의 길이 : strlen()

echo strlen("hello"); // 5

많은 프로그래밍 언어에서 공통적으로 그리고 매우 자주사용하는 함수이기 때문에 많은 설명이 필요하지 않을 것이다. 인자로 받은 문자열의 길이를 리턴한다.

 

문자열 찾아내기 : strstr()

string strstr ( string $haystack , mixed $needle [, bool $before_needle ] )

<?php
$email  = 'name@example.com';
$domain = strstr($email, '@');
echo $domain; // @example.com 출력.

$user = strstr($email, '@', true); // PHP 5.3.0부터
echo $user; // name 출력
?>

함수 strstr()은 haystack에서 needle이 있는지 찾아 needle부터 그 이후의 문자열을 반환한다. 만약 세 번째 인자로 true를 주면 needle 전까지의 문자열을 반환한다. 이 함수는 대소문자를 구별한다.

stristr() : 대소문자를 가리지 않는다.
strchr() : strstr()의 별칭이다.
strrchr() : 세 번째 인자가 없다. strstr()과 거의 동일한데 needle이 여러 번 나타날 때 마지막 위치기준이라는 점에서 차이가 있다.(아직까지는 needle에 하나의 문자만 사용할 수 있다.)

 

문자열 위치 찾아내기 : strpos()

int strpos ( string $haystack , mixed $needle [, int $offset ] )

<?php
$test = "Hello world";
echo strpos($test, 'o'); // 4
echo strpos($test, 'o', 5) // 7
?>

함수 strstr()과 조금 비슷하다. strpo() 이 함수는 haystack에서 needle이 있는 위치를 숫자(인덱스)로 알려준다. 인덱스는 0부터 시작하며, 함수 strstr()보다 더 빠르다. 탐색에 성공하지 못한다면 false를 리턴한다.

추가인자 offset검색을 시작할 위치(인덱스)를 지정하고 싶을 때 사용한다.

strrpos() : needle이 여러 번 나타날 때 마지막에 나타난 위치를 리턴한다.(그 외 동일)

문자열 대체하기 : str_replace(), substr_replace()

mixed str_replace(mixed $search, mixed $replace, mixed $subject[, int &$count])

subject에서 search를 찾아 replace로 바꾼다. count는 몇 번 바꿨는지를 기록한다.(count: PHP 5이상)

모든 파라미터를 배열로 전달할 수도 있다.

 

mixed substr_replace(mixed $string, mixed $replacement, mixed $start[, mixed $length])

만약 어떤 문자열을 위치를 기준으로 바꾸고 싶을 때 substr_replace()를 사용한다. 사용법은 함수 substr()과 유사하다. string에서 start부터 length까지의 문자열을 replacement로 대체한다. 만약 length를 지정하지 않으면 끝까지 바꾼다.

댓글

댓글 본문