1

Let's say I have a string variable:

$string = "1 2 3 1 2 3 1 2 3 1 2 3";

I want to cut off the end of this string starting at the fourth occurrence of the substring "2", so $string is now equal to this:
1 2 3 1 2 3 1 2 3 1.

Effectively cutting off the fourth occurrence of "2" and everything after it.

How would one go about doing this? I know how to count the number of occurrences with substr_count($string,"2");, but I haven't found anything else searching online.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
WillumMaguire
  • 537
  • 2
  • 10
  • 21
  • So far I can use substr_count to get the number of occurrences in a string – WillumMaguire Jan 20 '13 at 20:16
  • The number of occurrences is the wrong thing to concentrate on here, instead you should concentrate on the position of those occurrences (hint: use `strpos()`). So you should loop 4 times, and after the 4th loop take a substring up to the 4th occurrence. – DaveRandom Jan 20 '13 at 20:21

6 Answers6

2

To find the position of the fourth 2 you could start with an offset of 0 and recursively call $offset = strpos($str, '2', $offset) + 1 while keeping track of how many 2's you've matched so far. Once you reach 4, you just can just use substr().

Of course, the above logic doesn't account for false returns or not enough 2's, I'll leave that to you.


You could also use preg_match_all with the PREG_OFFSET_CAPTURE flag to avoid doing the recursion yourself.


Another option, expanding on @matt idea:

implode('2', array_slice(explode('2', $string, 5), 0, -1));
Alix Axel
  • 151,645
  • 95
  • 393
  • 500
1

May be this would work for you:

$str = "1 2 3 1 2 3 1 2 3 1 2 3"; // initial value
preg_match("#((.*)2){0,4}(.*)#",$str, $m);
//var_dump($m);
$str = $m[2]; // last value
Abu Romaïssae
  • 3,841
  • 5
  • 37
  • 59
1

This code snippet should do it:


implode($needle, array_slice(explode($needle, $string), 0, $limit));
Mirko Adari
  • 5,083
  • 1
  • 15
  • 23
1
$string = explode( "2", $string, 5 );
$string = array_slice( $string, 0, 4 );
$string = implode( "2", $string );

See it here in action: http://codepad.viper-7.com/GM795F


To add some confusion (as people are won't to do), you can turn this into a one-liner:

implode( "2", array_slice( explode( "2", $string, 5 ), 0, 4 ) );

See it here in action: http://codepad.viper-7.com/mgek8Z


For a more sane approach, drop it into a function:

function truncateByOccurence ($haystack, $needle,  $limit) {
    $haystack = explode( $needle, $haystack, $limit + 1 );
    $haystack = array_slice( $haystack, 0, $limit );
    return implode( $needle, $haystack );
}

See it here in action: http://codepad.viper-7.com/76C9VE

Joseph Silber
  • 214,931
  • 59
  • 362
  • 292
  • It seems to work there, I'll have to test it out in my script – WillumMaguire Jan 20 '13 at 20:35
  • @MirkoAdari, I didn't know what implode and explode did when I posted this (a quick google search was all I needed to figure them out). This answer is a bit easier to understand, as it breaks up what has to be done into individual steps. – WillumMaguire Jan 20 '13 at 20:42
  • @MirkoAdari - When I started writing this answer you hadn't posted yet. After I finished writing it, supplied the demo & posted, I realized that you had just given a similar answer. I figured this was much more complete, so I left it here. – Joseph Silber Jan 20 '13 at 20:44
  • @MirkoAdari - Also, you forgot to limit the `explode`. – Joseph Silber Jan 20 '13 at 20:45
0

How about something simple like

$newString = explode('2',$string);

and then loop through the array as many times as occurrences you need:

$finalString = null;
for($i=0:$i<2;$i++){
    $finalString .= 2 . $newString[$i];
}

echo $finalString;
matt
  • 2,312
  • 5
  • 34
  • 57
0

Match zero or more non-2 characters followed by a 2 -- repeated 4 times.

Restart the fullstring match before every matched 2 with \K.

After successfully matching four 2's, match the remaining characters and replace the matched characters with an empty string.

$string = "1 2 3 1 2 3 1 2 3 1 2 3";

echo preg_replace(
         '~([^2]*\K2){4}.*~',
         '',
         $string
     );

I have similar pattern advice at this answer which splits a string on every n characters.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136