Trích xuất chuỗi con PHP. Lấy chuỗi trước '/' đầu tiên hoặc toàn bộ chuỗi


170

Tôi đang cố gắng để trích xuất một chuỗi con. Tôi cần một số trợ giúp để làm điều đó trong PHP.

Dưới đây là một số chuỗi mẫu tôi đang làm việc và kết quả tôi cần:

home/cat1/subcat2 => home

test/cat2 => test

startpage => startpage

Tôi muốn có được chuỗi cho đến đầu tiên /, nhưng nếu không /có, hãy lấy toàn bộ chuỗi.

Tôi đã thử

substr($mystring, 0, strpos($mystring, '/'))

Tôi nghĩ nó nói - lấy vị trí của /và sau đó lấy chuỗi con từ vị trí 0 đến vị trí đó .

Tôi không biết làm thế nào để xử lý trường hợp không có /, mà không làm cho tuyên bố quá lớn.

Có cách nào để xử lý trường hợp đó mà không làm cho câu lệnh PHP quá phức tạp không?


1
Bạn có thể thấy s($str)->beforeFirst('/')hữu ích, như được tìm thấy trong thư viện độc lập này .
caw

Câu trả lời:


261

Sử dụng explode()

$arr = explode("/", $string, 2);
$first = $arr[0];

Trong trường hợp này, tôi đang sử dụng limittham số để explodephp không quét chuỗi nhiều hơn những gì cần thiết.


2
+1 Cảm ơn câu trả lời. Nó hoạt động :) Nhưng một câu hỏi. Tôi chỉ có thể làm điều này -> $arr = explode('/',$mystring,2); echo $arr[0];. Tôi không thể có được chuỗi đầu tiên trong một câu lệnh - echo explode('/',$mystring,2)[0];. Vì explode trả về một mảng, tôi sẽ có thể làm điều đó phải không? Nhưng tôi nhận được một lỗi. Bất kỳ đề xuất?

1
Php không giống như bạn lập chỉ mục vào các giá trị trả về từ các hàm.
gnud

3
Oh. Được chứ. sẽ là tốt đẹp nếu nó có thể.

36
explode() + [0]là một cách viết dài dòngstrtok($string, "/")
mario

5
Nhân tiện, bạn có thể phát nổ ("/", $ string, 2) [0] trong php 5.5
billynoah

292

Các hiệu quả nhất giải pháp là strtokchức năng:

strtok($mystring, '/')

Ví dụ:

$mystring = 'home/cat1/subcat2/';
$first = strtok($mystring, '/');
echo $first; // home

$mystring = 'home';
$first = strtok($mystring, '/');
echo $first; // home

25
Điều này cũng nhanh hơn khoảng 40% so với current-explodegiải pháp. (Không phải tôi sử dụng nó thường xuyên đến mức nó quan trọng.)
kéo dài

5
Điều này là thanh lịch và nhanh chóng - nên là câu trả lời được chấp nhận.
Kosta Kontos

5
Đây phải là câu trả lời bị loại trừ. Chắc chắn nhanh hơn và nhiều bộ nhớ và CPU hoạt động hiệu quả hơn bất kỳ explodegiải pháp nào được đưa ra.
Shivam Maheshwari

Vấn đề với strtokfirst/secondsẽ trả về firstnhưng /secondsẽ trả về secondchứ không phải là một chuỗi rỗng.
rybo111

Thêm vào nhận xét trên của tôi: Hành vi khi tìm thấy một phần trống đã thay đổi với PHP 4.1.0. Hành vi cũ trả về một chuỗi rỗng, trong khi hành vi mới, chính xác, chỉ cần bỏ qua phần của chuỗi
rybo111

95
$first = explode("/", $string)[0];

2
thanh lịch, nhưng không hiệu quả trong thời gian máy tính. Nhưng những ngày này mọi người không quan tâm nhiều về chu kỳ CPU phút
Dennis

13

Cái này thì sao :

substr($mystring.'/', 0, strpos($mystring, '/'))

Chỉ cần thêm '/' vào cuối bí ẩn để bạn có thể chắc chắn có ít nhất một;)


Bạn chỉ có thể kiểm tra nếu có một dấu gạch chéo trong chuỗi trước khi thực hiện việc này. Dù sao, đó là giải pháp đơn giản nhất.
Guilherme Sampaio

12

Phiên bản một dòng của câu trả lời được chấp nhận:

$out=explode("/", $mystring, 2)[0];

Nên hoạt động trong php 5.4+


1
Không giống như bên dưới, "2" giới hạn số lượng mục mảng mà nó tạo ra. Suy nghĩ tốt.
Ben ở CA

9

Đây có lẽ là ví dụ ngắn nhất xuất hiện trong đầu tôi:

list($first) = explode("/", $mystring);

1) list()sẽ tự động gán chuỗi cho đến khi "/"tìm thấy dấu phân cách
2) nếu "/"không tìm thấy dấu phân cách thì toàn bộ chuỗi sẽ được chỉ định

... Và nếu bạn thực sự bị ám ảnh bởi hiệu suất, bạn có thể thêm tham số bổ sung để phát nổ explode("/", $mystring, 2)giới hạn tối đa của các phần tử được trả về.


