Body text special characters are escaped I have this code which I am using to get the body text from a node rewrite it with a regular expression and replace it, (I am replacing all you tube video links with embed codes)
function hook_entity_presave(Drupal\Core\Entity\EntityInterface $entity) {

  switch ($entity-&gt;bundle()) {
    case 'article':

    $node_body = $entity-&gt;get('body')-&gt;value;

    Drupal::logger('origin-body')-&gt;notice($node_body);


    $node_body_replaced = preg_replace('/(?:https:\/\/)?(?:http:\/\/)?(?:www\.)?(?:youtube\.com|youtu\.be)\/(?:watch\?v=)?(.+)/', '&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/$1&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;/iframe&gt;', $node_body);

      Drupal::logger('replaced-body')-&gt;notice($node_body_replaced);
      $body_encoded = htmlspecialchars($node_body_replaced, ENT_QUOTES, 'UTF-8');
      //$entity-&gt;body = $node_body_replaced;
      $entity-&gt;set( 'body',$body_encoded  ); // This appears to be where special characters are getting escaped
      
     break;
  }
}

Both my logger messages show normal text output in the drupal log so I guess it happens somwhere when the node gets saved or $entity-&gt;set().  I have tried running through htmlspecialchars() and it does nothing.
For example, I am migrating content from WordPress and after running through this function my normal HTML becomes

&lt;p&gt;lorem ipsum dolar lorem ipsum dolar lorem ipsum dolar lorem
ipsum dolar lorem ipsum dolar lorem ipsum dolar .&lt;/p&gt; &lt;!--
/wp:paragraph --&gt;

I am using Drupal 9
Assuming by my normal HTML becomes you mean the escaped HTML is rendering on the front end, you're probably just resetting the format for the body field with this line
$entity-&gt;set('body', $body_encoded);

You can target the value directly instead like this (and you shouldn't need to encode/decode anything):
$entity-&gt;body-&gt;value = preg_replace('/(?:https:\/\/)?(?:http:\/\/)?(?:www\.)?(?:youtube\.com|youtu\.be)\/(?:watch\?v=)?(.+)/', '&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/$1&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;/iframe&gt;', $node_body);

If that isn't working you can try setting the format too:
// Possibly change 'full_html' to whatever's appropriate for your site.
$entity-&gt;body-&gt;format = 'full_html';