문자열의 시작 부분에서 문자열을 제거


146

다음과 같은 문자열이 있습니다.

$str = "bla_string_bla_bla_bla";

첫 번째를 어떻게 제거 할 수 있습니까 bla_? 그러나 문자열의 시작 부분에서 발견되는 경우에만?

를 사용 str_replace()하면의 모든 항목 이 제거 됩니다bla_ .


1
이 독립형 라이브러리에s($str)->replacePrefix('_bla') 있는 것처럼 도움 이 될 수 있습니다 .
caw

답변:


339

정규식이없는 일반 형식 :

$prefix = 'bla_';
$str = 'bla_string_bla_bla_bla';

if (substr($str, 0, strlen($prefix)) == $prefix) {
    $str = substr($str, strlen($prefix));
} 

소요 : 0.0369ms (0.000,036,954 초)

그리고

$prefix = 'bla_';
$str = 'bla_string_bla_bla_bla';
$str = preg_replace('/^' . preg_quote($prefix, '/') . '/', '', $str);

소요 : 0.1749 MS (0.000,174,999 초) (컴파일) 1 차 실행하고, 0.0510 MS (0.000,051,021 초) 후를.

분명히 내 서버에 프로파일 링되었습니다.


8
나는 삼항 연산자가 그렇게 심하게 학대받는 것을 본 적이 없다. 단순한 if(condition) { statement }것이 훨씬 명확했을 것이다.
Tatu Ulmanen

4
@ 살라 테 : 나는 비판을 받아들입니다. 가장 빠른 것이 무엇인지 보는 것은 호기심이었습니다.
Fabio Mora

51
@ 살라 테, 나는 그것을 얻지 못한다. 관용적 솔루션과 정규식 기반 솔루션이 모두 제안되었습니다. 효율성 측면에서 두 가지를 비교하면 최상의 효율성을 다시 찾는 데 도움이됩니다. 그게 왜 악한가요?
cbrandolino

5
@cbrandolino, 아무도 하다고 말했다 . 방금 질문과 관련이 없다고 생각했습니다. "여기에 두 가지 해결책이 있으며 여기에 더 많은 투표를위한 새끼 고양이 그림이 있습니다"와 같습니다.
salathe

5
if (substr($str, 0, strlen($prefix)) == $prefix) 변경 가능 if (0 === strpos($str, $prefix))동일한 판독성 : 유지하면서 불필요한 메모리 할당을 피하기 위해
xDaizu

63

캐럿 기호 ( ^) 와 함께 정규 표현식을 사용 하여 일치를 문자열의 시작 부분에 고정 시킬 수 있습니다 .

$str = preg_replace('/^bla_/', '', $str);

substr()버전 보다 빨리 작동하는지 궁금합니다 ... 그렇다고 생각하고 적절한 답변으로 표시해야합니다.
Flash Thunder

preg_quote'd
vp_arth

나는 이것이 프로그래머의 눈에는 훨씬 덜 고통스럽고 직관적이라고 생각합니다. 제안 된 다른 솔루션 (실제로 의심되는 솔루션)의 성능이 떨어지더라도 여전히 이것을 선호합니다.
Fr0zenFyr

multibyte악몽은 다른 솔루션의 또 다른 문제이지만 파일 인코딩이 올바른 경우에는 잘 작동합니다. 어쨌든, 그것은이 질문의 범위에 있어서는 안되므로 신경 쓰지 않을 것입니다.
Fr0zenFyr

이것은 주제 문자열 배열로 작업 할 때 추가 이점이 있음을 언급했습니다. substrstrpos배열을 받아 들일 수 없습니다. 어레이를 다루면 성능이 크게 향상됩니다. 건배!
Fr0zenFyr

20
function remove_prefix($text, $prefix) {
    if(0 === strpos($text, $prefix))
        $text = substr($text, strlen($prefix)).'';
    return $text;
}

10
.''필요하지 않습니다.
NateS

1
모든 사람이 여기에서 미세 최적화하는 것처럼 보이므로 가치가있는 것으로, 이것은 내 계산에 의해 일관되게 가장 빠릅니다. .17 초에 백만 회 반복이 발생했지만 (substr($str, 0, strlen($prefix)) == $prefix)허용 된 답변의 .37과 비슷했습니다.
billynoah 5

5

여기.

$array = explode("_", $string);
if($array[0] == "bla") array_shift($array);
$string = implode("_", $array);