2
Tôi thích cách tiếp cận này. Tiết kiệm làm cho một mảng không cần thiết. Và strtok()không an toàn.
rybo111

1
@ rybo111: Điều gì không an toàn strtok()?
hakre

@ rybo111 Tôi lặp lại tình cảm của hakre; Điều gì làm cho strtok()không an toàn?
Doktor J

@hakre Xem câu trả lời của tôi cho câu trả lời của jmarceli. Nó có thể gây ra hành vi bất ngờ tùy thuộc vào phiên bản PHP.
rybo111

php 4.1.0 - rly?
hakre

8

Muộn còn hơn không. php có một chức năng được xác định trước cho điều đó. đây là cách tốt

strstr

nếu bạn muốn lấy phần trước khi khớp, chỉ cần đặt before_needle (tham số thứ 3) thành true http://php.net/manual/en/feft.strstr.php

function not_strtok($string, $delimiter)
{    
    $buffer = strstr($string, $delimiter, true);

    if (false === $buffer) {
        return $string;
    }

    return $buffer;
}

var_dump(
    not_strtok('st/art/page', '/')
);

Điều này không an toàn để sử dụng nếu bạn không thể chắc chắn rằng kim tồn tại trong chuỗi.
fooquency

@fooquency - Đúng, nhưng bạn luôn có thể thêm ký tự vào cuối chuỗi bạn đang kiểm tra, chỉ để chắc chắn.
MikeSchinkel 17/07/19

Cảm ơn. Các thử nghiệm của tôi cho thấy rằng strstrnhanh hơn một chút strtok. Tôi sẽ đi với người cũ.
Ian Y.

5

Hàm strstr () trong PHP 5.3 sẽ thực hiện công việc này .. Tuy nhiên, tham số thứ ba nên được đặt thành true ..

Nhưng nếu bạn không sử dụng 5.3, thì chức năng bên dưới sẽ hoạt động chính xác:

function strbstr( $str, $char, $start=0 ){
    if ( isset($str[ $start ]) && $str[$start]!=$char ){
        return $str[$start].strbstr( $str, $char, $start+1 );
    }
}

Tôi đã không thử nó mặc dù, nhưng nó sẽ hoạt động tốt .. Và nó cũng khá nhanh


3
+1 cho strstr(), nhưng lưu ý rằng nó trả về falsenếu chuỗi không chứa $needle, do đó các explode()giải pháp ở trên phù hợp hơn trong trường hợp này.
Benjamin

3

Bạn có thể tạo một hàm trợ giúp để xử lý việc đó:

/**
 * Return string before needle if it exists.
 *
 * @param string $str
 * @param mixed $needle
 * @return string
 */
function str_before($str, $needle)
{
    $pos = strpos($str, $needle);

    return ($pos !== false) ? substr($str, 0, $pos) : $str;
}

Đây là trường hợp sử dụng:

$sing = 'My name is Luka. I live on the second floor.';

echo str_before($sing, '.'); // My name is Luka

3

Bạn có thể thử sử dụng regex như thế này:

$s = preg_replace('|/.*$|', '', $s);

đôi khi, regex chậm hơn, vì vậy nếu hiệu suất là một vấn đề, hãy đảm bảo điểm chuẩn này đúng và sử dụng một giải pháp thay thế khác với chuỗi con nếu nó phù hợp hơn với bạn.


2
Regex có lẽ cũng quá mức cần thiết, nhưng vì tôi nói tương tự về explodenó sẽ rất thú vị để xem cái nào nhanh hơn.
rvighne

1
hoàn toàn không có gì sai với điều này và tôi không thể nghĩ tại sao nó lại xứng đáng với 2 lượt tải xuống. Cá nhân tôi sẽ không sử dụng regex nhưng chắc chắn không sai.
billynoah


0
$string="kalion/home/public_html";

$newstring=( stristr($string,"/")==FALSE ) ? $string : substr($string,0,stripos($string,"/"));

0

Bạn cũng có thể sử dụng giải pháp một dòng này

list($substring) = explode("/", $string);

-1

Tôi nghĩ rằng điều này sẽ làm việc?

substr($mystring, 0, (($pos = (strpos($mystring, '/') !== false)) ? $pos : strlen($mystring)));

Hàm của bạn sẽ luôn trả về char đầu tiên vì bạn đang thực hiện (strpose ($ mystring, '/')! == false) trước khi bạn gán nó cho $ pos, bạn cần thực hiện (($ pos = strpose ($ FirstColumnName, '_'))! == sai). Đây sẽ là 1 lót mà anh chàng đã đăng câu hỏi đang tìm kiếm.
Mihai P.

-1

tại sao không sử dụng:

function getwhatiwant($s)
{
    $delimiter='/';
    $x=strstr($s,$delimiter,true);
    return ($x?$x:$s);
}

HOẶC LÀ:

   function getwhatiwant($s)
   {
       $delimiter='/';
       $t=explode($delimiter, $s);
       return ($t[1]?$t[0]:$s);
   }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.