user2641845
user2641845

Reputation: 73

Loop over array and replacing with regex returns empty string

I have a String which contains substrings which I have to replace. The substrings are stored in an array. When I loop through the array everything works fine, until the array has more than 120 entries.

foreach ( $activeTags as $k => $v ) {
  $find = $activeTags[$k]['Tag']['tag'];
  $replace = 'that';
  $pattern = "/\#\#[a-zA-Z][a-zA-Z]\#\#.*\b$find\b.*\#\#END_[a-zA-Z][a-zA-Z]\#\#|$find/"; 
  $sText = '<p>Do not replace ##DS## this ##END_DS## replace this.</p>';

  $sText = preg_replace_callback($pattern, function($match) use($find, $replace){
    if($match[0] == $find){
      return($replace);
    }else{
      return($match[0]);
    }
  }, $sText);
}

when count($activeTags) == 121 i only get an empty string.

Has onyone an idea why this happens?

Upvotes: 1

Views: 96

Answers (1)

Stephan
Stephan

Reputation: 43053

Try this improved pattern:

$pattern = "~##([a-zA-Z]{2})##.*?\b$find\b.*?##END_\1##|$find~s";

Description

Regular expression visualization

Discussion

The ~s flag indicates that dot (.) should match newlines. In your example, p tags are metionned. So I guess its an html fragment. Since newlines are alloed in html, I have added the ~s flag. More over, I have made the pattern more readable by:

  • using custom pattern boundaries: / becomes ~, you avoid escape anything...
  • replacing duplicate subpatterns: [a-zA-Z][a-zA-Z] becomes [a-zA-Z]{2}
  • taking advantage of the sequence ##DS## ##END_DS##. I use a backreference (\1) for matching what was found in the first matching group (Group 1 in the above image).

Upvotes: 1

Related Questions