PHP Thay thế lần xuất hiện cuối cùng của Chuỗi trong Chuỗi?


Câu trả lời:


228

Bạn có thể sử dụng chức năng này:

function str_lreplace($search, $replace, $subject)
{
    $pos = strrpos($subject, $search);

    if($pos !== false)
    {
        $subject = substr_replace($subject, $replace, $pos, strlen($search));
    }

    return $subject;
}

Điều này vẫn trở lại đúng sự thật không có vấn đề gì. Xem xét sửa đổi nó thành: if ($ pos) {$ topic = struct_Vplace ($ topic, $ thay thế, $ pos, strlen ($ search)); trả về chủ đề $; } khác {trả về false; }
Jazzy

4
@Jason Nó không trở lại TRUEbất kể điều gì. Nó trả về một chuỗi bất kể điều gì. Nếu một sự thay thế không thể được thực hiện, nó sẽ trả về bản gốc $subject, giống như substr_replace str_replacelàm.
Mischa

@Mischa Không phải điều tương tự trong trường hợp này sao? Tôi đã cố gắng làm một cái gì đó như! Str_lreplace, nhưng nếu nó không trả về sai, nó được coi là đúng, phải không? Dù bằng cách nào, điều này đã giúp tôi ra ngoài và tôi đánh giá cao nó. Cảm ơn.
Jazzy

1
Làm thế nào điều này có thể làm việc? strpos — Find the position of the first occurrence of a substring in a string- chỉnh sửa: wow. Php thiên tài thực sự đã thực hiện một chức năng được gọi là strposstrrpos? Cảm ơn ....
BarryBones41

1
@Barry đây là một trường hợp PHP không xứng đáng đổ lỗi :-) Các tên được hoa văn trên những thập kỷ tuổi strstr, strrstrcủa thư viện C chuẩn, đó là những chức năng tương tự. (Nhưng họ phải đổi tên không?)
alexis

30

Một lớp lót khác nhưng không có preg:

$subject = 'bourbon, scotch, beer';
$search = ',';
$replace = ', and';

echo strrev(implode(strrev($replace), explode(strrev($search), strrev($subject), 2))); //output: bourbon, scotch, and beer

3
FWIW, giải pháp được chấp nhận nhanh hơn khoảng 35% so với giải pháp này.
JustCarty

27
$string = 'this is my world, not my world';
$find = 'world';
$replace = 'farm';
$result = preg_replace(strrev("/$find/"),strrev($replace),strrev($string),1);
echo strrev($result); //output: this is my world, not my farm

Giải pháp tuyệt vời nhất theo quan điểm của tôi và vẫn e ngại để hiểu.
Blackbam

Tại sao nó hoạt động với tất cả các chuỗi đảo ngược? Có một số (tôi giả sử) tăng hiệu suất cụ thể khi sử dụng biểu thức chính quy?
Kamafeather

Không, nó thực sự làm giảm hiệu suất nhưng đó là vì bạn chỉ muốn lần xuất hiện cuối cùng nên bạn giới hạn tìm kiếm ở một và đảo ngược mọi thứ nếu bạn muốn lần đầu tiên, bạn sẽ không phải đảo ngược bất cứ điều gì
Tofandel

15

Giải pháp khá nhỏ gọn sau đây sử dụng xác nhận tìm kiếm tích cực PCRE để khớp với lần xuất hiện cuối cùng của chuỗi con quan tâm, nghĩa là sự xuất hiện của chuỗi con không theo sau bởi bất kỳ sự xuất hiện nào khác của cùng một chuỗi con. Do đó, ví dụ thay thế last 'fox'bằng 'dog'.

$string = 'The quick brown fox, fox, fox jumps over the lazy fox!!!';
echo preg_replace('/(fox(?!.*fox))/', 'dog', $string);

ĐẦU RA: 

The quick brown fox, fox, fox jumps over the lazy dog!!!

5
Ý tưởng là tốt, nhưng mã không. Nó phải là:$string = 'The quick brown fox, fox, fox jumps over the lazy fox!!!'; echo preg_replace('/(fox(?!.*fox))/', 'dog', $string);
RoTable

Thật vậy, mã tôi đã đăng thay đổi tất cả các trường hợp của "con cáo" ngoại trừ cái cuối cùng thành "con chó", nhưng những gì chúng ta muốn thì hoàn toàn ngược lại. Cảm ơn bạn đã chỉ ra rằng thay thế? = Với?! khắc phục sự cố.
John Sonderson

11

Bạn có thể làm điều này:

$str = 'Hello world';
$str = rtrim($str, 'world') . 'John';

Kết quả là 'Xin chào John';

Trân trọng


4
Điều này hoạt động miễn là không có bất kỳ ký tự lặp đi lặp lại. Trong tình huống của tôi, tôi sẽ loại bỏ số trang khỏi ngày lưu trữ để tôi có "2015-12 / 2" và phải mất tất cả / và tất cả 2 kết thúc trở thành "2015-1".
Mike

Điều này sẽ chỉ hoạt động nếu lần xuất hiện cuối cùng được tìm kiếm là từ cuối cùng và không có ký tự bổ sung sau nó.
AwesomeGuy

Điều này không hiệu quả vì rtrimkhông hành xử theo cách bạn nghĩ. Nó sẽ loại bỏ từ cuối bất kỳ ký tự nào tồn tại trong chuỗi tìm kiếm theo bất kỳ thứ tự nào (và luôn nối thêm từ thay thế), ví dụ: "Xin chào từ" -> "Xin chào John", "Xin chào chúa" -> "Xin chào John", "Xin chào motor "->" Xin chào motJohn "," Xin chào worldy "->" Xin chào worldyJohn ".
Jake