2
측정 0.0000459153 초 :)
Fabio Mora

속도는 좋지만으로 끝나는 바늘에 따라 하드 코딩됩니다 _. 일반 버전이 있습니까?
toddmo 2016 년

0

substr_replace는 문자열의 일부로 바꾸기를 제한 할 수있는 곳에서 원하는 것을 수행한다고 생각합니다. http://nl3.php.net/manual/en/function.substr-replace.php (이것은 오직 문자열의 시작)

str_replace의 count 매개 변수 ( http://nl3.php.net/manual/en/function.str-replace.php )를 사용할 수 있습니다. 이렇게하면 왼쪽부터 시작하여 교체 횟수를 제한 할 수 있습니다. 처음에 강요하지 않습니다.


1
substr_replace제거하려는 접두사인지 또는 다른 문자인지에 관계없이 주어진 범위의 문자를 대체합니다. OP는 bla_"문자열의 시작 부분에있는 경우에만" 를 제거하려고 합니다.
Olivier 'Ölbaum'Scherler

0

속도는 좋지만 _로 끝나는 바늘에 따라 하드 코딩됩니다. 일반 버전이 있습니까? – toddmo 6 월 29 일 23:26

일반적인 버전 :

$parts = explode($start, $full, 2);
if ($parts[0] === '') {
    $end = $parts[1];
} else {
    $fail = true;
}

일부 벤치 마크 :

<?php

$iters = 100000;
$start = "/aaaaaaa/bbbbbbbbbb";
$full = "/aaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee";
$end = '';

$fail = false;

$t0 = microtime(true);
for ($i = 0; $i < $iters; $i++) {
    if (strpos($full, $start) === 0) {
        $end = substr($full, strlen($start));
    } else {
        $fail = true;
    }
}
$t = microtime(true) - $t0;
printf("%16s : %f s\n", "strpos+strlen", $t);

$t0 = microtime(true);
for ($i = 0; $i < $iters; $i++) {
    $parts = explode($start, $full, 2);
    if ($parts[0] === '') {
        $end = $parts[1];
    } else {
        $fail = true;
    }
}
$t = microtime(true) - $t0;
printf("%16s : %f s\n", "explode", $t);

내 아주 오래된 집 PC에서 :

$ php bench.php

출력 :

   strpos+strlen : 0.158388 s
         explode : 0.126772 s

0

더 빠른 접근 방식은 다음과 같습니다.

// strpos is faster than an unnecessary substr() and is built just for that 
if (strpos($str, $prefix) === 0) $str = substr($str, strlen($prefix));

0

이렇게하면 시작, 중간 또는 종료와 같은 첫 번째 일치 항목이 제거됩니다.

$str = substr($str, 0, strpos($str, $prefix)).substr($str, strpos($str, $prefix)+strlen($prefix));


-6

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

지금 당신이 원하는 것을합니다.

$str = "bla_string_bla_bla_bla";
str_replace("bla_","",$str,1);

7
str_replace()함수의 $count매개 변수는 교체 횟수를 제한하지 않고 발견 된 교체 횟수를 포함하기 위해 참조로 전달되는 변수 여야합니다.
AL the X

-6

www를 제거하십시오. 문자열의 처음부터 가장 쉬운 방법입니다 (ltrim)

$a="www.google.com";
echo ltrim($a, "www.");

8
두 번째 매개 변수는 문자열의 왼쪽에서 제거 할 문자 맵입니다 ( php.net/manual/function.ltrim.php ). 따라서 ltrim($a, "w.");도메인이 "w"로 시작하지 않는 경우에만 작업을 수행합니다. ltrim ('m.google.com', ".omg")결과 le.com.
fragmentedreality

그러나 그것은 질문의 특정 문제를 해결합니다. +1
chulian

1
그것은 문제의 문제가 아니라 그의 답변에 대한 특정한 문제를 실제로 해결합니다. 와 함께가더라도 ltrim잘못 사용됩니다. 두 번째 매개 변수는 트리밍해야하는 문자 목록입니다. 그러므로 하나면 "w."충분하다.
fragmentedreality

IMHO, 그것은 질문과 문제에 맞다고 생각합니다.
abkrim

2
몇 가지 테스트로 테스트 후 내 의견을 변경 .... 어떤 상황에서 질문에 대한 작동하지 않습니다
abkrim
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.