Given two equal-length strings, is there an elegant way to get the offset of the first different character?
The obvious solution would be:
for ($offset = 0; $offset < $length; ++$offset) {
if ($str1[$offset] !== $str2[$offset]) {
return $offset;
}
}
But that doesn’t look quite right, for such a simple task.
You can use a nice property of bitwise XOR (
^) to achieve this: Basically, when you xor two strings together, the characters that are the same will become null bytes ("\0"). So if we xor the two strings, we just need to find the position of the first non-null byte usingstrspn:That’s all there is to it. So let’s look at an example:
That will output:
So that should do it. It’s very efficient since it’s only using C functions, and requires only a single copy of memory of the string.
Edit: A MultiByte Solution Along The Same Lines:
First the difference at the byte level is found using the above method and then the offset is mapped to the character level. This is done using the
mb_strcutfunction, which is basicallysubstrbut honoring multibyte character boundaries.It’s not as elegant as the first solution, but it’s still a one-liner (and if you use the default encoding a little bit simpler):