matching a word to end of string with strpos [closed]
Asked Answered
L

5

5

I'm trying to match a word in a string to see if it occurs at the end of that string. The usual strpos($theString, $theWord); wouldn't do that.

Basically if $theWord = "my word";

$theString = "hello myword";        //match
$theString = "myword hello";        //not match
$theString = "hey myword hello";    //not match

What would be the most efficient way to do it?

P.S. In the title I said strpos, but if a better way exists, that's ok too.

Ligamentous answered 27/3, 2010 at 5:50 Comment(3)
What do you mean by "word"? Space delimited text? Would the key "foo" match "barfoo" or only "bar foo"?Feminize
@Nick, if $word = "foo"; then both $sentence = "barfoo" or "bar foo"; should still match. It's not important in this case if it has a space before it or not.Ligamentous
possible duplicate of What's the most efficient test of whether a PHP string ends with another string?Portraiture
R
11

You can make use of strrpos function for this:

$str = "Oh, hi O";
$key = "O";

if(strlen($str) - strlen($key) == strrpos($str,$key))
    print "$str ends in $key"; // prints Oh, hi O ends in O

or a regex based solution as:

if(preg_match("#$key$#",$str)) {
 print "$str ends in $key"; // prints Oh, hi O ends in O
}
Regurgitation answered 27/3, 2010 at 5:56 Comment(3)
The regex solution doesn't always produce correct results. See my comment on @jjclarkson's answer.Radiophotograph
@Ayman, thanks for pointing it out. Will update the summary of the thread.Ligamentous
@Aryam: OP wants to match a word not just any string. Now I've assumed a word will be alphabetic or alphanumeric. If the word can contain any char of which some can be regex meta char, this will not work and we'll have to escape the metas.Regurgitation
D
1

strpos could be the most efficient in some cases, but you can also substr with a negative value as the second parameter to count backwards from the end of the string:

$theWord = "my word";
$theWordLen = strlen($theWord);

$theString = "hello myword";
$matches = ($theWord ==substr($theString, -1 * $theWordLen);
Deprived answered 27/3, 2010 at 6:14 Comment(1)
The disadvantage of this method is that you are creating a temporary string from the "substr" result. The strrpos method mentioned by codaddict is probably faster (although you would want to test strict equality).Deprived
L
1

Why just not reverse the strings and use strpos as intended:

if(strpos(strrev($haystack), strrev($needle))===0)

True that strrev will mess up multi-byte chars, but since both haystack and needle are messed equally it still works fine. I did some tests and this is faster than any other method. Probably consumes more memory though.

Lunisolar answered 6/7, 2018 at 14:23 Comment(1)
+1 for the simplicity of this solution. I agree that in principle this will work for multibyte characters as well, but in case someone wants a multibyte-compliant version: php function endsWith($word, $suffix) { if (mb_strrpos(mb_strrev($word), self::mb_strrev($suffix)) === 0) { return TRUE; } return FALSE; } function mb_strrev($text) { $str = iconv('UTF-8', 'windows-1251', $text); $string = strrev($str); $str = iconv('windows-1251', 'UTF-8', $string); return $str; } Crespo
M
0

You could use a regular expression.

if(preg_match('/'.$theWord.'$/', $theString)) {
    //matches at the end of the string
}

Or you could use strrpos() and add the length of the word. (strrpos — "Find position of last occurrence of a char in a string") Then see if that is the position of the last character in the string.

Merta answered 27/3, 2010 at 5:54 Comment(4)
Doesn't produce the correct output if $theWord contains meta-characters. Try it with $theWord set to '.' for example.Radiophotograph
Quite true, you'd definitely have to validate the word and/or escape meta-characters.Merta
It's probably slower than codaddict's first method too.Casey
You might want to wrap $theWord in preg_quote()Grosz
E
0

Another, slightly shorter solution using strrpos:

$haystack = "foobar";
$needle = "bar";

if(false !== strrpos($haystack, $needle, -strlen($needle)))
    print "$haystack ends in $needle";

It doesn't have to scan the whole haystack and requires only one strlen call.

Eponymous answered 14/5 at 21:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.