5

Điều này cũng sẽ làm việc:

function str_lreplace($search, $replace, $subject)
{
    return preg_replace('~(.*)' . preg_quote($search, '~') . '(.*?)~', '$1' . $replace . '$2', $subject, 1);
}

CẬP NHẬT Phiên bản ngắn gọn hơn một chút ( http://ideone.com/B8i4o ):

function str_lreplace($search, $replace, $subject)
{
    return preg_replace('~(.*)' . preg_quote($search, '~') . '~', '$1' . $replace, $subject, 1);
}

Có phải tôi đang làm sai? Nếu vậy hãy bỏ qua cho tôi :) ||| echo str_lreplace ("x", "y", "this x hoặc that x"); => Đầu ra: "y" Xem: ideone.com/UXuTo
edorian

@edorian: Rất tiếc! Xin lỗi, tôi đã đăng một cách vội vàng, phiên bản chính xác có ở đây: ideone.com/vR073 .
Alix Axel

5

Chỉ cần một dòng mã (câu trả lời trễ nhưng đáng để thêm nó):

$string = 'The quick brown fox jumps over the lazy dog';
$find_me = 'dog';

preg_replace('/'. $find_me .'$/', '', $string);

$ kết thúc chỉ ra sự kết thúc của chuỗi.


5

Đây là một câu hỏi cổ xưa, nhưng tại sao mọi người lại nhìn ra giải pháp dựa trên cơ chế regrec đơn giản nhất? Bình thường định lượng regrec là tham lam, mọi người! Nếu bạn muốn tìm ví dụ cuối cùng của một mẫu, chỉ cần dán .*trước mẫu đó. Đây là cách thực hiện:

$text = "The quick brown fox, fox, fox, fox, jumps over etc.";
$fixed = preg_replace("((.*)fox)", "$1DUCK", $text);
print($fixed);

Điều này sẽ thay thế ví dụ cuối cùng của "con cáo" thành "Ducks", giống như nó được yêu cầu và in:

The quick brown fox, fox, fox, DUCK, jumps over etc.

1
Cảm ơn! Các chức năng hoàn hảo để bao quanh biểu hiện của tôi để thực hiện điều này. Trong trường hợp của tôi, tôi thay thế dấu phẩy cuối cùng bằng "và". Vui mừng tôi đã cuộn xuống một chút trong danh sách câu trả lời này.
rlhane

3
$string = "picture_0007_value";
$findChar =strrpos($string,"_");
if($findChar !== FALSE) {
  $string[$findChar]=".";
}

echo $string;

Ngoài những sai lầm trong mã, Faruk Unal có anwser tốt nhất. Một chức năng thực hiện các mẹo.


Bạn cần kiểm tra, nếu $ findChar không sai (giống như trong câu trả lời được chấp nhận). Nếu chuỗi không chứa chuỗi tìm kiếm, bạn nhận được thông báo và ký tự đầu tiên sẽ được thay thế.
hổ

Điều này thật tuyệt, nhưng vì nó đứng nên nó chỉ có thể thay thế 1 ký tự bằng 1 ký tự.
Pete

3

Bạn có thể sử dụng strrpose () để tìm kết quả cuối cùng.

$string = "picture_0007_value";
$findChar =strrpos($string,"_");

$string[$findChar]=".";

echo $string;

Đầu ra: hình ảnh_0007.giá trị


2

Viết tắt cho câu trả lời được chấp nhận

function str_lreplace($search, $replace, $subject){ 
    return is_numeric($pos=strrpos($subject,$search))?
    substr_replace($subject,$replace,$pos,strlen($search)):$subject;
}


0

Sử dụng "$" trên biểu thức reg để khớp với phần cuối của chuỗi

$string = 'The quick brown fox jumps over the lazy fox';
echo preg_replace('/fox$/', 'dog', $string);

//output
'The quick brown fox jumps over the lazy dog'

4
điều này chỉ hoạt động nếu lần xuất hiện cuối cùng ở cuối chuỗi ideone.com/nbNSNq
cawecoy

1
Điều này sẽ không hoạt động nếu có bất kỳ nhân vật nào khác xuất hiện sau 'con cáo' cuối cùng.
John Sonderson

0

Đối với người quan tâm: Tôi đã viết một hàm sử dụng preg_match để bạn có thể thay thế từ phía bên tay phải bằng regex.

function preg_rreplace($search, $replace, $subject) {
    preg_match_all($search, $subject, $matches, PREG_SET_ORDER);
    $lastMatch = end($matches);

    if ($lastMatch && false !== $pos = strrpos($subject, $lastMatchedStr = $lastMatch[0])) {
        $subject = substr_replace($subject, $replace, $pos, strlen($lastMatchedStr));
    }

    return $subject;
}

Hoặc như một sự kết hợp tốc độ / thực hiện của cả hai tùy chọn:

function str_rreplace($search, $replace, $subject) {
    return (false !== $pos = strrpos($subject, $search)) ?
        substr_replace($subject, $replace, $pos, strlen($search)) : $subject;
}
function preg_rreplace($search, $replace, $subject) {
    preg_match_all($search, $subject, $matches, PREG_SET_ORDER);
    return ($lastMatch = end($matches)) ? str_rreplace($lastMatch[0], $replace, $subject) : $subject;
}

dựa trên https://stackoverflow.com/a/3835653/3017716https://stackoverflow.com/a/23343396/3017716

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.