{"flag":true,"single":true,"pageTitle":"replace text only not html strings using PHP and dom | str_replace alternative","post":{"id":141,"user_id":"1","slug":"replace-text-only-not-html-strings-using-php-and-dom-str-replace-alternative-82td","title":"replace text only not html strings using PHP and dom | str_replace alternative","body":"<p>In this tutorial, we will learn how to manipulate text within HTML strings using PHP and the DOM (Document Object Model) without affecting the HTML structure. Specifically, we will focus on replacing text content while preserving anchor tags. This method is different from str_replace, which replaces text in a string without considering the HTML context.<\/p>\r\n<p>str_replace is a simple string replacement function, and it may cause issues when you need to replace text within an HTML string while preserving the structure. For example, it might accidentally replace content within an anchor tag or other HTML tags, which could break the structure.<\/p>\r\n<p>On the other hand, using the DOM allows us to manipulate the HTML string by treating it as an HTML document. This way, we can target and modify specific elements or text nodes without affecting the overall structure.<\/p>\r\n<p>Let's go through a step-by-step process for replacing text in an HTML string while preserving anchor tags.<\/p>\r\n<p>1.First, create a function named replace_text_only that accepts three parameters: $search, $replace, and $subject.<\/p>\r\n<pre class=\"language-markup\"><code>function replace_text_only($search, $replace, $subject) {\r\n    \/\/ function body\r\n}\r\n<\/code><\/pre>\r\n<p>2. Inside the function, create a new DOMDocument object and load the HTML string $subject. We'll wrap the $subject with a &lt;div&gt; tag to ensure proper parsing.<\/p>\r\n<pre class=\"language-markup\"><code>$dom = new DOMDocument;\r\nlibxml_use_internal_errors(true);\r\n$dom-&gt;loadHTML(mb_convert_encoding('&lt;div&gt;' . $subject . '&lt;\/div&gt;', 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);\r\nlibxml_clear_errors();\r\n<\/code><\/pre>\r\n<p>3. Create a new DOMXPath object and query for all text nodes that are not children of anchor tags.<\/p>\r\n<pre class=\"language-markup\"><code>$xpath = new DOMXPath($dom);\r\n$nodes = $xpath-&gt;query('\/\/text()[not(ancestor::a)]');<\/code><\/pre>\r\n<p>4. Loop through the text nodes and replace the text content based on the $search and $replace parameters. Use preg_replace to perform case-insensitive replacement.<\/p>\r\n<pre class=\"language-markup\"><code>foreach ($nodes as $node) {\r\n    $nodeContent = $node-&gt;textContent;\r\n    $nodeContent = preg_replace('\/\\b' . preg_quote($search, '\/') . '\\b\/i', $replace, $nodeContent);\r\n\r\n    $newNode = $dom-&gt;createTextNode($nodeContent);\r\n    $node-&gt;parentNode-&gt;replaceChild($newNode, $node);\r\n}<\/code><\/pre>\r\n<p>5. Extract the modified content from the DOM and return it as a string.<\/p>\r\n<pre class=\"language-markup\"><code>$body = $dom-&gt;getElementsByTagName('div')-&gt;item(0);\r\n$newContent = '';\r\nforeach ($body-&gt;childNodes as $childNode) {\r\n    $newContent .= $dom-&gt;saveHTML($childNode);\r\n}\r\nreturn $newContent;<\/code><\/pre>\r\n<p>Now, you can use the replace_text_only function to replace text within an HTML string while preserving the structure.<\/p>\r\n<pre class=\"language-markup\"><code>echo replace_text_only(\"hello\", \"new Hello\", \"Hello word &lt;a href='hello'&gt;hello&lt;\/a&gt;\");<\/code><\/pre>\r\n<p>Output:<\/p>\r\n<pre class=\"language-markup\"><code>new Hello word &lt;a href='hello'&gt;hello&lt;\/a&gt;<\/code><\/pre>\r\n<p>&nbsp;<\/p>\r\n<p>Complete code:<\/p>\r\n<pre class=\"language-markup\"><code>function replace_text_only($search, $replace , $subject) {\r\n    $dom = new DOMDocument;\r\n    libxml_use_internal_errors(true);\r\n    $dom-&gt;loadHTML(mb_convert_encoding('&lt;div&gt;' . $subject . '&lt;\/div&gt;', 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);\r\n    libxml_clear_errors();\r\n    $xpath = new DOMXPath($dom);\r\n    $nodes = $xpath-&gt;query('\/\/text()[not(ancestor::a)]');\r\n    foreach ($nodes as $node) {\r\n        $nodeContent = $node-&gt;textContent;\r\n        $nodeContent = preg_replace('\/\\b' . preg_quote($search, '\/') . '\\b\/i', $replace, $nodeContent); \/\/ Add the \"i\" modifier for case-insensitive matching\r\n\r\n        $newNode = $dom-&gt;createTextNode($nodeContent);\r\n        $node-&gt;parentNode-&gt;replaceChild($newNode, $node);\r\n    }\r\n    $body = $dom-&gt;getElementsByTagName('div')-&gt;item(0);\r\n    $newContent = '';\r\n    foreach ($body-&gt;childNodes as $childNode) {\r\n        $newContent .= $dom-&gt;saveHTML($childNode);\r\n    }\r\n    return $newContent;\r\n}\r\necho replace_text_only(\"hello\", \"new Hello\", \"Hello word &lt;a href='hello'&gt;hello&lt;\/a&gt;\");<\/code><\/pre>","category_id":"1","is_private":"0","created_at":"2023-05-09T07:04:19.000000Z","updated_at":"2023-05-09T07:04:19.000000Z","category":{"id":1,"user_id":"1","name":"PHP","slug":"php-3ius","parent_id":null,"created_at":"2023-03-14T03:58:19.000000Z","updated_at":"2023-03-14T03:58:19.000000Z"},"user":{"id":1,"name":"R GONDAL","email":"rizikmw@gmail.com","email_verified_at":null,"two_factor_confirmed_at":null,"current_team_id":"1","profile_photo_path":null,"created_at":"2023-03-12T10:49:33.000000Z","updated_at":"2025-01-10T12:59:00.000000Z","profile_photo_url":"https:\/\/ui-avatars.com\/api\/?name=R+G&color=7F9CF5&background=EBF4FF"}},"pageDesc":"In this tutorial, we will learn how to manipulate text within HTML strings using PHP and the DOM (Document Object Model) without affecting t - replace text only not html strings using PHP and dom | str_replace alternative (Updated: May 9, 2023) - Read more about replace text only not html strings using PHP and dom | str_replace alternative at my programming site [SITE]","categories":[]}