<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Kolade Chris - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Kolade Chris - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 17 May 2026 22:27:50 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/koladechris/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Use Developer Tools to Debug JavaScript in the Browser ]]>
                </title>
                <description>
                    <![CDATA[ The console object is the number one go-to for developers when working with buggy JavaScript code. But if you still rely heavily on the console object alone to debug your JavaScript, then you're missing out on some amazing browser developer tools fea... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-developer-tools-to-debug-javascript-in-the-browser/</link>
                <guid isPermaLink="false">67224a271058ad4196106527</guid>
                
                    <category>
                        <![CDATA[ debugging ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Wed, 30 Oct 2024 15:00:55 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/gTs2w7bu3Qo/upload/f2ead89e25e967947691c8e4a1f8f862.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The <code>console</code> object is the number one go-to for developers when working with buggy JavaScript code.</p>
<p>But if you still rely heavily on the <code>console</code> object alone to debug your JavaScript, then you're missing out on some amazing browser developer tools features.</p>
<p>Let's take a look at how you can debug JavaScript with the Chrome developer tools.</p>
<h2 id="heading-the-buggy-code-were-working-with">The Buggy Code We're Working With</h2>
<p>To get started, I’ve prepared some buggy code that should add four numbers and also get their average.</p>
<p>Here's the HTML of the code:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"num1"</span>&gt;</span>Number 1:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"num1"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter a number"</span> /&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"num2"</span>&gt;</span>Number 2:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"num2"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter a number"</span> /&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"num3"</span>&gt;</span>Number 3:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"num3"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter a number"</span> /&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"num4"</span>&gt;</span>Number 4:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"num4"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter a number"</span> /&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"calculateBtn"</span>&gt;</span>Calculate Sum and Average<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"sum"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"average"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"script.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>Here's the very minimal CSS to push the labels to their respective lines and enlarge the input elements and button a bit:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">background</span>: <span class="hljs-number">#d2d2d2</span>;
}

<span class="hljs-selector-tag">label</span> {
  <span class="hljs-attribute">display</span>: block;
  <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">0.5rem</span>;
}

<span class="hljs-selector-tag">button</span> {
  <span class="hljs-attribute">display</span>: block;
  <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">1rem</span>;
}

<span class="hljs-selector-tag">input</span>,
<span class="hljs-selector-tag">button</span> {
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.2rem</span>;
}
</code></pre>
<p>Here's what the HTML and CSS displays in the browser:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729767323533/db4b903d-8cfe-4d6b-85b2-2233a2a2bcd0.png" alt="Sum and Average Calculator" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>And here's the JavaScript in which the bug occurs:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> calculateBtn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'calculateBtn'</span>);
<span class="hljs-keyword">const</span> sumText = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'sum'</span>);
<span class="hljs-keyword">const</span> avgText = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'average'</span>);

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">calculateTotal</span>(<span class="hljs-params">a, b, c, d</span>) </span>{
 <span class="hljs-keyword">return</span> a + b + c + d;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">calculateAverage</span>(<span class="hljs-params">total, count</span>) </span>{
 <span class="hljs-keyword">return</span> total / count;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleButtonClick</span>(<span class="hljs-params"></span>) </span>{
 <span class="hljs-keyword">let</span> num1 = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'num1'</span>).value;
 <span class="hljs-keyword">let</span> num2 = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'num2'</span>).value;
 <span class="hljs-keyword">let</span> num3 = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'num3'</span>).value;
 <span class="hljs-keyword">let</span> num4 = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'num4'</span>).value;

 <span class="hljs-keyword">let</span> total = calculateTotal(num1, num2, num3, num4);
 <span class="hljs-keyword">let</span> average = calculateAverage(total, <span class="hljs-number">4</span>);

 sumText.textContent = <span class="hljs-string">`The sum is <span class="hljs-subst">${total}</span>`</span>;
 avgText.textContent = <span class="hljs-string">`The average is: <span class="hljs-subst">${average}</span>`</span>;
}

calculateBtn.addEventListener(<span class="hljs-string">'click'</span>, handleButtonClick);
</code></pre>
<p>Here's what happens if you enter the 4 numbers, say <code>3</code>, <code>4</code>, <code>2</code>, <code>1</code>, and click the <code>Calculate Sum and Average</code> button:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729767417791/6c5a49d1-dc6f-45db-9720-c3c6daedbeb3.png" alt="Wrong sum and average" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Unfortunately, the numbers just got merged and the average is calculated based on that, which means concatenation is going on instead of addition. The buggy addition leads to a buggy average calculation too.</p>
<p>Let's investigate what's happening with the browser developer tools.</p>
<h2 id="heading-how-to-debug-javascript-code-using-chrome-developer-tools">How to Debug JavaScript Code Using Chrome Developer Tools</h2>
<p>When such a bug occurs, you might be tempted to add a bunch of console logs.</p>
<p>Many times, console logs get the job done – but you have to spend a lot of time figuring things out.</p>
<p>The browser developer tools give you more options such as adding breakpoints, watching particular expressions, and even stepping through the code line by line to see where the bug occurs.</p>
<h3 id="heading-how-to-open-the-developer-tools-and-the-sources-tab">How to Open the Developer Tools and the Sources Tab</h3>
<p>To start, right-click in the browser and select "inspect" to open the Chrome DevTools.</p>
<p>While in DevTools, head over to the "Sources" tab to see the files in the program. You can also press <code>F12</code> on your keyboard and select the Sources tab.</p>
<p>Here's a brief anatomy of the Chrome DevTools Sources tab:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729767628385/30310aa1-ddb0-41d5-a3ce-9ecc84b034e3.png" alt="Anatomy of the chrome developer tools source tab" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>On top of the debugger tab are some greyed-out icons. When active, they let you step through your code and add or remove breakpoints.</p>
<p>Also in the debugger tab are:</p>
<ul>
<li><p>Watch: where you can add and see the watch expressions</p>
</li>
<li><p>Breakpoints: where you can see the code of the line you add a breakpoint to</p>
</li>
<li><p>Scope: contains the local and global variables</p>
</li>
<li><p>Callstack: shows the function calls that lead to the current point of code execution</p>
</li>
</ul>
<p>To see the contents of any file, you can click on it. After doing that, some of the icons in the debugger tab won’t be greyed out anymore.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729767971149/04f8e5c7-a08a-49b3-be7f-2854f820b94a.png" alt="Icons of the Chrome developer tools source tab" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-how-to-debug-the-code-by-adding-breakpoints">How to Debug the Code by Adding Breakpoints</h3>
<p>To start debugging the code, you can add a breakpoint to a line by clicking the line number.</p>
<p>A breakpoint is like a line marker you can set in the developer tools to pause the execution of your code before that line executes. This lets you check variable values, see if functions are called as expected, or observe the general flow of the code.</p>
<p>When you add a breakpoint and execute the code, a bluish icon appears on that line, indicating that execution will pause before that line.</p>
<p>Alternatively, you can add the <code>debugger</code> statement to the line where you want the execution to be paused. But let’s stick to using breakpoints.</p>
<p>For example, let's add a breakpoint to line 14, then enter the four numbers and click the <code>Calculate Sum and Average</code> button so the code will run:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729768234921/8c1f0d4e-5fb2-4461-8e62-574d95a51672.png" alt="Breakpoint at line 14" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>At this point, you can see that the execution did not continue – that's why you see "value unavailable" for all the variables under “Local”.</p>
<p>From here, you can start stepping through the code line by line by pressing the step icon in the top right corner:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729768323163/45fb5c6b-682d-4b90-8bec-d4ef8596c4b7.png" alt="The step icon of the Chrome developer tools source tab" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Once you click the step icon, the line you step out of executes.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729768411765/f2670800-c8d8-490f-8dc9-1fdfa8c8da7b.png" alt="Clicking the step icon" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>You can see that <code>"3"</code> is the value for line <code>14</code>. That value is surrounded by a pair of double quotes. That means it‘s a string. You need to be sure about that, though, and that’s what the watch feature lets you do. You’ll learn about that feature soon.</p>
<p>If you’re working with several lines of code, it might be time-consuming to step through the code line by line. So, you might have to add another breakpoint.</p>
<p>I will go ahead and set a breakpoint at line <code>23</code> and run the code again:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729768528136/478fc837-0c16-4990-9b70-19ff1695331e.png" alt="Breakpoint at line 23" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Now you can see that all the variable results apart from <code>average</code> appear to be strings. This takes us to the next Chrome developer tools debugger feature – watcher.</p>
<h3 id="heading-how-to-use-the-developer-tools-watch-feature">How to Use the Developer Tools Watch Feature</h3>
<p>The developer tools watch feature lets you monitor specific variables or expressions as your code runs.</p>
<p>To confirm the data type of the variables, you can add a watch expression that shows their values, or more appropriately, their types.</p>
<p>To add a watch expression, click the plus (+) icon right beside “Watch” and hit <code>ENTER</code> on your keyboard.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729768780977/ef22ae71-068c-41a2-9a2e-509c7c6a8afb.png" alt="Adding a watch expression" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Here are the watch expressions that confirm that <code>num1</code> through <code>num4</code> and <code>total</code> are strings – but they should be integers:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729768808497/5d7352d6-37b3-490c-9ce2-f430c2d9a0e6.png" alt="Watch expressions" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>You can also verify this in the console tab by checking the types of the variables there:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729768847227/3730a133-0a5b-4eb1-a5dd-257fa0ac2293.png" alt="Variable types in the console" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>This means that the numbers you enter are interpreted as strings. That’s because, in JavaScript, values from HTML elements like input fields are always retrieved as strings.</p>
<p>This happens because the <code>value</code> property of an input element returns a string, regardless of whether you enter numbers – and that’s how the bug was introduced.</p>
<p>Remember that JavaScript only concatenates strings even if they’re numbers. That means <code>"3"</code> is a string type and not an integer type.</p>
<p>To fix the bug, you should change the types of <code>num1</code> through <code>num4</code> to integers so JavaScript can correctly sum up their values.</p>
<p>You can then go ahead and fix this in the DevTools and press <code>CTRL + S</code> on Windows or <code>CMD + S</code> on Mac to save the code. You can also fix it inside your code editor by wrapping the variables of the numbers in <code>parseInt()</code>.</p>
<p>Once you do that and run the code again, the correct data types should show in the watcher, and the correct variable values should show under Local:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729768941146/964cabbd-2298-4303-ac0d-2b54af070d66.png" alt="Correct variable types in the watch" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>You can also go ahead and implement the changes in your code editor so that everything works. Here’s the correct code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> calculateBtn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'calculateBtn'</span>);
<span class="hljs-keyword">const</span> sumText = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'sum'</span>);
<span class="hljs-keyword">const</span> avgText = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'average'</span>);

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">calculateTotal</span>(<span class="hljs-params">a, b, c, d</span>) </span>{
  <span class="hljs-keyword">return</span> a + b + c + d;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">calculateAverage</span>(<span class="hljs-params">total, count</span>) </span>{
  <span class="hljs-keyword">return</span> total / count;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleButtonClick</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">let</span> num1 = <span class="hljs-built_in">parseInt</span>(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'num1'</span>).value);
  <span class="hljs-keyword">let</span> num2 = <span class="hljs-built_in">parseInt</span>(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'num2'</span>).value);
  <span class="hljs-keyword">let</span> num3 = <span class="hljs-built_in">parseInt</span>(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'num3'</span>).value);
  <span class="hljs-keyword">let</span> num4 = <span class="hljs-built_in">parseInt</span>(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'num4'</span>).value);

  <span class="hljs-keyword">let</span> total = calculateTotal(num1, num2, num3, num4);
  <span class="hljs-keyword">let</span> average = calculateAverage(total, <span class="hljs-number">4</span>);

  sumText.textContent = <span class="hljs-string">`The sum is <span class="hljs-subst">${total}</span>`</span>;
  avgText.textContent = <span class="hljs-string">`The average is: <span class="hljs-subst">${average}</span>`</span>;
}

calculateBtn.addEventListener(<span class="hljs-string">'click'</span>, handleButtonClick);
</code></pre>
<p>And here’s the result in the browser:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729769063113/b7e39538-e9fe-4ce5-a4de-e98f43263235.png" alt="Sum and average calculator working fine" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>That’s how you can debug JavaScript using Chrome’s developer tools. The breakpoint and watcher features, alongside the step-through buttons, are upgrades over a basic console log.</p>
<p>Note that every modern browser has this JavaScript debugging tool built into it, so you can use the same approach to debug JavaScript with Firefox or Edge.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Callout Component for your Astro Blog ]]>
                </title>
                <description>
                    <![CDATA[ Earlier this year, I became really interested in learning about Astro, so I completely rebuilt my blog using it. The results have been amazing since then: I can easily handle automatic sitemap generation and SEO, and integrating other tools became a ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-a-callout-component-for-your-astro-blog/</link>
                <guid isPermaLink="false">6717a6755af2bda0ccbde415</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Astro ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Tue, 22 Oct 2024 13:19:49 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1728900397885/4c9f906f-e531-4588-9e45-7b56920d676e.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Earlier this year, I became really interested in learning about Astro, so I completely rebuilt my blog using it. The results have been amazing since then: I can easily handle automatic sitemap generation and SEO, and integrating other tools became a breeze. Because of these benefits, I was inspired to publish an article every single week.</p>
<p>Astro is incredible for content-driven websites – so much so that since then, I've been cracking a joke: it should be a crime to build a blog and documentation site with any frontend framework other than Astro.</p>
<p>Another notable thing I was able to do on my blog was build a callout component. This is the little tangential boxes you see on documentation sites and some advanced developer blogs.</p>
<p>This is an example of one in the freeCodeCamp docs:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728898968834/da8175de-6380-4094-bf96-1c0d14f51625.png" alt="freeCodeCamp docs callout" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>And here’s one in the Astro docs:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728898998665/981f943b-d138-4f52-9e3f-627ab83526d8.png" alt="Astro documentation callout box" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>A bit unique, this is one on Josh Comeau's blog:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728899020675/a1199846-e851-4438-81dd-17a3da759d97.png" alt="Josh Comeau blog callout box" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Keep reading, so I can show you how to build a callout component for your Astro blog.</p>
<p>You can also use the same technique to create one for a blog built with any other frontend framework.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>To get the most out of this article, you need the following:</p>
<ul>
<li><p>basic knowledge of Astro</p>
</li>
<li><p>a knowledge of Astro slots and fragments</p>
</li>
<li><p>familiarity with JSX and prop-drilling</p>
</li>
<li><p>understanding of component-based architecture</p>
</li>
</ul>
<p>Astro slots and fragments might sound a bit strange. If that's the case, don't worry, I’l do my best to make things as clear as possible for you.</p>
<h2 id="heading-how-to-build-a-callout-component-for-your-blog">How to Build a Callout Component for your Blog</h2>
<p>The approach we are going to use is to have a <strong>parent component</strong> that will handle all the rendering for the callout box: the type, icon, text, and the styling.</p>
<p>What will follow are respective components that indicate a note, tip, caution, error callout boxes, and more.</p>
<p>Here's a diagram that simplifies the approach:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728934365025/93fe73ce-5781-47bd-a9f1-02519c22776a.png" alt="Callout parent and children components diagram" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Each of the child components is what you'll bring in any time you want to display a callout related to them.</p>
<p>To get started, create a folder, name it what you want (I call it astro-callout on my end), and install Astro.</p>
<p>What follows is a series of prompts. Here are the choices I made during the prompts:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728899147064/9d3f33ba-5b56-44de-a700-b3652fbefaec.png" alt="Astro installation prompt choices" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Here's what the project folder structure looks like after installing Astro and choosing the blog template:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728899305440/93267555-d761-4759-b666-037c9ff13738.png" alt="Astro blog template folder structure" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-how-to-build-the-parent-callout-component">How to Build the Parent <code>Callout</code> Component.</h3>
<p>Head over to the <code>src/component</code> directory and create a folder named <code>callout</code>. Then inside the folder, create a <code>Callout.astro</code> file.</p>
<p>The callout component is an <code>aside</code> element that will take in the following props:</p>
<ul>
<li><p><code>type</code>: the callout type (note, caution, error, tip, and others)</p>
</li>
<li><p><code>icon</code>: the icon that will signify the callout type. This could be an emoji or an icon from an icon library.</p>
</li>
<li><p><code>backgroundColor</code>: the different background color of each callout type</p>
</li>
<li><p><code>borderLeftColor</code>: the border-left color of each callout type</p>
</li>
</ul>
<p>Destructure those props from <code>Astro.props</code> in the code fence of the <code>Callout.astro</code> component:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> { icon, type, backgroundColor, borderLeftColor } = Astro.props
</code></pre>
<p>Don't forget the <code>aside</code> element has to have some text content, too. Astro has a way to handle this using the <code>&lt;slot /&gt;</code> element. </p>
<p><code>&lt;slot /&gt;</code> lets you insert child content written between opening and closing tags into any component.</p>
<p>Here's how I filled everything into the <code>aside</code> element:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">aside</span>
 <span class="hljs-attr">class</span>=<span class="hljs-string">"callout-box"</span>
 <span class="hljs-attr">style</span>=<span class="hljs-string">{{backgroundColor,</span> <span class="hljs-attr">borderLeftColor</span>}}
 &gt;</span>
 <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"callout-icon-and-type"</span>&gt;</span>
   {icon}
   {type}
 <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
 <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"callout-content"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">slot</span> /&gt;</span>
 <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">aside</span>&gt;</span>
</code></pre>
<p>The <code>icon</code> prop fills in for any icon you would like to use, be it an emoji or an icon library like Ionicons or Font Awesome.</p>
<p>The problem is that not all emojis will be rendered in a presentable way, as different operating systems render emojis their own ways. So, you must find a way to accept both emojis and an icon library. </p>
<p>The icon library I chose for this project is ionicons. Go into the layout file (in this case <code>layouts/BlogPost.astro</code>) and insert the following scripts just before the closing body tag:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.esm.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">nomodule</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>Here's the function that will let you render an icon, whether it’s an emoji or an ionicons icon:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">renderIcon</span>(<span class="hljs-params">icon:any</span>) </span>{
 <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> icon === <span class="hljs-string">'string'</span>) {
   <span class="hljs-keyword">return</span> icon;
 } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> icon === <span class="hljs-string">'object'</span> &amp;&amp; icon.name) {
   <span class="hljs-keyword">return</span> <span class="hljs-string">`&lt;ion-icon name="<span class="hljs-subst">${icon.name}</span>"&gt;&lt;/ion-icon&gt;`</span>;
 }
 <span class="hljs-keyword">return</span> <span class="hljs-string">''</span>;
}
</code></pre>
<p>This function checks if the <code>icon</code> you pass in is an emoji or an icon from the Ionicons library.</p>
<p>An emoji corresponds to a string. So if you pass in an emoji, the <code>icon</code> is returned. If you pass in an icon from the Ionicons library, the function will look out for the icon name and display that icon.</p>
<p>You need to modify the content of the <code>aside</code> element a bit so the icon will be rendered the correct way:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">aside</span>
 <span class="hljs-attr">class</span>=<span class="hljs-string">"callout-box"</span>
 <span class="hljs-attr">style</span>=<span class="hljs-string">{{backgroundColor,</span> <span class="hljs-attr">borderLeftColor</span>}}
 &gt;</span>
 <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"callout-icon-and-type"</span>&gt;</span>
   <span class="hljs-comment">&lt;!-- New icon renderer --&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">Fragment</span> <span class="hljs-attr">set:html</span>=<span class="hljs-string">{renderIcon(icon)}</span> /&gt;</span>
   {type}
 <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
 <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"callout-content"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">slot</span> /&gt;</span>
 <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">aside</span>&gt;</span>
</code></pre>
<p>If you're wondering what <code>set:html</code> is, it's an Astro template directory similar to the JavaScript <code>element.innerHTML</code>.</p>
<p>The <code>Fragment</code> component itself is a component you can use with the <code>set:*</code> directives to render HTML content.</p>
<p>Here's the CSS for the <code>Callout</code> component:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
 <span class="hljs-selector-class">.callout-box</span> {
   <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
   <span class="hljs-attribute">flex-direction</span>: column;
   <span class="hljs-attribute">padding</span>: <span class="hljs-number">1rem</span>;
   <span class="hljs-attribute">border-left-width</span>: <span class="hljs-number">4px</span>;
   <span class="hljs-attribute">border-left-style</span>: solid;
   <span class="hljs-attribute">margin</span>: <span class="hljs-number">1.5rem</span> <span class="hljs-number">0</span>;
   <span class="hljs-attribute">border-top-right-radius</span>: <span class="hljs-number">4px</span>;
   <span class="hljs-attribute">border-bottom-right-radius</span>: <span class="hljs-number">4px</span>;
 }

 <span class="hljs-selector-class">.callout-icon-and-type</span> {
   <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1.5rem</span>;
   <span class="hljs-attribute">display</span>: flex;
   <span class="hljs-attribute">gap</span>: <span class="hljs-number">0.4rem</span>;
 }

 <span class="hljs-selector-class">.icon</span> {
   <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">4rem</span>;
 }

 <span class="hljs-selector-class">.callout-content</span> {
   <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1.2rem</span>;
 }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
</code></pre>
<p>This will make more sense when we start using the parent <code>Callout</code> component in the child callout components.</p>
<h3 id="heading-how-to-build-the-child-callout-components">How to Build the Child Callout Components</h3>
<p>Let's demonstrate how to do this with a sample note callout box.</p>
<p>Create a <code>NoteCallout.astro</code> file inside the <code>components/callout</code> directory.</p>
<p>Import the parent <code>Callout</code> component inside the code fence of the <code>NoteCallout.astro</code> file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> CallOutBox <span class="hljs-keyword">from</span> <span class="hljs-string">"./Callout.astro"</span>;
</code></pre>
<p>To make things less confusing, you can rename CalloutBox to <code>NoteCalloutBox</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> NoteCallOutBox <span class="hljs-keyword">from</span> <span class="hljs-string">"./Callout.astro"</span>;
</code></pre>
<p>After that, use the <code>NoteCalloutBox</code> as a tag and pass ion all the props the parent <code>Callout</code> component accepts:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">NoteCallOutBox</span>
 <span class="hljs-attr">icon</span>=<span class="hljs-string">'&lt;ion-icon style="color: #3347ff;" size="large" name="information-circle"&gt;&lt;/ion-icon&gt;'</span>
 <span class="hljs-attr">type</span>=<span class="hljs-string">"Note"</span>
 <span class="hljs-attr">backgroundColor</span>=<span class="hljs-string">"#171d4f"</span>
 <span class="hljs-attr">borderLeftColor</span>=<span class="hljs-string">"#3347ff"</span>
&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">NoteCallOutBox</span>&gt;</span>
</code></pre>
<p>To account for the content of the NoteCalloutBox to be passed in when it's finally used, pass in <code>&lt;slot /&gt;</code> as the content of the <code>NoteCallOutBox</code>:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">NoteCallOutBox</span>
 <span class="hljs-attr">icon</span>=<span class="hljs-string">'&lt;ion-icon style="color: #3347ff;" size="large" name="information-circle"&gt;&lt;/ion-icon&gt;'</span>
 <span class="hljs-attr">type</span>=<span class="hljs-string">"Note"</span>
 <span class="hljs-attr">backgroundColor</span>=<span class="hljs-string">"#171d4f"</span>
 <span class="hljs-attr">borderLeftColor</span>=<span class="hljs-string">"#3347ff"</span>
&gt;</span>
 <span class="hljs-tag">&lt;<span class="hljs-name">slot</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">NoteCallOutBox</span>&gt;</span>
</code></pre>
<p>You can follow this process to create an error, caution, warning, and tip callout child components. All you need to do is to fill in the appropriate prop values.</p>
<h2 id="heading-how-to-use-the-callout-child-components">How to Use the Callout Child Components</h2>
<p>To use the child callout components in an MDX file for example, import the <code>NoteCallout</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> NoteCallout <span class="hljs-keyword">from</span> <span class="hljs-string">'../../components/callout/NoteCallout.astro'</span>;
</code></pre>
<p>Then use it as a tag and pass in the note you want to communicate to the user:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">NoteCallout</span>&gt;</span>
 You can only use this component in an MDX file, not a regular Markddown file
 with a .md extension.
<span class="hljs-tag">&lt;/<span class="hljs-name">NoteCallout</span>&gt;</span>
</code></pre>
<p>Here's the result in the browser:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728899862999/7c6624f9-5d29-44eb-b283-f57e31663ee8.png" alt="NoteCallout component" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Here are other child components I created using the same approach:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728899912952/5c19e264-fed6-483f-94b9-afd2b761424a.png" alt="Caution, Tip, Error, and Success Callout components" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I hope this article showed you everything you need to build a callout component for your blog.</p>
<p>Don’t forget that you can use the same technique to build a callout for a blog built with any other frontend framework.</p>
<p>If you find the article helpful, you can read more articles like it on <a target="_blank" href="https://www.koladechris.com/blog">my blog</a>. I also have articles on PHP, JavaScript, React, Python, and more.</p>
<p>Keep coding…</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ PHP Arrays in Practice: How to Rebuild the Football Team Cards Project with PHP and MongoDB ]]>
                </title>
                <description>
                    <![CDATA[ This is the second part of my PHP array handbook. You can find the first part here, where I cover array basics. In the first part, you learned about arrays, how to create arrays, array functions, and how to loop through arrays. This second part will ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/php-arrays-how-to-rebuild-the-football-team-cards-with-php-and-mongodb/</link>
                <guid isPermaLink="false">66adf1bf007ea266ef6d923b</guid>
                
                    <category>
                        <![CDATA[ arrays ]]>
                    </category>
                
                    <category>
                        <![CDATA[ handbook ]]>
                    </category>
                
                    <category>
                        <![CDATA[ MongoDB ]]>
                    </category>
                
                    <category>
                        <![CDATA[ PHP ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Tue, 18 Jun 2024 20:58:07 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/06/PHP-Arrays-in-Practice-Cover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>This is the second part of my PHP array handbook. You can <a target="_blank" href="https://www.freecodecamp.org/news/php-array-handbook/">find the first part here</a>, where I cover array basics.</p>
<p>In the first part, you learned about arrays, how to create arrays, array functions, and how to loop through arrays.</p>
<p>This second part will teach you how to use PHP and MongoDB to rebuild the football team cards project of freeCodeCamp's updated JavaScript curriculum.</p>
<p>The football team data will live in a MongDB Atlas database. We will fetch it as an array, and display it based on the players selected (goalkeepers, defenders, midfielders, and forwards).</p>
<p>This will help you build on top of what you learned about looping through arrays. After all, on many occassions, you'll be looping through what you get from a database or an API, not necessarily some hard-coded arrays.</p>
<p>In order not to shock you by jumping straight into databases from arrays, we'll start with what data and databases are, and then go on to learn about:</p>
<ul>
<li><p>Relational vs non-relational databases</p>
</li>
<li><p>How to use MongoDB Atlas</p>
</li>
<li><p>How to Install MongoDB for PHP on a Mac</p>
</li>
<li><p>How to set up MongoDB Atlas</p>
</li>
<li><p>How to build a CRUD app with PHP and MongoDB Atlas</p>
</li>
<li><p>And finally, how to rebuild the football team cards project with PHP and MongoDB Atlas</p>
</li>
</ul>
<h2 id="heading-pre-requisites">Pre-requisites</h2>
<p>To get the best put of this guide, I suggest you have a basic knowledge of the following:</p>
<ul>
<li><p>PHP fundamentals (variables, arrays, functions, loops)</p>
</li>
<li><p>HTML and CSS</p>
</li>
<li><p>JavaScript events</p>
</li>
<li><p>Command line</p>
</li>
<li><p>Composer</p>
</li>
<li><p>How to set up a PHP development environment with VS Code</p>
</li>
<li><p>Databases</p>
</li>
<li><p>MongoDB Atlas</p>
</li>
<li><p>Git and GitHub</p>
</li>
</ul>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-are-data-and-databases">What are Data and Databases?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-relational-vs-non-relational-databases">Relational vs Non-relational Databases</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-mongodb-atlas-an-example-of-a-non-relational-database">MongoDB Atlas – An Example of a Non-relational Database</a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-install-mongodb-for-php">How to Install MongoDB for PHP</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-step-1-install-the-mongodb-extension-with-pecl-php-extension-community-library">Step 1: Install the MongoDB Extension with PECL (PHP Extension Community Library)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-2-modify-the-phpini-file-to-include-the-mongodb-extension">Step 2: Modify the <code>php.ini</code> File to Include the MongoDB Extension</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-3-verify-the-installation-of-the-mongodb-extension">Step 3: Verify the Installation of the MongoDB Extension</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-4-set-up-a-mongodb-atlas-cluster">Step 4: Set Up a MongoDB Atlas Cluster</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-5-install-the-mongodb-php-library">Step 5: Install the MongoDB PHP Library</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-crud-operations-using-php-and-mongodb">CRUD Operations Using PHP and MongoDB</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-step-1-install-mongodb-library-and-dotenv-package">Step 1: Install MongoDB Library and Dotenv Package</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-2-create-a-env-file-for-your-mongodb-atlas-uri-credential">Step 2: Create a <code>.env</code> File for your MongoDB Atlas URI Credential</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-3-create-a-database-connection-file">Step 3: Create a Database Connection File</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-4-the-read-part-of-the-crud">Step 4: The <code>READ</code> Part of the CRUD</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-5-the-create-part-of-the-crud">Step 5: The <code>CREATE</code> Part of the CRUD</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-6-the-update-part-of-the-crud">Step 6: The <code>UPDATE</code> Part of the CRUD</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-7-the-delete-part-of-the-crud">Step 7: The <code>DELETE</code> Part of the CRUD</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-project-how-to-use-php-to-rebuild-the-football-team-cards-project-of-the-updated-javascript-curriculum">Project: How to Use PHP to Rebuild the Football Team Cards Project of the Updated JavaScript Curriculum</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-step-1-set-up-mongodb-atlas">Step 1: Set up MongoDB Atlas</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-2-install-the-project-dependencies-with-composer">Step 2: Install the Project Dependencies with Composer</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-3-create-project-files">Step 3: Create Project Files</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-4-wrap-the-select-tag-in-a-form-element">Step 4: Wrap the <code>select</code> tag in a <code>form</code> Element</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-5-create-the-logic-for-fetching-the-footballers-from-the-footballers-collection">Step 5: Create the Logic for Fetching the Footballers from the <code>footballers</code> Collection</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-6-create-the-logic-for-filtering-the-footballers-based-on-position">Step 6: Create the Logic for Filtering the Footballers Based on Position</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-7-display-the-players-on-the-page-based-on-the-selected-position">Step 7: Display the Players on the Page Based on the Selected Position</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-wrapping-up">Wrapping Up</a></p>
</li>
</ul>
<h2 id="heading-what-are-data-and-databases">What are Data and Databases?</h2>
<p>Data is central to pretty much everything in the modern world. The people you see on social media and other websites, the content they post, the comments they add to posts, and many other online activities all produce a lot of data. Even patient files in a hospital or a company's payroll hosted on a local server are data. Data does not have to be on the Internet.</p>
<p>To effectively manage and utilize data for growth, you need a <strong>database</strong>. A <strong>Database</strong> is a structured collection of data that helps you efficiently store, retrieve, and manipulate that data.</p>
<p>Databases come in two primary types – relational and non-relational databases. We'll discuss the differences between them next.</p>
<p>Both relational and non-relational databases are managed with what is called database management systems (DBMS). A DBMS is an interface between the user and the database that allows you to create, read, update, and delete data in the database.</p>
<h2 id="heading-relational-vs-non-relational-databases">Relational vs Non-relational Databases</h2>
<h3 id="heading-what-are-relational-databases">What are Relational Databases?</h3>
<p><strong>Relational databases</strong> organize data into tables consisting of rows and columns. Each table represents a specific entity, such as customers or products. The columns define the attributes of these entities, like the customer name or product name.</p>
<p>The relational model uses structured query language (SQL) for querying and managing data. Relationships between tables are established through primary and foreign keys to ensure data integrity and reduce redundancy.</p>
<p>Relational databases are known for their robustness, consistency, and support for complex queries. They are well-suited for applications that require multi-row transactions, such as financial systems, enterprise resource planning (ERP) software, and customer relationship management (CRM) systems.</p>
<p>Examples of relational databases are MySQL, PostgreSQL, and Microsoft SQL Server.</p>
<h3 id="heading-what-are-non-relational-databases">What are Non-Relational Databases?</h3>
<p><strong>Non-relational</strong> databases store and manage data in flexible, schema-less formats like key-value pairs, documents, wide-columns, or graphs. They are also known as NoSQL databases because they don't use SQL like relational databases.</p>
<p>Non-relational databases are designed to scale horizontally, making them ideal for large-scale data processing and real-time web applications.</p>
<p>Non-relational databases are easy to use, scalable, and high-performing at the same time. Due to that, they often sacrifice some degree of consistency in favor of availability and partition tolerance.</p>
<p>Common use cases include real-time analytics, real-time web apps, and applications requiring high-speed data ingestion.</p>
<h3 id="heading-mongodb-atlas-an-example-of-a-non-relational-database">MongoDB Atlas – An Example of a Non-relational Database</h3>
<p>MongoDB Atlas is a non-relational database that stores data in a document-oriented JSON-like format called BSON (Binary JSON). BSON extends the JSON model to provide additional data types and to be efficient for encoding and decoding within various programming languages.</p>
<p>MongoDB Atlas offers the flexibility and scalability of MongoDB, with the benefits of automated deployment, backups, and monitoring. It allows developers to focus on building applications without bothering about database management</p>
<p>MongoDB Atlas also supports advanced features such as data partitioning, replication, and global distribution. This makes it a powerful choice for modern applications requiring flexibility and performance.</p>
<h2 id="heading-how-to-install-mongodb-for-php">How to Install MongoDB for PHP</h2>
<p>Before you can install MongoDB for PHP, make sure you have PHP itself installed correctly.</p>
<p>On a Mac, you can install PHP with homebrew by running <code>brew install PHP</code>. In addition to that, make sure you have Apache installed by running <code>brew install httpd</code> and starting it by running <code>brew services start httpd</code>.</p>
<p>You can follow the steps below to install MongoDB for PHP on a Mac.</p>
<h3 id="heading-step-1-install-the-mongodb-extension-with-pecl-php-extension-community-library">Step 1: Install the MongoDB Extension with PECL (PHP Extension Community Library)</h3>
<p>Install the MongoDB extension for PHP by running <code>pecl install mongodb</code>.</p>
<h3 id="heading-step-2-modify-the-phpini-file-to-include-the-mongodb-extension">Step 2: Modify the <code>php.ini</code> File to Include the MongoDB Extension</h3>
<p>Installing the MongoDB extension should automatically add the necessary configurations to the <code>php.ini</code> file. But of it doesnt do that, locate the <code>php.ini</code> file by running the command below:</p>
<pre><code class="lang-bash">$ php --ini
Configuration File (php.ini) Path: /usr/<span class="hljs-built_in">local</span>/etc/php/8.3
</code></pre>
<p>After that, paste the following at the end of the <code>php.ini</code> file and save it:</p>
<pre><code class="lang-bash">extension=mongodb.so
</code></pre>
<p>After doing that, restart Apache by running <code>brew services restart httpd</code>.</p>
<h3 id="heading-step-3-verify-the-installation-of-the-mongodb-extension">Step 3: Verify the Installation of the MongoDB Extension</h3>
<p>Run the command below to see whether the PHP extension has been successflly installed:</p>
<pre><code class="lang-bash">php -i | grep mongo
</code></pre>
<p>You should see something like this in the terminal:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-05-24-at-09.21.50.png" alt="Screenshot-2024-05-24-at-09.21.50" width="600" height="400" loading="lazy"></p>
<p>Check out <a target="_blank" href="https://www.mongodb.com/docs/languages/php/">the MongoDB PHP docs</a> for more information on how to use MongoDB with PHP and frameworks like Laravel and Symfony.</p>
<h3 id="heading-step-4-set-up-a-mongodb-atlas-cluster">Step 4: Set Up a MongoDB Atlas Cluster</h3>
<p>To test out the PHP extension you just installed, you need a MongoDB database. Atlas makes this easy for you because the heavy lifting is handled on the cloud.</p>
<h4 id="heading-1-login-to-your-mongodb-account">1. Login to your MongoDB Account</h4>
<p>Head over to https://cloud.mongodb.com/ and log in to your account. If you don't have an account, <strong>you can create one for free</strong>.</p>
<h4 id="heading-2-create-a-project">2. Create a Project</h4>
<p>If you have existing projects, create a new project by clicking on the arrow right beside the currently opened project and selecting "New Project".</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-05-24-at-09.34.05.png" alt="Screenshot-2024-05-24-at-09.34.05" width="600" height="400" loading="lazy"></p>
<p>Give your project a name and click the "Next" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-05-24-at-09.37.13.png" alt="Screenshot-2024-05-24-at-09.37.13" width="600" height="400" loading="lazy"></p>
<p>Click "Create Project" to finally create the project.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-05-24-at-09.38.29.png" alt="Screenshot-2024-05-24-at-09.38.29" width="600" height="400" loading="lazy"></p>
<h4 id="heading-3-create-a-cluster">3. Create a Cluster</h4>
<p>After creating a project, you should be prompted to create a cluster. If you're not, make sure you're in the Overview tab. From there, click the big "Create" button:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/create-giant-1.png" alt="create-giant-1" width="600" height="400" loading="lazy"></p>
<p>Select the "MO" free tier, give your cluster a name, and click the "Create Deployment" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-05-24-at-09.44.11.png" alt="Screenshot-2024-05-24-at-09.44.11" width="600" height="400" loading="lazy"></p>
<p>I have given the cluster the name <code>movie-list</code>.</p>
<p>Just keep in mind that as your database grows, you might need to upgrade to one of the paid tiers.</p>
<h4 id="heading-4-create-a-database-user">4. Create a Database User</h4>
<p>Immediately after you create your cluster, you'll be prompted to create a database user. Fill in your database user username and password and click the "Create Database User" button. Then click "Choose a connection method".</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-05-24-at-09.50.54.png" alt="Screenshot-2024-05-24-at-09.50.54" width="600" height="400" loading="lazy"></p>
<p>Make sure you enter a password you can remember or save it in a password manager.</p>
<h4 id="heading-5-choose-a-connection-method">5. Choose a Connection Method</h4>
<p>You'll see several methods you can use to connect to the cluster once you click the "Choose a connection method" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-05-24-at-09.56.37.png" alt="Screenshot-2024-05-24-at-09.56.37" width="600" height="400" loading="lazy"></p>
<p>Select Drivers from the list.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-05-24-at-09.58.02.png" alt="Screenshot-2024-05-24-at-09.58.02" width="600" height="400" loading="lazy"></p>
<p>Choose PHP from the list and select PHP Lib 1.9 + MongoDB 1.10 or later as the version to use. Then copy the connection string and click the "Done" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-05-24-at-10.02.55.png" alt="Screenshot-2024-05-24-at-10.02.55" width="600" height="400" loading="lazy"></p>
<h4 id="heading-6-choose-network-access">6. Choose Network Access</h4>
<p>Head over to the "Network Access" tab and select "Add IP ADDRESS", click "ALLOW ACCESS FROM ANYWHERE", and then click the "Confirm" button. You can change this later depending on where your app is deployed.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-05-24-at-10.05.03.png" alt="Screenshot-2024-05-24-at-10.05.03" width="600" height="400" loading="lazy"></p>
<p>Go back to the "Database" tab and click the "Browse Collections" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-05-24-at-10.07.48.png" alt="Screenshot-2024-05-24-at-10.07.48" width="600" height="400" loading="lazy"></p>
<p>Select "Load a Sample Dataset" so you don't have to add your own data – at least for now.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-05-24-at-10.24.54.png" alt="Screenshot-2024-05-24-at-10.24.54" width="600" height="400" loading="lazy"></p>
<p>Now you should see the following databases:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-05-24-at-10.28.04.png" alt="Screenshot-2024-05-24-at-10.28.04" width="600" height="400" loading="lazy"></p>
<p>To test that your MongoDB extension for PHP is running, you can query any of the data in those databases. But first, you need to install the MongoDB PHP library with <code>composer</code>. <code>composer</code> lets you manage dependencies for your PHP project.</p>
<h3 id="heading-step-5-install-the-mongodb-php-library">Step 5: Install the MongoDB PHP Library</h3>
<p>If you don't have <code>composer</code> installed, install it with homebrew by running <code>brew install composer</code>.</p>
<p>After that, create a folder and open it with your Text Editor. If your Text Editor has an integrated terminal, open it and run the command below:</p>
<pre><code class="lang-bash">composer require mongodb/mongodb
</code></pre>
<p>If the installation is successful, you'll see a <code>vendor</code> folder, along with <code>composer.json</code> and <code>composer.lock</code> files in the root of your project. You'll also see the following in the terminal:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-05-24-at-10.36.29.png" alt="Screenshot-2024-05-24-at-10.36.29" width="600" height="400" loading="lazy"></p>
<p>Now you need to query any data in your atlas database and display them.</p>
<p>Create an <code>index.php</code> file and paste the following inside it:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">require_once</span> <span class="hljs-keyword">__DIR__</span> . <span class="hljs-string">'/vendor/autoload.php'</span>;

<span class="hljs-comment">// Your connection string</span>
$client = <span class="hljs-keyword">new</span> MongoDB\Client(
 <span class="hljs-string">'mongodb+srv://username:&lt;password&gt;@movie-list.s6r7qkr.mongodb.net/?retryWrites=true&amp;w=majority&amp;appName=movie-list'</span>
);

$movies = $client-&gt;selectCollection(<span class="hljs-string">'sample_mflix'</span>, <span class="hljs-string">'movies'</span>);
$document = $movies-&gt;findOne([<span class="hljs-string">'title'</span> =&gt; <span class="hljs-string">'Wild and Woolly'</span>]);

<span class="hljs-keyword">echo</span> <span class="hljs-string">'&lt;pre&gt;'</span>;
print_r($document);
</code></pre>
<p>The code above lets you connect to the <code>movies</code> database in the <code>sample_mflix</code> collection with the <code>selectCollection()</code> function and query a movie titled "Wild and Bolly" in it.</p>
<p><strong>Note</strong>: Make sure you replace the existing connection string with your own. You copied this in item 5 of step 4. Also, make sure you replace <code>&lt;password&gt;</code> with your database user password.</p>
<p>After that, run your PHP app (with <code>php -S localhost:8000</code> on Mac in the terminal). If you have everything set up correctly, you should see the following in the browser:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-05-24-at-10.54.05.png" alt="Screenshot-2024-05-24-at-10.54.05" width="600" height="400" loading="lazy"></p>
<p><strong>Note</strong>: I have the data formatted nicely because I installed the PHP View Chrome extension. It prints everything you have inside the <code>print_r()</code> function like that.</p>
<h2 id="heading-crud-operations-using-php-and-mongodb">CRUD Operations Using PHP and MongoDB</h2>
<p>With MongoDB Atlas for database management and UI persistence, and PHP for server-side logic, you can build an application that implements full CRUD operations – create, read, update, and delete.</p>
<p>The particular CRUD app we are building is a movie list. So make sure you set up an Atlas database for it, as we already covered in this guide.</p>
<p>Now let's look at how you can build a movie list CRUD app.</p>
<h3 id="heading-step-1-install-mongodb-library-and-dotenv-package">Step 1: Install MongoDB Library and Dotenv Package</h3>
<p>Make sure you have a MongoDB extension and a Dotenv package to help manage your <code>.env</code> variables by running the following commands:</p>
<pre><code class="lang-bash">composer require mongodb/mongodb
composer require vlucas/phpdotenv
</code></pre>
<h3 id="heading-step-2-create-a-env-file-for-your-mongodb-atlas-uri-credential">Step 2: Create a <code>.env</code> File for your MongoDB Atlas URI Credential</h3>
<p>Create a <code>.env</code> file and add the following in it:</p>
<pre><code class="lang-md">MDB<span class="hljs-emphasis">_URI="Your MongoDB Atlas connection string"</span>
</code></pre>
<h3 id="heading-step-3-create-a-database-connection-file">Step 3: Create a Database Connection File</h3>
<p>Create a <code>mongo_atlas_setup.php</code> file for the database connection in the root and paste the following in it:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
<span class="hljs-keyword">require_once</span> <span class="hljs-keyword">__DIR__</span> . <span class="hljs-string">'/vendor/autoload.php'</span>;

$dotenv = Dotenv\Dotenv::createImmutable(<span class="hljs-keyword">__DIR__</span>);
$dotenv-&gt;load();

$client = <span class="hljs-keyword">new</span> MongoDB\Client($_ENV[<span class="hljs-string">'MDB_URI'</span>]);

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getMongoClient</span>(<span class="hljs-params"></span>)
</span>{
 <span class="hljs-keyword">global</span> $client;
 <span class="hljs-keyword">return</span> $client;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getMongoCollection</span>(<span class="hljs-params">$database, $collection</span>)
</span>{
 $client = getMongoClient();
 <span class="hljs-keyword">return</span> $client-&gt;selectCollection($database, $collection);
}
</code></pre>
<p>With the code above, we are:</p>
<ul>
<li><p>loading the dependencies required for the project</p>
</li>
<li><p>loading the environment variable</p>
</li>
<li><p>using a function to get the database and the collection we want within it</p>
</li>
</ul>
<p>Importing the file and calling the <code>getMongoCollection</code> in it with the database and the collection in it will let you connect to the database and the collection.</p>
<h3 id="heading-step-4-the-read-part-of-the-crud">Step 4: The <code>READ</code> Part of the CRUD</h3>
<p>In the root again, create an <code>index.php</code> file that will take care of the READ part of the CRUD. Paste the following in the file:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">require_once</span> <span class="hljs-keyword">__DIR__</span> . <span class="hljs-string">'/vendor/autoload.php'</span>;
<span class="hljs-keyword">require_once</span> <span class="hljs-keyword">__DIR__</span> . <span class="hljs-string">'/mongo_atlas_setup.php'</span>;

$movies_list = getMongoCollection(<span class="hljs-string">'movie_list'</span>, <span class="hljs-string">'movies'</span>);
$movies = $movies_list-&gt;find([], [<span class="hljs-string">'sort'</span> =&gt; [<span class="hljs-string">'_id'</span> =&gt; <span class="hljs-number">-1</span>]]);
<span class="hljs-meta">?&gt;</span>

&lt;!DOCTYPE html&gt;
&lt;html lang=<span class="hljs-string">"en"</span>&gt;

&lt;head&gt;
 &lt;meta charset=<span class="hljs-string">"UTF-8"</span>&gt;
 &lt;meta name=<span class="hljs-string">"viewport"</span> content=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;
 &lt;title&gt;Movie <span class="hljs-keyword">List</span> CRUD App&lt;/title&gt;
 &lt;script src=<span class="hljs-string">"https://cdn.tailwindcss.com"</span>&gt;&lt;/script&gt;
&lt;/head&gt;

&lt;body <span class="hljs-class"><span class="hljs-keyword">class</span>="<span class="hljs-title">bg</span>-<span class="hljs-title">gray</span>-100 <span class="hljs-title">p</span>-10"&gt;

 &lt;<span class="hljs-title">div</span> <span class="hljs-title">class</span>="<span class="hljs-title">max</span>-<span class="hljs-title">w</span>-4<span class="hljs-title">xl</span> <span class="hljs-title">mx</span>-<span class="hljs-title">auto</span> <span class="hljs-title">bg</span>-<span class="hljs-title">white</span> <span class="hljs-title">p</span>-6 <span class="hljs-title">rounded</span> <span class="hljs-title">shadow</span>"&gt;
   &lt;<span class="hljs-title">h1</span> <span class="hljs-title">class</span>="<span class="hljs-title">text</span>-3<span class="hljs-title">xl</span> <span class="hljs-title">font</span>-<span class="hljs-title">bold</span> <span class="hljs-title">mb</span>-4 <span class="hljs-title">text</span>-<span class="hljs-title">center</span>"&gt;<span class="hljs-title">Movie</span> <span class="hljs-title">List</span> <span class="hljs-title">CRUD</span> <span class="hljs-title">App</span>&lt;/<span class="hljs-title">h1</span>&gt;

   &lt;?<span class="hljs-title">php</span> <span class="hljs-title">include</span> '<span class="hljs-title">create</span>.<span class="hljs-title">php</span>' ?&gt;

   &lt;<span class="hljs-title">div</span> <span class="hljs-title">class</span>="<span class="hljs-title">space</span>-<span class="hljs-title">y</span>-4"&gt;
     &lt;?<span class="hljs-title">php</span> <span class="hljs-title">foreach</span> ($<span class="hljs-title">movies</span> <span class="hljs-title">as</span> $<span class="hljs-title">movie</span>) : ?&gt;
       &lt;<span class="hljs-title">div</span> <span class="hljs-title">class</span>="<span class="hljs-title">p</span>-4 <span class="hljs-title">border</span> <span class="hljs-title">rounded</span> <span class="hljs-title">shadow</span>-<span class="hljs-title">sm</span> <span class="hljs-title">bg</span>-<span class="hljs-title">gray</span>-50"&gt;
         &lt;<span class="hljs-title">h2</span> <span class="hljs-title">class</span>="<span class="hljs-title">text</span>-2<span class="hljs-title">xl</span> <span class="hljs-title">font</span>-<span class="hljs-title">semibold</span>"&gt;&lt;?= $<span class="hljs-title">movie</span>['<span class="hljs-title">movie_title</span>'] ?&gt;&lt;/<span class="hljs-title">h2</span>&gt;
         &lt;<span class="hljs-title">p</span> <span class="hljs-title">class</span>="<span class="hljs-title">text</span>-<span class="hljs-title">gray</span>-700"&gt;<span class="hljs-title">Year</span>: &lt;?= $<span class="hljs-title">movie</span>['<span class="hljs-title">movie_year</span>'] ?&gt;&lt;/<span class="hljs-title">p</span>&gt;
         &lt;<span class="hljs-title">div</span> <span class="hljs-title">class</span>="<span class="hljs-title">mt</span>-2"&gt;
           &lt;<span class="hljs-title">a</span> <span class="hljs-title">href</span>="<span class="hljs-title">update</span>.<span class="hljs-title">php</span>?<span class="hljs-title">id</span>=&lt;?= $<span class="hljs-title">movie</span>['<span class="hljs-title">_id</span>'] ?&gt;" <span class="hljs-title">class</span>="<span class="hljs-title">bg</span>-<span class="hljs-title">yellow</span>-500 <span class="hljs-title">text</span>-<span class="hljs-title">white</span> <span class="hljs-title">py</span>-1 <span class="hljs-title">px</span>-3 <span class="hljs-title">rounded</span>"&gt;<span class="hljs-title">Update</span>&lt;/<span class="hljs-title">a</span>&gt;
           &lt;<span class="hljs-title">a</span> <span class="hljs-title">href</span>="<span class="hljs-title">delete</span>.<span class="hljs-title">php</span>?<span class="hljs-title">id</span>=&lt;?= $<span class="hljs-title">movie</span>['<span class="hljs-title">_id</span>'] ?&gt;" <span class="hljs-title">onclick</span>="<span class="hljs-title">return</span> <span class="hljs-title">confirm</span>('<span class="hljs-title">Are</span> <span class="hljs-title">you</span> <span class="hljs-title">sure</span> <span class="hljs-title">you</span> <span class="hljs-title">want</span> <span class="hljs-title">to</span> <span class="hljs-title">delete</span> <span class="hljs-title">this</span> <span class="hljs-title">movie</span>?')" <span class="hljs-title">class</span>="<span class="hljs-title">bg</span>-<span class="hljs-title">red</span>-500 <span class="hljs-title">text</span>-<span class="hljs-title">white</span> <span class="hljs-title">py</span>-1 <span class="hljs-title">px</span>-3 <span class="hljs-title">rounded</span>"&gt;<span class="hljs-title">Delete</span>&lt;/<span class="hljs-title">a</span>&gt;
         &lt;/<span class="hljs-title">div</span>&gt;
       &lt;/<span class="hljs-title">div</span>&gt;
     &lt;?<span class="hljs-title">php</span> <span class="hljs-title">endforeach</span> ?&gt;
   &lt;/<span class="hljs-title">div</span>&gt;
 &lt;/<span class="hljs-title">div</span>&gt;

&lt;/<span class="hljs-title">body</span>&gt;

&lt;/<span class="hljs-title">html</span>&gt;</span>
</code></pre>
<p>Notice that there are the Update and Delete linking to an <code>update.php</code> and a <code>delete.php</code> files with the id of the movie clicked. That way, we will know which movie is clicked in order to update or delete it. There's also an include statement for a <code>create.php</code> file.</p>
<p>For now, you can go ahead and create the <code>create.php</code>, <code>update.php</code>, and <code>delete.php</code> files in the root.</p>
<p>At this point, you won't see anything in the UI yet because you need to handle the creation functionality.</p>
<h3 id="heading-step-5-the-create-part-of-the-crud">Step 5: The <code>CREATE</code> Part of the CRUD</h3>
<p>Create a <code>create.php</code> file in the root (if you haven't already) and paste in the following:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
<span class="hljs-keyword">require_once</span> <span class="hljs-keyword">__DIR__</span> . <span class="hljs-string">'/mongo_atlas_setup.php'</span>;

<span class="hljs-keyword">if</span> ($_SERVER[<span class="hljs-string">'REQUEST_METHOD'</span>] === <span class="hljs-string">'POST'</span>) {
 $movies = getMongoCollection(<span class="hljs-string">'movie_list'</span>, <span class="hljs-string">'movies'</span>);
 $newMovie = [
   <span class="hljs-string">'movie_title'</span> =&gt; $_POST[<span class="hljs-string">'movie-title'</span>],
   <span class="hljs-string">'movie_year'</span> =&gt; (<span class="hljs-keyword">int</span>)$_POST[<span class="hljs-string">'movie-year'</span>],
 ];
 $result = $movies-&gt;insertOne($newMovie);
 <span class="hljs-keyword">if</span> ($result-&gt;getInsertedCount() === <span class="hljs-number">1</span>) {
   <span class="hljs-comment">// echo "Movie created successfully!";</span>
   header(<span class="hljs-string">'Location: '</span> . <span class="hljs-string">'/'</span>);
 } <span class="hljs-keyword">else</span> {
   <span class="hljs-keyword">echo</span> <span class="hljs-string">"Failed to create movie"</span>;
 }
}
<span class="hljs-meta">?&gt;</span>

&lt;form method=<span class="hljs-string">"POST"</span> action=<span class="hljs-string">"create.php"</span> <span class="hljs-class"><span class="hljs-keyword">class</span>="<span class="hljs-title">space</span>-<span class="hljs-title">y</span>-4 <span class="hljs-title">mb</span>-6"&gt;
 &lt;<span class="hljs-title">div</span>&gt;
   &lt;<span class="hljs-title">label</span> <span class="hljs-title">class</span>="<span class="hljs-title">block</span> <span class="hljs-title">text</span>-<span class="hljs-title">gray</span>-700"&gt;<span class="hljs-title">Movie</span> <span class="hljs-title">Title</span>&lt;/<span class="hljs-title">label</span>&gt;
   &lt;<span class="hljs-title">input</span> <span class="hljs-title">type</span>="<span class="hljs-title">text</span>" <span class="hljs-title">name</span>="<span class="hljs-title">movie</span>-<span class="hljs-title">title</span>" <span class="hljs-title">required</span> <span class="hljs-title">class</span>="<span class="hljs-title">w</span>-<span class="hljs-title">full</span> <span class="hljs-title">p</span>-2 <span class="hljs-title">border</span> <span class="hljs-title">rounded</span> <span class="hljs-title">max</span>-<span class="hljs-title">w</span>-<span class="hljs-title">md</span>"&gt;
 &lt;/<span class="hljs-title">div</span>&gt;
 &lt;<span class="hljs-title">div</span>&gt;
   &lt;<span class="hljs-title">label</span> <span class="hljs-title">class</span>="<span class="hljs-title">block</span> <span class="hljs-title">text</span>-<span class="hljs-title">gray</span>-700"&gt;<span class="hljs-title">Movie</span> <span class="hljs-title">Year</span>&lt;/<span class="hljs-title">label</span>&gt;
   &lt;<span class="hljs-title">input</span> <span class="hljs-title">type</span>="<span class="hljs-title">text</span>" <span class="hljs-title">name</span>="<span class="hljs-title">movie</span>-<span class="hljs-title">year</span>" <span class="hljs-title">required</span> <span class="hljs-title">class</span>="<span class="hljs-title">w</span>-<span class="hljs-title">full</span> <span class="hljs-title">p</span>-2 <span class="hljs-title">border</span> <span class="hljs-title">rounded</span> <span class="hljs-title">max</span>-<span class="hljs-title">w</span>-<span class="hljs-title">md</span>"&gt;
 &lt;/<span class="hljs-title">div</span>&gt;
 &lt;<span class="hljs-title">button</span> <span class="hljs-title">type</span>="<span class="hljs-title">submit</span>" <span class="hljs-title">class</span>="<span class="hljs-title">bg</span>-<span class="hljs-title">green</span>-500 <span class="hljs-title">text</span>-<span class="hljs-title">white</span> <span class="hljs-title">py</span>-2 <span class="hljs-title">px</span>-4 <span class="hljs-title">rounded</span>"&gt;<span class="hljs-title">Create</span>&lt;/<span class="hljs-title">button</span>&gt;
&lt;/<span class="hljs-title">form</span>&gt;</span>
</code></pre>
<p>The code above contains the form and input elements for creating a movie. We are then using the name attributes in those input elements to create the <code>POST</code> request that will let us create a movie and save it in the <code>movies</code> collection of a <code>movie_list</code> database.</p>
<h3 id="heading-step-6-the-update-part-of-the-crud">Step 6: The <code>UPDATE</code> Part of the CRUD</h3>
<p>To handle the updating, we need to create a separate file and do something similar to how the movie creation worked. The exeception is that we are going to use the id (<code>_id</code>) field to determine whether the movie exists and then update it instead of creating a fresh one.</p>
<p>To do that, create an <code>update.php</code> file (if you haven't already) in the root and paste in the following:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
<span class="hljs-keyword">require_once</span> <span class="hljs-keyword">__DIR__</span> . <span class="hljs-string">'/vendor/autoload.php'</span>;
<span class="hljs-keyword">require_once</span> <span class="hljs-keyword">__DIR__</span> . <span class="hljs-string">'/mongo_atlas_setup.php'</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">MongoDB</span>\<span class="hljs-title">BSON</span>\<span class="hljs-title">ObjectId</span>;

$movies_list = getMongoCollection(<span class="hljs-string">'movie_list'</span>, <span class="hljs-string">'movies'</span>);
$title = <span class="hljs-string">''</span>;
$year = <span class="hljs-string">''</span>;

<span class="hljs-keyword">if</span> ($_SERVER[<span class="hljs-string">'REQUEST_METHOD'</span>] === <span class="hljs-string">'POST'</span>) {
 $filter = [<span class="hljs-string">'_id'</span> =&gt; <span class="hljs-keyword">new</span> ObjectId($_POST[<span class="hljs-string">'id'</span>])];

 $update = [<span class="hljs-string">'$set'</span> =&gt; [
   <span class="hljs-string">'movie_title'</span> =&gt; $_POST[<span class="hljs-string">'movie-title'</span>],
   <span class="hljs-string">'movie_year'</span> =&gt; (<span class="hljs-keyword">int</span>)$_POST[<span class="hljs-string">'movie-year'</span>],
 ]];

 $result = $movies_list-&gt;updateOne($filter, $update);

 <span class="hljs-keyword">if</span> ($result-&gt;getModifiedCount() === <span class="hljs-number">1</span>) {
   <span class="hljs-comment">// echo "Movie updated successfully!";</span>
   header(<span class="hljs-string">'Location: '</span> . <span class="hljs-string">'/'</span>);
 } <span class="hljs-keyword">else</span> {
   <span class="hljs-keyword">echo</span> <span class="hljs-string">"Failed to update movie."</span>;
 }
} <span class="hljs-keyword">else</span> {
 <span class="hljs-keyword">if</span> (<span class="hljs-keyword">isset</span>($_GET[<span class="hljs-string">'id'</span>])) {
   $id = $_GET[<span class="hljs-string">'id'</span>];
   $movie = $movies_list-&gt;findOne([<span class="hljs-string">'_id'</span> =&gt; <span class="hljs-keyword">new</span> ObjectId($id)]);
   <span class="hljs-keyword">if</span> ($movie) {
     $title = $movie[<span class="hljs-string">'movie_title'</span>];
     $year = $movie[<span class="hljs-string">'movie_year'</span>];
   } <span class="hljs-keyword">else</span> {
     <span class="hljs-keyword">echo</span> <span class="hljs-string">"Movie not found."</span>;
     <span class="hljs-keyword">exit</span>;
   }
 } <span class="hljs-keyword">else</span> {
   <span class="hljs-keyword">echo</span> <span class="hljs-string">"No movie ID provided."</span>;
   <span class="hljs-keyword">exit</span>;
 }
}
<span class="hljs-meta">?&gt;</span>

&lt;!DOCTYPE html&gt;
&lt;html lang=<span class="hljs-string">"en"</span>&gt;

&lt;head&gt;
 &lt;meta charset=<span class="hljs-string">"UTF-8"</span>&gt;
 &lt;meta name=<span class="hljs-string">"viewport"</span> content=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;
 &lt;script src=<span class="hljs-string">"https://cdn.tailwindcss.com"</span>&gt;&lt;/script&gt;
 &lt;title&gt;Update Movie &lt;/title&gt;
&lt;/head&gt;

&lt;body <span class="hljs-class"><span class="hljs-keyword">class</span>="<span class="hljs-title">bg</span>-<span class="hljs-title">gray</span>-100 <span class="hljs-title">p</span>-10"&gt;

 &lt;<span class="hljs-title">div</span> <span class="hljs-title">class</span>="<span class="hljs-title">max</span>-<span class="hljs-title">w</span>-4<span class="hljs-title">xl</span> <span class="hljs-title">mx</span>-<span class="hljs-title">auto</span> <span class="hljs-title">bg</span>-<span class="hljs-title">white</span> <span class="hljs-title">p</span>-6 <span class="hljs-title">rounded</span> <span class="hljs-title">shadow</span>"&gt;
   &lt;<span class="hljs-title">h1</span> <span class="hljs-title">class</span>="<span class="hljs-title">text</span>-3<span class="hljs-title">xl</span> <span class="hljs-title">font</span>-<span class="hljs-title">bold</span> <span class="hljs-title">mb</span>-4"&gt;<span class="hljs-title">Update</span> &lt;?= $<span class="hljs-title">title</span> ?&gt; &lt;/<span class="hljs-title">h1</span>&gt;

   &lt;<span class="hljs-title">form</span> <span class="hljs-title">method</span>="<span class="hljs-title">POST</span>" <span class="hljs-title">action</span>="<span class="hljs-title">update</span>.<span class="hljs-title">php</span>" <span class="hljs-title">class</span>="<span class="hljs-title">space</span>-<span class="hljs-title">y</span>-4"&gt;
     &lt;<span class="hljs-title">input</span> <span class="hljs-title">type</span>="<span class="hljs-title">hidden</span>" <span class="hljs-title">name</span>="<span class="hljs-title">id</span>" <span class="hljs-title">value</span>="&lt;?<span class="hljs-title">php</span> <span class="hljs-title">echo</span> $<span class="hljs-title">id</span>; ?&gt;"&gt;

     &lt;<span class="hljs-title">div</span>&gt;
       &lt;<span class="hljs-title">label</span> <span class="hljs-title">class</span>="<span class="hljs-title">block</span> <span class="hljs-title">text</span>-<span class="hljs-title">gray</span>-700"&gt;<span class="hljs-title">Title</span>&lt;/<span class="hljs-title">label</span>&gt;
       &lt;<span class="hljs-title">input</span> <span class="hljs-title">type</span>="<span class="hljs-title">text</span>" <span class="hljs-title">name</span>="<span class="hljs-title">movie</span>-<span class="hljs-title">title</span>" <span class="hljs-title">value</span>="&lt;?= <span class="hljs-title">htmlspecialchars</span>($<span class="hljs-title">title</span>); ?&gt;" <span class="hljs-title">required</span> <span class="hljs-title">class</span>="<span class="hljs-title">w</span>-<span class="hljs-title">full</span> <span class="hljs-title">p</span>-2 <span class="hljs-title">border</span> <span class="hljs-title">rounded</span>" /&gt;
     &lt;/<span class="hljs-title">div</span>&gt;

     &lt;<span class="hljs-title">div</span>&gt;
       &lt;<span class="hljs-title">label</span> <span class="hljs-title">class</span>="<span class="hljs-title">block</span> <span class="hljs-title">text</span>-<span class="hljs-title">gray</span>-700"&gt;<span class="hljs-title">Release</span> <span class="hljs-title">Year</span>&lt;/<span class="hljs-title">label</span>&gt;
       &lt;<span class="hljs-title">input</span> <span class="hljs-title">type</span>="<span class="hljs-title">number</span>" <span class="hljs-title">name</span>="<span class="hljs-title">movie</span>-<span class="hljs-title">year</span>" <span class="hljs-title">value</span>="&lt;?= <span class="hljs-title">htmlspecialchars</span>($<span class="hljs-title">year</span>); ?&gt;" <span class="hljs-title">required</span> <span class="hljs-title">class</span>="<span class="hljs-title">w</span>-<span class="hljs-title">full</span> <span class="hljs-title">p</span>-2 <span class="hljs-title">border</span> <span class="hljs-title">rounded</span>" /&gt;
     &lt;/<span class="hljs-title">div</span>&gt;

     &lt;<span class="hljs-title">button</span> <span class="hljs-title">class</span>=" <span class="hljs-title">bg</span>-<span class="hljs-title">green</span>-500 <span class="hljs-title">text</span>-<span class="hljs-title">white</span> <span class="hljs-title">py</span>-2 <span class="hljs-title">px</span>-4 <span class="hljs-title">rounded</span>" <span class="hljs-title">type</span>="<span class="hljs-title">submit</span>"&gt;<span class="hljs-title">Update</span>&lt;/<span class="hljs-title">button</span>&gt;
   &lt;/<span class="hljs-title">form</span>&gt;

   &lt;<span class="hljs-title">div</span> <span class="hljs-title">class</span>="<span class="hljs-title">mt</span>-4"&gt;
     &lt;<span class="hljs-title">a</span> <span class="hljs-title">href</span>="<span class="hljs-title">index</span>.<span class="hljs-title">php</span>" <span class="hljs-title">class</span>="<span class="hljs-title">bg</span>-<span class="hljs-title">gray</span>-500 <span class="hljs-title">text</span>-<span class="hljs-title">white</span> <span class="hljs-title">py</span>-2 <span class="hljs-title">px</span>-4 <span class="hljs-title">rounded</span>"&gt;<span class="hljs-title">Back</span> <span class="hljs-title">to</span> <span class="hljs-title">List</span>&lt;/<span class="hljs-title">a</span>&gt;
   &lt;/<span class="hljs-title">div</span>&gt;
 &lt;/<span class="hljs-title">div</span>&gt;

&lt;/<span class="hljs-title">body</span>&gt;

&lt;/<span class="hljs-title">html</span>&gt;</span>
</code></pre>
<h3 id="heading-step-7-the-delete-part-of-the-crud">Step 7: The <code>DELETE</code> Part of the CRUD</h3>
<p>To handle the delete functionality, we can get the movie and use the <code>deleteOne</code> function provided by MongoDB to delete it. Once the deleting is done, we will then use the <code>header()</code> function again to redirect to the home page.</p>
<p>Paste the following code in your <code>delete.php</code> file:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
<span class="hljs-keyword">require_once</span> <span class="hljs-keyword">__DIR__</span> . <span class="hljs-string">'/mongo_atlas_setup.php'</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">MongoDB</span>\<span class="hljs-title">BSON</span>\<span class="hljs-title">ObjectId</span>;

<span class="hljs-keyword">if</span> ($_SERVER[<span class="hljs-string">'REQUEST_METHOD'</span>] === <span class="hljs-string">'GET'</span> &amp;&amp; <span class="hljs-keyword">isset</span>($_GET[<span class="hljs-string">'id'</span>])) {
 $movies = getMongoCollection(<span class="hljs-string">'movie_list'</span>, <span class="hljs-string">'movies'</span>);
 $filter = [<span class="hljs-string">'_id'</span> =&gt; <span class="hljs-keyword">new</span> ObjectId($_GET[<span class="hljs-string">'id'</span>])];
 $result = $movies-&gt;deleteOne($filter);
 <span class="hljs-keyword">if</span> ($result-&gt;getDeletedCount() === <span class="hljs-number">1</span>) {
   <span class="hljs-comment">// echo "Movie deleted successfully!";</span>
   header(<span class="hljs-string">'Location: '</span> . <span class="hljs-string">'/'</span>);
 } <span class="hljs-keyword">else</span> {
   <span class="hljs-keyword">echo</span> <span class="hljs-string">"Failed to delete movie."</span>;
 }
} <span class="hljs-keyword">else</span> {
 <span class="hljs-keyword">echo</span> <span class="hljs-string">"No movie provided."</span>;
}
<span class="hljs-meta">?&gt;</span>
</code></pre>
<p>This is what the CRUD app should look like now:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/CRUD-gif.gif" alt="CRUD-gif" width="600" height="400" loading="lazy"></p>
<p>All the code is in this <a target="_blank" href="https://github.com/Ksound22/crud-app-for-php-fcc-article">GitHub repo</a></p>
<h2 id="heading-project-how-to-use-php-to-rebuild-the-football-team-cards-project-of-the-updated-javascript-curriculum">Project: How to Use PHP to Rebuild the Football Team Cards Project of the Updated JavaScript Curriculum</h2>
<p>Before you start going through the steps to build the project, grab the starter code for the project in <a target="_blank" href="https://github.com/Ksound22/football-team-cards-php-rebuild">the starter branch of this GitHub repo</a>.</p>
<p>You can also take a look at <a target="_blank" href="https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures-v8/learn-modern-javascript-methods-by-building-football-team-cards/step-1">the football team cards project</a> to know what we are trying to achieve.</p>
<h3 id="heading-step-1-set-up-mongodb-atlas">Step 1: Set up MongoDB Atlas</h3>
<p>Log in to your MongoDB Atlas account and create a <code>football-team-cards</code> database. Feel free to create it in an existing project or a new one if you want. In the <code>football-team-cards</code> database, create a <code>footballers</code> collection.</p>
<p>In the <code>footballers</code> collection, click the "INSERT DOCUMENT" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-06-09-at-14.33.15.png" alt="Screenshot-2024-06-09-at-14.33.15" width="600" height="400" loading="lazy"></p>
<p>Then paste in the content of the <code>footballers.json</code> file in the starter branch of the project GitHub repo and click "Done".</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-06-09-at-14.42.47.png" alt="Screenshot-2024-06-09-at-14.42.47" width="600" height="400" loading="lazy"></p>
<p>After that, your <code>footballers</code> collection should look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-06-09-at-14.44.59.png" alt="Screenshot-2024-06-09-at-14.44.59" width="600" height="400" loading="lazy"></p>
<h3 id="heading-step-2-install-the-project-dependencies-with-composer">Step 2: Install the Project Dependencies with Composer</h3>
<p>Create a <code>football-team-cards-php</code> folder on your computer and open it with your favorite text editor. Open the same folder in your terminal and run the following commands:</p>
<pre><code class="lang-bash">composer require vlucas/phpdotenv 
composer require mongodb/mongodb
</code></pre>
<h3 id="heading-step-3-create-project-files">Step 3: Create Project Files</h3>
<p>Inside the <code>football-team-cards-php</code> folder, create the following files:</p>
<ul>
<li><p><code>.env</code></p>
</li>
<li><p><code>mongo_atlas_php_setup.php</code></p>
</li>
<li><p><code>index.php</code></p>
</li>
<li><p><code>styles.css</code></p>
</li>
</ul>
<p>In the <code>.env</code> file, you should have the MongoDB Atlas URI:</p>
<pre><code class="lang-bash">MDB_URI=<span class="hljs-string">"Your MongoDB Atlas connection string"</span>
</code></pre>
<p>In the <code>mongo_atlas_php_setup.php</code> file, you should connect to the database with this code:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
<span class="hljs-keyword">require_once</span> <span class="hljs-keyword">__DIR__</span> . <span class="hljs-string">'/vendor/autoload.php'</span>;
$dotenv = Dotenv\Dotenv::createImmutable(<span class="hljs-keyword">__DIR__</span>);
$dotenv-&gt;load();


<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getMongoClient</span>(<span class="hljs-params"></span>)
</span>{
 <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> MongoDB\Client($_ENV[<span class="hljs-string">'MDB_URI'</span>]);
}


<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getMongoCollection</span>(<span class="hljs-params">$database, $collection</span>)
</span>{
 $client = getMongoClient();
 <span class="hljs-keyword">return</span> $client-&gt;selectCollection($database, $collection);
}
</code></pre>
<p>In the code above, we are loading the environment variables and using a <code>getMongCollection</code> function to connect the database. Make sure you replace the connection string with your own.</p>
<p>Now, anytime you want to connect to a database, require the file, then pass the database and the collection names to the <code>getMongoCollection</code> function.</p>
<p>Copy the content of the <code>index.html</code> and <code>styles.css</code> files in the starter branch of the project GitHub repo and paste them into your <code>index.php</code> and <code>styles.css</code> files.</p>
<h3 id="heading-step-4-wrap-the-select-tag-in-a-form-element">Step 4: Wrap the <code>select</code> tag in a <code>form</code> Element</h3>
<p>Replace the existing <code>select</code> tag with the following:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"POST"</span> <span class="hljs-attr">action</span>=<span class="hljs-string">""</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"options-label"</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"players"</span>&gt;</span>Filter Teammates:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">select</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"position"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"players"</span> <span class="hljs-attr">onchange</span>=<span class="hljs-string">"this.form.submit()"</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"all"</span>&gt;</span>All Players<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"nickname"</span>&gt;</span>Nicknames<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"forward"</span>&gt;</span>Position Forward<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"midfielder"</span>&gt;</span>Position Midfielder<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"defender"</span>&gt;</span>Position Defender<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"goalkeeper"</span>&gt;</span>Position Goalkeeper<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
     <span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<p>This will let you make a <code>POST</code> request with the <code>name</code> attribute set to <code>position</code>. And with the <code>onchange</code> attribute of <code>this.form.submit()</code>, you'll be able to fetch footballers based on any of the options selected. More on this later.</p>
<h3 id="heading-step-5-create-the-logic-for-fetching-the-footballers-from-the-footballers-collection">Step 5: Create the Logic for Fetching the Footballers from the <code>footballers</code> Collection</h3>
<pre><code class="lang-php"><span class="hljs-keyword">require_once</span> <span class="hljs-keyword">__DIR__</span> . <span class="hljs-string">'/mongo_atlas_php_setup.php'</span>;

$position = <span class="hljs-keyword">isset</span>($_POST[<span class="hljs-string">'position'</span>]) ? $_POST[<span class="hljs-string">'position'</span>] : <span class="hljs-string">'all'</span>;

$collection = getMongoCollection(<span class="hljs-string">'football-team-cards'</span>, <span class="hljs-string">'footballers'</span>);
$team = $collection-&gt;findOne([<span class="hljs-string">'team'</span> =&gt; <span class="hljs-string">'Argentina'</span>]);
$players = $team[<span class="hljs-string">'players'</span>]-&gt;getArrayCopy();
</code></pre>
<p>With the code above, we are:</p>
<ul>
<li><p>importing the database connection file</p>
</li>
<li><p>checking for <code>POST</code> data with the name on the <code>select</code> tag and setting a default value of <code>all</code> (the first option in the select element)</p>
</li>
<li><p>getting the database and collection in it</p>
</li>
<li><p>using the <code>findOne</code> method from MongoDB to get the team</p>
</li>
<li><p>and fetching the data as an array with <code>getArraCopy()</code> so we can loop through it</p>
</li>
</ul>
<p>At this point, you can print the <code>$players</code> variable with <code>print_r()</code> or <code>var_dump()</code> to see what it looks like. On my end, it looks like this when I ran the app with <code>php -S localhost:4000</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-06-09-at-16.24.47.png" alt="Screenshot-2024-06-09-at-16.24.47" width="600" height="400" loading="lazy"></p>
<h3 id="heading-step-6-create-the-logic-for-filtering-the-footballers-based-on-position">Step 6: Create the Logic for Filtering the Footballers Based on Position</h3>
<p>Remember we have to display the players based on whether they are goakeepers, defenders, midfielders, or forwards. To do that, we can utilize the code below:</p>
<pre><code class="lang-php">$filteredPlayers = $players;


<span class="hljs-keyword">if</span> ($position !== <span class="hljs-string">'all'</span>) {
 <span class="hljs-keyword">if</span> ($position === <span class="hljs-string">'nickname'</span>) {
   $filteredPlayers = array_filter($players, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">$player</span>) </span>{
     <span class="hljs-keyword">return</span> !<span class="hljs-keyword">empty</span>($player[<span class="hljs-string">'nickname'</span>]);
   });
 } <span class="hljs-keyword">else</span> {
   $filteredPlayers = array_filter($players, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">$player</span>) <span class="hljs-title">use</span> (<span class="hljs-params">$position</span>) </span>{
     <span class="hljs-keyword">return</span> $player[<span class="hljs-string">'position'</span>] === $position;
   });
 }
}
</code></pre>
<p>At first, we are initializing <code>$filteredPlayers</code> to all the players. If the selected position is not <code>all</code>, we filter the players based on <code>nickname</code>. And if the selected position is not <code>nickname</code>, we filter the players to include only those whose position matches the selected <code>position</code>.</p>
<h3 id="heading-step-7-display-the-players-on-the-page-based-on-the-selected-position">Step 7: Display the Players on the Page Based on the Selected Position</h3>
<p>Now, all we need to do is set each option's value (all players, goalkeepers, defenders, midfielders, forwards) to <code>selected</code> if that option is matched. After that, we need to use <code>foreach</code> loop to do the proper display.</p>
<p>Here's one way you can set the value of each <code>option</code> to <code>selected</code>:</p>
<pre><code class="lang-php">&lt;option value=<span class="hljs-string">"all"</span> <span class="hljs-meta">&lt;?=</span> $position === <span class="hljs-string">'all'</span> ? <span class="hljs-string">'selected'</span> : <span class="hljs-string">''</span> <span class="hljs-meta">?&gt;</span>&gt;All Players&lt;/option&gt;
       &lt;option value=<span class="hljs-string">"nickname"</span> <span class="hljs-meta">&lt;?=</span> $position === <span class="hljs-string">'nickname'</span> ? <span class="hljs-string">'selected'</span> : <span class="hljs-string">''</span> <span class="hljs-meta">?&gt;</span>&gt;Nicknames&lt;/option&gt;
       &lt;option value=<span class="hljs-string">"forward"</span> <span class="hljs-meta">&lt;?=</span> $position === <span class="hljs-string">'forward'</span> ? <span class="hljs-string">'selected'</span> : <span class="hljs-string">''</span> <span class="hljs-meta">?&gt;</span>&gt;Forwards&lt;/option&gt;
       &lt;option value=<span class="hljs-string">"midfielder"</span> <span class="hljs-meta">&lt;?=</span> $position === <span class="hljs-string">'midfielder'</span> ? <span class="hljs-string">'selected'</span> : <span class="hljs-string">''</span> <span class="hljs-meta">?&gt;</span>&gt;Midfielders&lt;/option&gt;
       &lt;option value=<span class="hljs-string">"defender"</span> <span class="hljs-meta">&lt;?=</span> $position === <span class="hljs-string">'defender'</span> ? <span class="hljs-string">'selected'</span> : <span class="hljs-string">''</span> <span class="hljs-meta">?&gt;</span>&gt;Defenders&lt;/option&gt;
       &lt;option value=<span class="hljs-string">"goalkeeper"</span> <span class="hljs-meta">&lt;?=</span> $position === <span class="hljs-string">'goalkeeper'</span> ? <span class="hljs-string">'selected'</span> : <span class="hljs-string">''</span> <span class="hljs-meta">?&gt;</span>&gt;Goalkeepers&lt;/option&gt;
</code></pre>
<p>And here's how you can use the <code>foreach</code> loop to finally display the players selected:</p>
<pre><code class="lang-php">&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span>="<span class="hljs-title">cards</span>" <span class="hljs-title">id</span>="<span class="hljs-title">player</span>-<span class="hljs-title">cards</span>"&gt;
     &lt;?<span class="hljs-title">php</span> <span class="hljs-title">if</span> (<span class="hljs-title">empty</span>($<span class="hljs-title">filteredPlayers</span>)) : ?&gt;
       &lt;<span class="hljs-title">p</span>&gt;<span class="hljs-title">No</span> <span class="hljs-title">players</span> <span class="hljs-title">found</span> <span class="hljs-title">for</span> <span class="hljs-title">the</span> <span class="hljs-title">selected</span> <span class="hljs-title">position</span>.&lt;/<span class="hljs-title">p</span>&gt;
     &lt;?<span class="hljs-title">php</span> <span class="hljs-title">else</span> : ?&gt;
       &lt;?<span class="hljs-title">php</span> <span class="hljs-title">foreach</span> ($<span class="hljs-title">filteredPlayers</span> <span class="hljs-title">as</span> $<span class="hljs-title">players</span>) : ?&gt;
         &lt;<span class="hljs-title">div</span> <span class="hljs-title">class</span>="<span class="hljs-title">player</span>-<span class="hljs-title">card</span>"&gt;
           &lt;<span class="hljs-title">h2</span>&gt;&lt;?= $<span class="hljs-title">players</span>['<span class="hljs-title">name</span>'] . ($<span class="hljs-title">players</span>['<span class="hljs-title">isCaptain</span>'] ? ' (<span class="hljs-title">Captain</span>)' : '') ?&gt;&lt;/<span class="hljs-title">h2</span>&gt;
           &lt;<span class="hljs-title">p</span>&gt;<span class="hljs-title">Position</span>: &lt;?= $<span class="hljs-title">players</span>['<span class="hljs-title">position</span>'] ?&gt;&lt;/<span class="hljs-title">p</span>&gt;
           &lt;<span class="hljs-title">p</span>&gt;<span class="hljs-title">Number</span>: &lt;?= $<span class="hljs-title">players</span>['<span class="hljs-title">number</span>'] ?&gt;&lt;/<span class="hljs-title">p</span>&gt;
           &lt;<span class="hljs-title">p</span>&gt;<span class="hljs-title">Nickname</span>: &lt;?= !<span class="hljs-title">empty</span>($<span class="hljs-title">players</span>['<span class="hljs-title">nickname</span>']) ? $<span class="hljs-title">players</span>['<span class="hljs-title">nickname</span>'] : '<span class="hljs-title">N</span>/<span class="hljs-title">A</span>' ?&gt;&lt;/<span class="hljs-title">p</span>&gt;
         &lt;/<span class="hljs-title">div</span>&gt;
       &lt;?<span class="hljs-title">php</span> <span class="hljs-title">endforeach</span> ?&gt;
     &lt;?<span class="hljs-title">php</span> <span class="hljs-title">endif</span> ?&gt;
   &lt;/<span class="hljs-title">div</span>&gt;</span>
</code></pre>
<p>Now, everything works as expected:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/football-team-cards.gif" alt="football-team-cards" width="600" height="400" loading="lazy"></p>
<p>You can grab the final code of the project in the main branch of this <a target="_blank" href="https://github.com/Ksound22/football-team-cards-php-rebuild">GitHub repo</a>.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>Rebuilding the football team cards project with PHP and MongoDB Atlas shows just how powerful and flexible it can be to combine server-side scripting with a cloud-based NoSQL database.</p>
<p>The project not only highlights how smoothly PHP and MongoDB Atlas work together, but it also shows the advantages of using a cloud-based database like Atlas. Atlas offers scalability, high availability, and easy management, making it a great choice for modern web applications.</p>
<p>Whichever data-driven application you're making, these techniques that we used here to build the project and the initial CRUD app can help you out.</p>
<p>Happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ PHP Array Handbook – How to Create, Work with, and Loop Through Arrays ]]>
                </title>
                <description>
                    <![CDATA[ In every programming language, arrays provide a flexible option to store more than one data type in a single variable. They are one of the most versatile data structures in the programming world, which is one reason a lot of external data and many AP... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/php-array-handbook/</link>
                <guid isPermaLink="false">66adf1bb6992d2a84c5d7936</guid>
                
                    <category>
                        <![CDATA[ arrays ]]>
                    </category>
                
                    <category>
                        <![CDATA[ handbook ]]>
                    </category>
                
                    <category>
                        <![CDATA[ PHP ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Wed, 08 May 2024 22:25:55 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/05/PHP-Array-Handbook-Cover-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In every programming language, arrays provide a flexible option to store more than one data type in a single variable. They are one of the most versatile data structures in the programming world, which is one reason a lot of external data and many APIs come as arrays.</p>
<p>When you create an array in PHP, you'll want to be able to use it. To do so, you have to manipulate or loop through it. PHP provides several built-in functions for manipulating arrays and several ways to loop through arrays.</p>
<p>Understanding and utilizing those built-in functions and loops is essential for efficient array manipulation. With them, you'll save time, write cleaner code, and become a more efficient PHP developer.</p>
<p>Note that this is the first part of a two-article series. The second part will focus on how to use MongoDB in PHP by rebuilding the Football Team Cards project. The footballers will come from a MongoDB Atlas database. We will then fetch them as arrays and display them on the page.</p>
<h2 id="heading-what-well-cover">What We'll Cover</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-to-create-arrays-in-php">How to Create Arrays in PHP</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-to-create-arrays-with-the-array-function">How to Create Arrays with the Array Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-arrays-with-the-square-bracket-syntax">How to Create Arrays with the Square Bracket Syntax</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-print-arrays-in-php">How to Print Arrays in PHP</a></p>
<ul>
<li><p><a class="post-section-overview" href="#howtoprintanarraywiththeprintrfunction">How to Print an Array with the <code>print_r()</code> Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#howtoprintanarraywiththevardumpfunction">How to Print an Array with the var_dump() Function</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-php-array-functions">PHP Array Functions</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-the-count-array-function">The <code>count()</code> Array Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#thearraypush_arrayfunction">The <code>array_push()</code> Array Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-arraypop-function">The <code>array_pop()</code> Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-arrayshift-function">The <code>array_shift()</code> Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-arrayunshift-function">The <code>array_unshift()</code> Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-arraysplice-function">The <code>array_splice()</code> Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-arraykeys-function">The <code>array_keys()</code> Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-arrayvalues-function">The <code>array_values()</code> Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-arrayreduce-function">The <code>array_reduce()</code> Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-sort-function">The <code>sort()</code> Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-rsort-function">The <code>rsort()</code> Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-arrayreplace-function">The <code>array_replace()</code> Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-arrayreverse-function">The <code>array_reverse()</code> Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-arrayslice-function">The <code>array_slice()</code> Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-arraysum-function">The <code>array_sum()</code> Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-arraymerge-function">The <code>array_merge()</code> Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-arrayfilter-function">The <code>array_filter()</code> Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#thearraymap_function">The <code>array_map()</code> Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-arraysearch-function">The <code>array_search()</code> Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#thearraycolumnfunction">The <code>array_column()</code> Function</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-inarray-function">The <code>in_array()</code> Function</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-loop-through-arrays-in-php">How to Loop Through Arrays in PHP</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-to-loop-through-an-indexed-array">How to Loop through an Indexed Array</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-loop-through-an-associative-array">How to Loop through an Associative Array</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-loop-through-an-array-inside-the-html-template">How to Loop through an Array Inside the HTML Template</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-how-to-create-arrays-in-php">How to Create Arrays in PHP</h2>
<p>In PHP, arrays exist in 3 forms:</p>
<ul>
<li><p><strong>indexed</strong> – a regular array with predefined indexes</p>
</li>
<li><p><strong>multidimensional</strong> – an array with arrays within it</p>
</li>
<li><p><strong>associative</strong> – an array with string indexes</p>
</li>
</ul>
<p>There are two ways you can create any of those 3 forms of arrays in PHP. You can either use the <code>Array()</code> function or the square brackets syntax (<code>[ ]</code>).</p>
<h3 id="heading-how-to-create-arrays-with-the-array-function">How to Create Arrays with the Array Function</h3>
<p>To create a PHP array with the <code>array()</code> function, just pass the elements into the function.</p>
<p>Here's the catch:</p>
<ul>
<li><p>a <strong>regular array</strong> is created with the <code>array()</code> function by passing the elements directly into the function</p>
</li>
<li><p>a <strong>multidimensional array</strong> is created with the <code>array()</code> function by nesting one or more <code>array()</code> functions inside one <code>array()</code> function</p>
</li>
<li><p>an <strong>associative array</strong> is created with the <code>array()</code> function by separating the key and values with a fat arrow (<code>=&gt;</code>) and separating each entry with a comma</p>
</li>
</ul>
<p>Here's examples of all of them in code:</p>
<pre><code class="lang-php"><span class="hljs-comment">// regular array with the array function</span>
$myFruitsArr1 = <span class="hljs-keyword">array</span>(<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>);


<span class="hljs-comment">// multidimensional array with the array function</span>
$myFruitsArr2 = <span class="hljs-keyword">array</span>(
 <span class="hljs-keyword">array</span>(<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Avocado"</span>, <span class="hljs-string">"Apricot"</span>),
 <span class="hljs-keyword">array</span>(<span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Blackeberry"</span>, <span class="hljs-string">"Babaco"</span>),
 <span class="hljs-keyword">array</span>(<span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Cherry"</span>, <span class="hljs-string">"Canary melon"</span>),
 <span class="hljs-keyword">array</span>(<span class="hljs-string">"Mango"</span>, <span class="hljs-string">"Melon"</span>, <span class="hljs-string">"Miracle fruit"</span>),
);


<span class="hljs-comment">// associative array with the array function</span>
$myFruitsArr3 = <span class="hljs-keyword">array</span>(
 <span class="hljs-string">"fruit 1"</span> =&gt; <span class="hljs-string">"Apple"</span>,
 <span class="hljs-string">"fruit 2"</span> =&gt; <span class="hljs-string">"Banana"</span>,
 <span class="hljs-string">"fruit 3"</span> =&gt; <span class="hljs-string">"Cashew"</span>,
 <span class="hljs-string">"fruit 4"</span> =&gt; <span class="hljs-string">"Mango"</span>,
);
</code></pre>
<h3 id="heading-how-to-create-arrays-with-the-square-bracket-syntax">How to Create Arrays with the Square Bracket Syntax</h3>
<p>The square bracket syntax is the most common way to create an array in PHP (and JavaScript as well).</p>
<p>To create an array with the square bracket syntax, replace every occurrence of <code>array()</code> with opening and closing square brackets:</p>
<pre><code class="lang-php"><span class="hljs-comment">// regular array with the square bracket syntax</span>
$myFruitsArr1 = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>];


<span class="hljs-comment">// multidimensional array with the square bracket syntax</span>
$myFruitsArr2 = [
 [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Avocado"</span>, <span class="hljs-string">"Apricot"</span>],
 [<span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Blackeberry"</span>, <span class="hljs-string">"Babaco"</span>],
 [<span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Cherry"</span>, <span class="hljs-string">"Canary melon"</span>],
 [<span class="hljs-string">"Mango"</span>, <span class="hljs-string">"Melon"</span>, <span class="hljs-string">"Miracle fruit"</span>],
];


<span class="hljs-comment">// associative array with the square bracket syntax</span>
$myFruitsArr3 = [
 <span class="hljs-string">"fruit 1"</span> =&gt; <span class="hljs-string">"Apple"</span>,
 <span class="hljs-string">"fruit 2"</span> =&gt; <span class="hljs-string">"Banana"</span>,
 <span class="hljs-string">"fruit 3"</span> =&gt; <span class="hljs-string">"Cashew"</span>,
 <span class="hljs-string">"fruit 4"</span> =&gt; <span class="hljs-string">"Mango"</span>,
];
</code></pre>
<h2 id="heading-how-to-print-arrays-in-php">How to Print Arrays in PHP</h2>
<p>Most times, you might need to print an array for debugging or visual purposes. PHP provides the <code>echo</code> statement, <code>print_r()</code>, and <code>var_dump()</code> functions for printing data.</p>
<p><code>echo</code> does not print an array as it should because it is meant for printing strings, integers, and floats. You should use <code>print_r()</code> and <code>var_dump()</code> to print arrays instead.</p>
<h3 id="heading-how-to-print-an-array-with-the-printr-function">How to Print an Array with the <code>print_r()</code> Function</h3>
<p>The <code>print_r()</code> function displays structured information about a variable in a human-readable format.</p>
<p><code>print_r()</code> is particularly useful for displaying and inspecting the contents of complex data structures like arrays and objects. You use it by passing the array identifier into it:</p>
<pre><code class="lang-php">print_r($myFruitsArr1);
print_r($myFruitsArr2);
print_r($myFruitsArr3);
</code></pre>
<p>Even if the array or object has nested elements, <code>print_r()</code> will traverse the entire array or object and display the content without missing any elements.</p>
<p>Here's what each of the 3 types of arrays looks like when you print them with the <code>print_r()</code> function:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/image6-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Regular, multidimensional, and associative array examples.</em></p>
<h3 id="heading-how-to-print-an-array-with-the-vardump-function">How to Print an Array with the <code>var_dump()</code> Function</h3>
<p>The <code>var_dump()</code> function lets you print an array or variable like the <code>print_r()</code> function. What it does differently is that it displays the data type of what you're printing, including each element of the array.</p>
<p>Here's how to use the <code>var_dump()</code> function:</p>
<pre><code class="lang-php">var_dump($myFruitsArr1);
var_dump($myFruitsArr2);
var_dump($myFruitsArr3);
</code></pre>
<p>And here's what each of the 3 types of array looks like when you print them with the <code>var_dump()</code> function:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/image3.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Regular, multidimensional, and associative arrays printed with var_dump()</em></p>
<h2 id="heading-php-array-functions">PHP Array Functions</h2>
<p>PHP provides a rich variety of array functions. They allow you to perform a wide range of operations on arrays, from basic manipulation to advanced data processing.</p>
<p>There are more than 70 array functions you can use in PHP, so we won't be able to cover all of them in this handbook.</p>
<p>Here are the ones we’ll cover:</p>
<ul>
<li><p><code>count()</code></p>
</li>
<li><p><code>array_push()</code></p>
</li>
<li><p><code>array_pop()</code></p>
</li>
<li><p><code>array_shift()</code></p>
</li>
<li><p><code>array_unshift()</code></p>
</li>
<li><p><code>array_splice()</code></p>
</li>
<li><p><code>array_keys()</code></p>
</li>
<li><p><code>array_values()</code></p>
</li>
<li><p><code>array_reduce()</code></p>
</li>
<li><p><code>sort()</code></p>
</li>
<li><p><code>rsort()</code></p>
</li>
<li><p><code>array_replace()</code></p>
</li>
<li><p><code>array_reverse()</code></p>
</li>
<li><p><code>array_slice()</code></p>
</li>
<li><p><code>array_sum()</code></p>
</li>
<li><p><code>array_merge()</code></p>
</li>
<li><p><code>array_filter()</code></p>
</li>
<li><p><code>array_map()</code></p>
</li>
<li><p><code>array_search()</code></p>
</li>
<li><p><code>array_column()</code></p>
</li>
<li><p><code>in_array()</code></p>
</li>
</ul>
<h3 id="heading-the-count-array-function">The <code>count()</code> Array Function</h3>
<p>The <code>count()</code> function does what its name implies — it goes through an array, counts the items, and returns an integer representing the array's length.</p>
<pre><code class="lang-php">$myFruitsArr = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>];
<span class="hljs-keyword">echo</span> count($myFruitsArr); <span class="hljs-comment">// 4</span>
</code></pre>
<p><code>count()</code> can be helpful if you want to do something based on the length of a particular array:</p>
<pre><code class="lang-php">$myFruitsArr = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>];


<span class="hljs-keyword">if</span> (count($myFruitsArr) === <span class="hljs-number">4</span>) {
 <span class="hljs-keyword">echo</span> <span class="hljs-string">"The fruits are enough"</span>;
} <span class="hljs-keyword">else</span> {
 <span class="hljs-keyword">echo</span> <span class="hljs-string">"The fruits are not enough"</span>;
}


<span class="hljs-comment">// The fruits are enough</span>
</code></pre>
<p>Because <code>count()</code> gets the length of an array, its commonly used in loops:</p>
<pre><code class="lang-php">$myFruitsArr = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>];


<span class="hljs-keyword">for</span> ($i = <span class="hljs-number">0</span>; $i &lt; count($myFruitsArr); $i++) {
 <span class="hljs-keyword">echo</span> $myFruitsArr[$i] . <span class="hljs-string">"&lt;br&gt;"</span>;
}


<span class="hljs-comment">/*
Output:


Apple
Banana
Cashew
Mango
*/</span>
</code></pre>
<h3 id="heading-the-arraypush-array-function">The <code>array_push()</code> Array Function</h3>
<p><code>array_push()</code> “pushes” an element to the end of the array. That is, it adds a specified item after the last item in the array. This means it modifies the original array.</p>
<p><code>array_push</code> takes a compulsory <code>array</code> argument and the element you want to push into the existing array:</p>
<pre><code class="lang-php">$myFruitsArr = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>];


array_push($myFruitsArr, <span class="hljs-string">"Avocado"</span>);
print_r($myFruitsArr); <span class="hljs-comment">// Array ( [0] =&gt; Apple [1] =&gt; Banana [2] =&gt; Cashew [3] =&gt; Mango [4] =&gt; Avocado )</span>
</code></pre>
<p>You can echo out the <code>&lt;pre&gt;</code> tag to format the resulting array better:</p>
<pre><code class="lang-php">$myFruitsArr = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>];


array_push($myFruitsArr, <span class="hljs-string">"Avocado"</span>);
<span class="hljs-keyword">echo</span> <span class="hljs-string">"&lt;pre&gt;"</span>;
var_dump($myFruitsArr);
<span class="hljs-keyword">echo</span> <span class="hljs-string">"&lt;pre&gt;"</span>;


<span class="hljs-comment">/*
Output:


array(5) {
 [0]=&gt;
 string(5) "Apple"
 [1]=&gt;
 string(6) "Banana"
 [2]=&gt;
 string(6) "Cashew"
 [3]=&gt;
 string(5) "Mango"
 [4]=&gt;
 string(7) "Avocado"
}
*/</span>
</code></pre>
<p>You can also push two or more items:</p>
<pre><code class="lang-php">$myFruitsArr = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>];


array_push($myFruitsArr, <span class="hljs-string">"Avocado"</span>, <span class="hljs-string">"Pineapple"</span>);
<span class="hljs-keyword">echo</span> <span class="hljs-string">"&lt;pre&gt;"</span>;
var_dump($myFruitsArr);
<span class="hljs-keyword">echo</span> <span class="hljs-string">"&lt;pre&gt;"</span>;


<span class="hljs-comment">/*
Output:


array(6) {
 [0]=&gt;
 string(5) "Apple"
 [1]=&gt;
 string(6) "Banana"
 [2]=&gt;
 string(6) "Cashew"
 [3]=&gt;
 string(5) "Mango"
 [4]=&gt;
 string(7) "Avocado"
 [5]=&gt;
 string(9) "Pineapple"
}
*/</span>
</code></pre>
<h3 id="heading-the-arraypop-function">The <code>array_pop()</code> Function</h3>
<p><code>array_pop()</code> does the opposite of what <code>array_push()</code> does – <strong>it removes an element from the end of the array</strong>. That means it can be useful in stack-based data structures.</p>
<p>To use the <code>array_pop()</code> function, you only need to pass in the array you want to remove from:</p>
<pre><code class="lang-php">$myFruitsArr = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>];
array_pop($myFruitsArr);


<span class="hljs-keyword">echo</span> <span class="hljs-string">"&lt;pre&gt;"</span>;
var_dump($myFruitsArr);
<span class="hljs-keyword">echo</span> <span class="hljs-string">"&lt;pre&gt;"</span>;


<span class="hljs-comment">/*
Mango is gone:


array(3) {
 [0]=&gt;
 string(5) "Apple"
 [1]=&gt;
 string(6) "Banana"
 [2]=&gt;
 string(6) "Cashew"
}
*/</span>
</code></pre>
<p>You can echo out the popped element because <code>array_pop()</code> modifies the original array:</p>
<pre><code class="lang-php">$myFruitsArr = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>];
$poppedElem = array_pop($myFruitsArr);


<span class="hljs-keyword">echo</span> $poppedElem; <span class="hljs-comment">// Mango</span>
</code></pre>
<h3 id="heading-the-arrayshift-function">The <code>array_shift()</code> Function</h3>
<p><code>array_shift()</code> is like <code>array_pop</code>, but it removes the first element of an array and not the last. So, it's helpful in queue-based data structures.</p>
<pre><code class="lang-php">$myFruitsArr = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>];
array_shift($myFruitsArr);
var_dump($myFruitsArr);


<span class="hljs-comment">/*
Apple is gone:


array(3) {
 [0]=&gt;
 string(6) "Banana"
 [1]=&gt;
 string(6) "Cashew"
 [2]=&gt;
 string(5) "Mango"
}
*/</span>
</code></pre>
<p>Because the <code>array_shift()</code> function modifies the original array, it reorders the indices:</p>
<pre><code class="lang-php">$myFruitsArr = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>];


<span class="hljs-keyword">echo</span> <span class="hljs-string">"before shift: "</span>;
var_dump($myFruitsArr);


<span class="hljs-keyword">echo</span> <span class="hljs-string">"&lt;br&gt;"</span>;


<span class="hljs-keyword">echo</span> <span class="hljs-string">"after shift: "</span>;
array_shift($myFruitsArr);
var_dump($myFruitsArr);
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/image5.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Before and after using the shift() function</em></p>
<p><code>array_shift()</code> also returns the removed array because it modifies the original array:</p>
<pre><code class="lang-php">$myFruitsArr = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>];
$shiftedElem = array_shift($myFruitsArr);

<span class="hljs-keyword">echo</span> $shiftedElem; <span class="hljs-comment">// Apple</span>
</code></pre>
<h3 id="heading-the-arrayunshift-function">The <code>array_unshift()</code> Function</h3>
<p>The <code>array_unshift()</code> function adds one or more elements to the beginning of an array. It modifies the original array by inserting the new elements at the start and re-indexing the existing elements.</p>
<p>It takes the array you want to add to and the element you want to add as the arguments. You can use it without providing the element to add to the beginning of the array, but it is advised not to do so.</p>
<p>Here’s an example:</p>
<pre><code class="lang-php">$myFruitsArr = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>];
array_unshift($myFruitsArr, <span class="hljs-string">"Avocado"</span>);

var_dump($myFruitsArr);

<span class="hljs-comment">/*
array(5) {
 [0]=&gt;
 string(7) "Avocado"
 [1]=&gt;
 string(5) "Apple"
 [2]=&gt;
 string(6) "Banana"
 [3]=&gt;
 string(6) "Cashew"
 [4]=&gt;
 string(5) "Mango"
}
*/</span>
</code></pre>
<h3 id="heading-the-arraysplice-function">The <code>array_splice()</code> Function</h3>
<p>The <code>array_splice()</code> method removes an item from an array and replaces it with the specified replacement. <code>array_splice()</code> modifies the original array, so it returns that removed item.</p>
<p><code>array_splice()</code> takes up to 4 arguments, as you can see in its basic syntax below:</p>
<pre><code class="lang-php">array_splice(<span class="hljs-keyword">array</span>, startingIndex, length, replacement)
</code></pre>
<ul>
<li><p><code>array</code> is the array you’re using the <code>array_splice()</code> function on</p>
</li>
<li><p><code>startingIndex</code> is the position where you want to start removing the item(s) in the array. That means if you specify <code>0</code>, it will remove the first element in the array.</p>
</li>
<li><p><code>length</code> is how far you want the splicing to go. For instance, if you specify <code>2</code>, two items will be removed starting from the specified <code>startingIndex</code></p>
</li>
<li><p><code>replacement</code> is the item that will replace the item to be removed. This could be a single item or another array.</p>
</li>
</ul>
<p>Here’s an example with an array and a string replacement:</p>
<pre><code class="lang-php">$myFruitsArr = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>];
$splicedItem = array_splice($myFruitsArr, <span class="hljs-number">1</span>, <span class="hljs-number">1</span>, <span class="hljs-string">"Avocado"</span>);

var_dump($myFruitsArr);

<span class="hljs-comment">/*
Output:

array(4) {
 [0]=&gt;
 string(5) "Apple"
 [1]=&gt;
 string(7) "Avocado"
 [2]=&gt;
 string(6) "Cashew"
 [3]=&gt;
 string(5) "Mango"
}
*/</span>
<span class="hljs-keyword">echo</span> <span class="hljs-string">"&lt;br&gt;"</span>;

var_dump($splicedItem);

<span class="hljs-comment">/*
Output:
array(1) {
 [0]=&gt;
 string(6) "Banana"
}
*/</span>
</code></pre>
<p>Here’s another example with an array as the replacement:</p>
<pre><code class="lang-php">$myFruitsArr = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>];
$splicedItem = array_splice($myFruitsArr, <span class="hljs-number">1</span>, <span class="hljs-number">1</span>, <span class="hljs-keyword">array</span>(<span class="hljs-string">"Avocado"</span>, <span class="hljs-string">"Apricot"</span>, <span class="hljs-string">"Abiu"</span>));

var_dump($myFruitsArr);
<span class="hljs-comment">/*
Output:

array(6) {
 [0]=&gt;
 string(5) "Apple"
 [1]=&gt;
 string(7) "Avocado"
 [2]=&gt;
 string(7) "Apricot"
 [3]=&gt;
 string(4) "Abiu"
 [4]=&gt;
 string(6) "Cashew"
 [5]=&gt;
 string(5) "Mango"
}
*/</span>

var_dump($splicedItem);
<span class="hljs-comment">/*
Output:

array(1) {
 [0]=&gt;
 string(6) "Banana"
}
*/</span>
</code></pre>
<h3 id="heading-the-arraykeys-function">The <code>array_keys()</code> Function</h3>
<p>There are two components in every array – the keys and the values. For a regular array, the keys are the indexes. For an associative array, the keys are the indices specified for each array item.</p>
<p>The <code>array_keys</code> function extracts the keys of the items in an array.</p>
<p>If the array is a regular array, it lists the indices of the array as the keys:</p>
<pre><code class="lang-php">$myFruitsArr = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>];
$myFruitsArrKeys = array_keys($myFruitsArr);

print_r($myFruitsArrKeys);
<span class="hljs-comment">/*
Output:

Array
(
   [0] =&gt; 0
   [1] =&gt; 1
   [2] =&gt; 2
   [3] =&gt; 3
)
*/</span>
</code></pre>
<p>If the array is an associative array, it lists out the keys you specified for each item in the array:</p>
<pre><code class="lang-php">$myFruitsWithColors = [
 <span class="hljs-string">"apple"</span> =&gt; <span class="hljs-string">"red"</span>,
 <span class="hljs-string">"banana"</span> =&gt; <span class="hljs-string">"yellow"</span>,
 <span class="hljs-string">"orange"</span> =&gt; <span class="hljs-string">"orange"</span>,
 <span class="hljs-string">"grape"</span> =&gt; <span class="hljs-string">"purple"</span>,
 <span class="hljs-string">"watermelon"</span> =&gt; <span class="hljs-string">"green"</span>,
];

$myFruitsWithColorsKeys = array_keys($myFruitsWithColors);

print_r($myFruitsWithColorsKeys);
<span class="hljs-comment">/*
Output:

Array
(
   [0] =&gt; apple
   [1] =&gt; banana
   [2] =&gt; orange
   [3] =&gt; grape
   [4] =&gt; watermelon
)
*/</span>
</code></pre>
<p><code>array_keys()</code> can accept a second argument. This is usually an item in the array.</p>
<p>If you specify an item as that second argument, <code>array_keys()</code> will return the key for that item only:</p>
<pre><code class="lang-php">$myFruitsWithColors = [
 <span class="hljs-string">"apple"</span> =&gt; <span class="hljs-string">"red"</span>,
 <span class="hljs-string">"banana"</span> =&gt; <span class="hljs-string">"yellow"</span>,
 <span class="hljs-string">"orange"</span> =&gt; <span class="hljs-string">"orange"</span>,
 <span class="hljs-string">"grape"</span> =&gt; <span class="hljs-string">"purple"</span>,
 <span class="hljs-string">"watermelon"</span> =&gt; <span class="hljs-string">"green"</span>,
];

$myFruitsWithColorsKeys = array_keys($myFruitsWithColors, <span class="hljs-string">"orange"</span>);

print_r($myFruitsWithColorsKeys);
<span class="hljs-comment">/*
Output:

Array
(
   [0] =&gt; orange
)
*/</span>
</code></pre>
<h3 id="heading-the-arrayvalues-function">The <code>array_values()</code> Function</h3>
<p>The <code>array_values()</code> function extracts the other part of an array – the values.</p>
<pre><code class="lang-php">$myFruitsArr = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>];
$myFruitsArrValues = array_values($myFruitsArr);

print_r($myFruitsArrValues);

<span class="hljs-comment">/*
Output:
Array
(
   [0] =&gt; Apple
   [1] =&gt; Banana
   [2] =&gt; Cashew
   [3] =&gt; Mango
)
*/</span>
</code></pre>
<p>The output of <code>array_values()</code> looks like what happens when you print a regular array with the <code>print_r()</code> function, but it’s not. What happens is it also assigns indices to those printed values.</p>
<p>An example with an associative array would make that clearer:</p>
<pre><code class="lang-php">$myFruitsWithColors = [
 <span class="hljs-string">"apple"</span> =&gt; <span class="hljs-string">"red"</span>,
 <span class="hljs-string">"banana"</span> =&gt; <span class="hljs-string">"yellow"</span>,
 <span class="hljs-string">"orange"</span> =&gt; <span class="hljs-string">"orange"</span>,
 <span class="hljs-string">"grape"</span> =&gt; <span class="hljs-string">"purple"</span>,
 <span class="hljs-string">"watermelon"</span> =&gt; <span class="hljs-string">"green"</span>,
];

$myFruitsWithColorsValues = array_values($myFruitsWithColors);
print_r($myFruitsWithColorsValues);

<span class="hljs-comment">/*
Output:

Array
(
   [0] =&gt; red
   [1] =&gt; yellow
   [2] =&gt; orange
   [3] =&gt; purple
   [4] =&gt; green
)
*/</span>
</code></pre>
<h3 id="heading-the-arrayreduce-function">The <code>array_reduce()</code> Function</h3>
<p>The <code>array_reduce()</code> function is used to "reduce" an array to a single value by applying a callback function to each element of the array. It works like the <code>reduce()</code> array method of JavaScript.</p>
<p><code>array_reduce()</code> iterates through the array and performs the callback function on each element, accumulating a single result.</p>
<p>That means you can use it for data aggregation and computation, like calculating the total value of items in a shopping cart.</p>
<p><code>array_reduce()</code> takes 2 required arguments and 1 optional argument. Here’s the syntax:</p>
<pre><code class="lang-php">array_reduce(arraytoReduce, callbackFunction, initialValue)
</code></pre>
<ul>
<li><p><code>arrayToReduce</code> is the array you’re using <code>reduce</code> on</p>
</li>
<li><p><code>callbackFunction</code> is the function that will “reduce” the items of the array into a single value</p>
</li>
<li><p><code>initialValue</code> is optional. It specifies the initial value of the accumulator. If provided, it will be used as the initial value for the first call to the callback function. If not provided, the first element of the array will be used as the initial accumulator value.</p>
</li>
</ul>
<p><code>array_reduce()</code> is usually used with numbers:</p>
<pre><code class="lang-php">$myNumbers = [<span class="hljs-number">5</span>, <span class="hljs-number">89</span>, <span class="hljs-number">19</span>, <span class="hljs-number">10</span>, <span class="hljs-number">49</span>];

$total = array_reduce($myNumbers, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">$carry, $item</span>) </span>{
 <span class="hljs-keyword">return</span> $carry + $item;
}, <span class="hljs-number">0</span>);

<span class="hljs-keyword">echo</span> $total; <span class="hljs-comment">// 172</span>
</code></pre>
<p>You can extract that callback function into a separate function and pass it in as one of the arguments of the <code>array_reduce()</code> function:</p>
<pre><code class="lang-php">$myNumbers = [<span class="hljs-number">5</span>, <span class="hljs-number">89</span>, <span class="hljs-number">19</span>, <span class="hljs-number">10</span>, <span class="hljs-number">49</span>];


<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addNums</span>(<span class="hljs-params">$carry, $item</span>)
</span>{
 <span class="hljs-keyword">return</span> $carry + $item;
}

$total = array_reduce($myNumbers, <span class="hljs-string">'addNums'</span>, <span class="hljs-number">0</span>);

<span class="hljs-keyword">echo</span> $total; <span class="hljs-comment">// 172</span>
</code></pre>
<p><code>array_reduce()</code> also works with strings:</p>
<pre><code class="lang-php">$words = [<span class="hljs-string">"Hello"</span>, <span class="hljs-string">"camper!"</span>, <span class="hljs-string">"How"</span>, <span class="hljs-string">"are"</span>, <span class="hljs-string">"you"</span>, <span class="hljs-string">"today?"</span>];

<span class="hljs-comment">// Use array_reduce to concatenate all the strings</span>
$result = array_reduce($words, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">$carry, $item</span>) </span>{
 <span class="hljs-keyword">return</span> $carry . <span class="hljs-string">" "</span> . $item;
}, <span class="hljs-string">""</span>);

<span class="hljs-keyword">echo</span> $result; <span class="hljs-comment">//  Hello camper! How are you today?</span>
</code></pre>
<h3 id="heading-the-sort-function">The <code>sort()</code> Function</h3>
<p>The <code>sort()</code> function takes an array and sorts it in ascending order based on the values of its items. It modifies the original array by rearranging its elements in ascending order.</p>
<p>If you have some data in an array that you want to organize in ascending order, the <code>sort()</code> function is perfect for that.</p>
<pre><code class="lang-php">$myNums = [<span class="hljs-number">4</span>, <span class="hljs-number">2</span>, <span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>];
sort($myNums);

print_r($myNums);

<span class="hljs-comment">/*
Output:

Array
(
   [0] =&gt; 1
   [1] =&gt; 2
   [2] =&gt; 3
   [3] =&gt; 4
   [4] =&gt; 5
)
*/</span>
</code></pre>
<h3 id="heading-the-rsort-function">The <code>rsort()</code> Function</h3>
<p>The <code>rsort()</code> function is similar to <code>sort()</code>, but it sorts the array in descending order instead of ascending order.</p>
<pre><code class="lang-php">$myNums = <span class="hljs-keyword">array</span>(<span class="hljs-number">4</span>, <span class="hljs-number">2</span>, <span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>);
rsort($myNums);

<span class="hljs-comment">/*
Output:

Array
(
   [0] =&gt; 5
   [1] =&gt; 4
   [2] =&gt; 3
   [3] =&gt; 2
   [4] =&gt; 1
)
*/</span>

print_r($myNums);
</code></pre>
<h3 id="heading-the-arrayreplace-function">The <code>array_replace()</code> Function</h3>
<p>The <code>array_replace()</code> function is used to replace the values of the first array with the values of a provided array. It's perfect for updating data.</p>
<p><code>array_replace()</code> takes two arguments – the array you want to replace, and the new array.</p>
<pre><code class="lang-php">$myNamesArr1 = [<span class="hljs-string">"Zen"</span>, <span class="hljs-string">"Kay"</span>, <span class="hljs-string">"Luger"</span>];
$myNamesArr2 = [<span class="hljs-string">"Yuan"</span>, <span class="hljs-string">"Jay"</span>, <span class="hljs-string">"John"</span>];

$replaceRes = array_replace($myNamesArr1, $myNamesArr2);

print_r($replaceRes);

<span class="hljs-comment">/*
Output:
Array
(
   [0] =&gt; Yuan
   [1] =&gt; Jay
   [2] =&gt; John
)
*/</span>
</code></pre>
<p>If you don’t provide a second value, it returns the only argument you provide:</p>
<pre><code class="lang-php">$myNamesArr1 = [<span class="hljs-string">"Zen"</span>, <span class="hljs-string">"Kay"</span>, <span class="hljs-string">"Luger"</span>];
$myNamesArr2 = [<span class="hljs-string">"Yuan"</span>, <span class="hljs-string">"Jay"</span>, <span class="hljs-string">"John"</span>];

$replaceRes = array_replace($myNamesArr1);

print_r($replaceRes);

<span class="hljs-comment">/*
Output:
Array
(
   [0] =&gt; Zen
   [1] =&gt; Kay
   [2] =&gt; Luger
)
*/</span>
</code></pre>
<p>If you pass in three or more arrays as the arguments, the last argument will be the replacement for the first one, not the second:</p>
<pre><code class="lang-php">$myNamesArr1 = [<span class="hljs-string">"Zen"</span>, <span class="hljs-string">"Kay"</span>, <span class="hljs-string">"Luger"</span>];
$myNamesArr2 = [<span class="hljs-string">"Yuan"</span>, <span class="hljs-string">"Jay"</span>, <span class="hljs-string">"John"</span>];
$myNamesArr3 = [<span class="hljs-string">"Eddy"</span>, <span class="hljs-string">"White"</span>, <span class="hljs-string">"Jane"</span>];


$replaceRes = array_replace($myNamesArr1, $myNamesArr2, $myNamesArr3);

print_r($replaceRes);

<span class="hljs-comment">/*
Output:
Array
(
   [0] =&gt; Eddy
   [1] =&gt; White
   [2] =&gt; Jane
)
*/</span>
</code></pre>
<p>You can selectively replace an item in a particular index too:</p>
<pre><code class="lang-php">$myFruitsArr1 = [<span class="hljs-string">"a"</span> =&gt; <span class="hljs-string">"apple"</span>, <span class="hljs-string">"b"</span> =&gt; <span class="hljs-string">"banana"</span>, <span class="hljs-string">"c"</span> =&gt; <span class="hljs-string">"cherry"</span>];
$myFruitsArr2 = <span class="hljs-keyword">array</span>(<span class="hljs-string">"b"</span> =&gt; <span class="hljs-string">"blueberry"</span>, <span class="hljs-string">"c"</span> =&gt; <span class="hljs-string">"cranberry"</span>);
$replaceRes = array_replace($myFruitsArr1, $myFruitsArr2);

print_r($replaceRes);

<span class="hljs-comment">/*
Output:
Array
(
   [a] =&gt; apple
   [b] =&gt; blueberry
   [c] =&gt; cranberry
)
*/</span>
</code></pre>
<h3 id="heading-the-arrayreverse-function">The <code>array_reverse()</code> Function</h3>
<p>The <code>array_reverse()</code> function is used to reverse the order of elements in an array. It creates a new array with the elements in reverse order.</p>
<pre><code class="lang-php">$myFruitsArr = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>];
$reversedArr = array_reverse($myFruitsArr);

print_r($reversedArr);

<span class="hljs-comment">/*
Output:

Array
(
   [0] =&gt; Mango
   [1] =&gt; Cashew
   [2] =&gt; Banana
   [3] =&gt; Apple
)
*/</span>
</code></pre>
<p>If you remember how the <code>rsort()</code> function works, it’s very similar to how <code>array_reverse()</code> works. The only difference is that <code>rsort()</code> modifies the original array, but <code>array_reverse()</code> does not.</p>
<h3 id="heading-the-arrayslice-function">The <code>array_slice()</code> Function</h3>
<p>If you want to extract a particular part of an array and return it as a separate array, <code>array_slice()</code> is the ideal function for you to use.</p>
<p><code>array_slice()</code> allows you to specify the start index, the length of the slice, and whether to preserve the keys of the original array. Here’s the basic syntax:</p>
<pre><code class="lang-php">array_slice(arrayToSlice, startIndex, length, preserve)
</code></pre>
<ul>
<li><p><code>arrayToSlice</code> is the array you want to use <code>array_slice()</code> on</p>
</li>
<li><p><code>startIndex</code> is the index you want to start the slicing from</p>
</li>
<li><p><code>length</code> is how far you want the slicing to go in the <code>arrayToSlice</code>. It is optional.</p>
</li>
<li><p><code>preserve</code> specifies whether you want the index(es) of the array to change or not. It’s a boolean.</p>
</li>
</ul>
<p>The example below starts the slicing from the second element in the array, which means it’ll leave the first element out and return the others:</p>
<pre><code class="lang-php">$myFruitsArr = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>, <span class="hljs-string">"Avocado"</span>, <span class="hljs-string">"Pineapple"</span>];
$slicedArr = array_slice($myFruitsArr, <span class="hljs-number">1</span>);

print_r($slicedArr);

<span class="hljs-comment">/*
Output:

Array
(
   [0] =&gt; Banana
   [1] =&gt; Cashew
   [2] =&gt; Mango
   [3] =&gt; Avocado
   [4] =&gt; Pineapple
)
*/</span>
</code></pre>
<p>Don’t forget you can specify the number of items you want from the slicing by specifying a third optional argument:</p>
<pre><code class="lang-php">$myFruitsArr = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>, <span class="hljs-string">"Avocado"</span>, <span class="hljs-string">"Pineapple"</span>];
$slicedArr = array_slice($myFruitsArr, <span class="hljs-number">1</span>, <span class="hljs-number">3</span>);

print_r($slicedArr);

<span class="hljs-comment">/*
Output:

Array
(
   [0] =&gt; Banana
   [1] =&gt; Cashew
   [2] =&gt; Mango
)
*/</span>
</code></pre>
<p>If you want to preserve the indexes, you can specify a fourth optional boolean argument of <code>true</code>:</p>
<pre><code class="lang-php">$myFruitsArr = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>, <span class="hljs-string">"Avocado"</span>, <span class="hljs-string">"Pineapple"</span>];
$slicedArr = array_slice($myFruitsArr, <span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-literal">true</span>);

print_r($slicedArr);

<span class="hljs-comment">/*
Output:

Array
(
   [1] =&gt; Banana
   [2] =&gt; Cashew
   [3] =&gt; Mango
)
*/</span>
</code></pre>
<h3 id="heading-the-arraysum-function">The <code>array_sum()</code> Function</h3>
<p><code>array_sum()</code> adds all the numeric values in an array together and returns the result. The only parameter it takes is the array containing the numeric values.</p>
<pre><code class="lang-php">$myNums = [<span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">9</span>, <span class="hljs-number">20</span>, <span class="hljs-number">1</span>];

$total = array_sum($myNums);
<span class="hljs-keyword">echo</span> $total; <span class="hljs-comment">// 41</span>
</code></pre>
<p>If used on an array containing strings, <code>array_sum()</code> throws the error <code>Warning: array_sum(): Addition is not supported on type string in /location/index.php on line #</code> :</p>
<pre><code class="lang-php">$myFruitsArr = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>, <span class="hljs-string">"Avocado"</span>, <span class="hljs-string">"Pineapple"</span>];
$total = array_sum($myFruitsArr);
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/image2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>sum() function error</em></p>
<h3 id="heading-the-arraymerge-function">The <code>array_merge()</code> Function</h3>
<p><code>array_merge()</code> merges two or more arrays. That means it's ideal for combining multiple arrays into one giant array.</p>
<pre><code class="lang-php">$array1 = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];
$array2 = [<span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>, <span class="hljs-number">8</span>];

$result = array_merge($array1, $array2);

print_r($result);
<span class="hljs-comment">/*
Output:


Array
(
   [0] =&gt; 1
   [1] =&gt; 2
   [2] =&gt; 3
   [3] =&gt; 4
   [4] =&gt; 5
   [5] =&gt; 6
   [6] =&gt; 7
   [7] =&gt; 8
)
*/</span>
</code></pre>
<p>You can also use <code>array_merge()</code> on associative arrays:</p>
<pre><code class="lang-php">$array1 = [
 <span class="hljs-string">'fname'</span> =&gt; <span class="hljs-string">'John'</span>,
 <span class="hljs-string">'sex'</span> =&gt; <span class="hljs-string">'male'</span>,
];


$array2 = [
 <span class="hljs-string">'lname'</span> =&gt; <span class="hljs-string">'Doe'</span>,
 <span class="hljs-string">'favColor'</span> =&gt; <span class="hljs-string">'red'</span>,
];

$result = array_merge($array1, $array2);
print_r($result);

<span class="hljs-comment">/*
Output:

Array
(
   [fname] =&gt; John
   [sex] =&gt; male
   [lname] =&gt; Doe
   [favColor] =&gt; red
)
*/</span>
</code></pre>
<p>If the arrays contain similar keys, the last one overrides the previous one(s) in the result:</p>
<pre><code class="lang-php">$array1 = [
 <span class="hljs-string">'fname'</span> =&gt; <span class="hljs-string">'John'</span>,
 <span class="hljs-string">'sex'</span> =&gt; <span class="hljs-string">'male'</span>,
];


$array2 = [
 <span class="hljs-string">'fname'</span> =&gt; <span class="hljs-string">'Jane'</span>,
 <span class="hljs-string">'favColor'</span> =&gt; <span class="hljs-string">'red'</span>,
];

$result = array_merge($array1, $array2);
print_r($result);

<span class="hljs-comment">/*
Output:

Array
(
   [fname] =&gt; Jane
   [sex] =&gt; male
   [favColor] =&gt; red
)
*/</span>
</code></pre>
<p>If a single array is passed into <code>array_merge()</code> and the keys are not sequential integers starting from 0, but rather a sequence like <code>3</code>, <code>7</code>, <code>8</code>, the resulting array will have its keys reindexed starting from <code>0</code>:</p>
<pre><code class="lang-php">$myArray = [<span class="hljs-number">3</span> =&gt; <span class="hljs-string">'Barn'</span>, <span class="hljs-number">7</span> =&gt; <span class="hljs-string">'Silo'</span>, <span class="hljs-number">8</span> =&gt; <span class="hljs-string">'Tank'</span>];
$res = array_merge($myArray);

print_r($res);

<span class="hljs-comment">/*
Array
(
   [0] =&gt; Barn
   [1] =&gt; Silo
   [2] =&gt; Tank
)
*/</span>
</code></pre>
<h3 id="heading-the-arrayfilter-function">The <code>array_filter()</code> Function</h3>
<p>The <code>array_filter()</code> function “filters” the items of an array based on a callback function you pass into it. You can use it to remove unnecessary items from an array.</p>
<p>If the callback function returns <code>true</code> for an element in the array, that element is included in the resulting array, otherwise, it is excluded.</p>
<p><code>array_filter()</code> takes up to 3 arguments. The basic syntax looks like this:</p>
<pre><code class="lang-php">array_filter(arrayToFilter, callbackFunction, flag)
</code></pre>
<ul>
<li><p><code>arrayToFilter</code> is the array you want to filter. It’s a compulsory argument.</p>
</li>
<li><p><code>callbackFunction</code> is the callback function you want to apply to each element of the array. If not provided, all elements evaluated to <code>true</code> will be included in the result.</p>
</li>
<li><p><code>flag</code> specifies whether the array keys will be preserved or reindexed. Possible values are <code>ARRAY_FILTER_USE_KEY</code>, <code>ARRAY_FILTER_USE_BOTH</code>, and <code>ARRAY_FILTER_USE_BOTH</code>.</p>
</li>
</ul>
<p>Here’s an example that gets the even numbers from an array of numbers:</p>
<pre><code class="lang-php">$array = [<span class="hljs-number">76</span>, <span class="hljs-number">11</span>, <span class="hljs-number">12</span>, <span class="hljs-number">22</span>, <span class="hljs-number">13</span>, <span class="hljs-number">43</span>, <span class="hljs-number">54</span>];
$getEvenNums = array_filter($array, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">$value</span>) </span>{
 <span class="hljs-keyword">return</span> $value % <span class="hljs-number">2</span> == <span class="hljs-number">0</span>;
});


print_r($getEvenNums);


<span class="hljs-comment">/*
Array
(
   [0] =&gt; 76
   [2] =&gt; 12
   [3] =&gt; 22
   [6] =&gt; 54
)
*/</span>
</code></pre>
<p>Here’s a more complex example of getting everyone with the first name “John” in a multidimensional associative array:</p>
<pre><code class="lang-php">$persons = [
 [<span class="hljs-string">'first'</span> =&gt; <span class="hljs-string">'John'</span>, <span class="hljs-string">'last'</span> =&gt; <span class="hljs-string">'Doe'</span>],
 [<span class="hljs-string">'first'</span> =&gt; <span class="hljs-string">'Janet'</span>, <span class="hljs-string">'last'</span> =&gt; <span class="hljs-string">'Jackson'</span>],
 [<span class="hljs-string">'first'</span> =&gt; <span class="hljs-string">'John'</span>, <span class="hljs-string">'last'</span> =&gt; <span class="hljs-string">'Smith'</span>],
 [<span class="hljs-string">'first'</span> =&gt; <span class="hljs-string">'Jane'</span>, <span class="hljs-string">'last'</span> =&gt; <span class="hljs-string">'Doe'</span>],
 [<span class="hljs-string">'first'</span> =&gt; <span class="hljs-string">'David'</span>, <span class="hljs-string">'last'</span> =&gt; <span class="hljs-string">'Lee'</span>],
 [<span class="hljs-string">'first'</span> =&gt; <span class="hljs-string">'John'</span>, <span class="hljs-string">'last'</span> =&gt; <span class="hljs-string">'Olga'</span>]
];


$personsWithJohnFirstnames = array_filter($persons, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">$person</span>) </span>{
 <span class="hljs-keyword">return</span> $person[<span class="hljs-string">'first'</span>] === <span class="hljs-string">"John"</span>;
});

print_r($personsWithJohnFirstnames);

<span class="hljs-comment">/*
Output:

Array
(
   [0] =&gt; Array
       (
           [first] =&gt; John
           [last] =&gt; Doe
       )

   [2] =&gt; Array
       (
           [first] =&gt; John
           [last] =&gt; Smith
       )

   [5] =&gt; Array
       (
           [first] =&gt; John
           [last] =&gt; Olga
       )

)
*/</span>
</code></pre>
<p>Remember that if you pass in the array as the only argument, the resulting array will contain every item that evaluates to <code>true</code>:</p>
<pre><code class="lang-php">$array = [<span class="hljs-number">9</span>, <span class="hljs-number">4</span>, <span class="hljs-number">10</span>, <span class="hljs-number">0</span>, <span class="hljs-number">3</span>];
$result = array_filter($array);


print_r($result);


<span class="hljs-comment">/*
Output:


Array
(
   [0] =&gt; 9
   [1] =&gt; 4
   [2] =&gt; 10
   [4] =&gt; 3
)
*/</span>
</code></pre>
<h3 id="heading-the-arraymap-function">The <code>array_map()</code> Function</h3>
<p>The <code>array_map()</code> function transforms all the elements of an array based on a callback function passed into it. It then returns a new array containing the transformed elements.</p>
<p>You can think about <code>array_map()</code> as a more convenient way to "loop" through an array, even though it's technically not a loop.</p>
<p><code>array_map()</code> takes two compulsory parameters – the callback function and the array you want to transform.</p>
<p>Here's an example in which all the numbers of an array are squared:</p>
<pre><code class="lang-php">$numbers = [<span class="hljs-number">5</span>, <span class="hljs-number">8</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>];

$squaredNumbers = array_map(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">$num</span>) </span>{
 <span class="hljs-keyword">return</span> $num * $num;
}, $numbers);

print_r($squaredNumbers);

<span class="hljs-comment">/*
Output:

Array
(
   [0] =&gt; 25
   [1] =&gt; 64
   [2] =&gt; 9
   [3] =&gt; 16
)
*/</span>
</code></pre>
<p>You can also extract the callback function into a separate function and pass it in:</p>
<pre><code class="lang-php"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">squareNums</span>(<span class="hljs-params">$num</span>)
</span>{
 <span class="hljs-keyword">return</span> $num * $num;
}

$numbers = [<span class="hljs-number">5</span>, <span class="hljs-number">8</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>];
$squaredNumbers = array_map(<span class="hljs-string">'squareNums'</span>, $numbers);

print_r($squaredNumbers);

<span class="hljs-comment">/*
Output:

Array
(
   [0] =&gt; 25
   [1] =&gt; 64
   [2] =&gt; 9
   [3] =&gt; 16
)
*/</span>
</code></pre>
<p>You can also use the <code>array_map()</code> function on an array of strings. The example below converts all the fruits in the <code>$fruitsArr</code> array to uppercase:</p>
<pre><code class="lang-php">$fruitsArr = [<span class="hljs-string">'mango'</span>, <span class="hljs-string">'apple'</span>, <span class="hljs-string">'orange'</span>, <span class="hljs-string">'strawberry'</span>];

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">toUpperCase</span>(<span class="hljs-params">$str</span>)
</span>{
 <span class="hljs-keyword">return</span> strtoupper($str);
}

$uppercasedFruits = array_map(<span class="hljs-string">'toUpperCase'</span>, $fruitsArr);

print_r($uppercasedFruits);

<span class="hljs-comment">/*
Output:

Array
(
   [0] =&gt; MANGO
   [1] =&gt; APPLE
   [2] =&gt; ORANGE
   [3] =&gt; STRAWBERRY
)
*/</span>
</code></pre>
<p>Here's an example using an associative array where all the values are prefixed with <code>prefix_</code>:</p>
<pre><code class="lang-php">$fruitsArr = [
 <span class="hljs-string">'fruit1'</span> =&gt; <span class="hljs-string">'mango'</span>,
 <span class="hljs-string">'fruit2'</span> =&gt; <span class="hljs-string">'banana'</span>,
 <span class="hljs-string">'fruit3'</span> =&gt; <span class="hljs-string">'orange'</span>,
];


<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addPrefixToFruits</span>(<span class="hljs-params">$fruit</span>)
</span>{
 <span class="hljs-keyword">return</span> <span class="hljs-string">'prefix_'</span> . $fruit;
}

$prefixedFruits = array_map(<span class="hljs-string">'addPrefixToFruits'</span>, $fruitsArr);

print_r($prefixedFruits);

<span class="hljs-comment">/*
Output:

Array
(
   [fruit1] =&gt; prefix_mango
   [fruit2] =&gt; prefix_banana
   [fruit3] =&gt; prefix_orange
)
*/</span>
</code></pre>
<blockquote>
<p><strong>Note</strong>: If you're wondering what the difference between <code>array_map()</code> and <code>array_filter()</code> is, the catch is that <code>array_map()</code> transforms all the elements of the array based on a callback function. In contrast, <code>array_filter()</code> returns any element of the array that matches the callback function passed into it.</p>
</blockquote>
<h3 id="heading-the-arraysearch-function">The <code>array_search()</code> Function</h3>
<p>The <code>array_search()</code> function is used to search for a given value within an array. If the value is found, it returns the key of the value, otherwise, it returns nothing.</p>
<p><code>array_search()</code> takes up to 3 arguments. Here's the syntax:</p>
<pre><code class="lang-php">array_search(valueToSearch, arrayToSearch, strict)
</code></pre>
<ul>
<li><p><code>valueToSearch</code> is the value you're looking for</p>
</li>
<li><p><code>arrayToSearch</code> is the array in which you want to search for the value</p>
</li>
<li><p><code>strict</code> is an optional boolean argument that determines whether a strict comparison operator should be used in the search. It's <code>false</code> by default. But if set to <code>true</code>, it will search for identical elements in the array and return them. For example, <code>"1"</code> and <code>1</code>.</p>
</li>
</ul>
<p>Here's an example checking for the item <code>Cashew</code> in an array of fruits:</p>
<pre><code class="lang-php">$myFruitsArr = [
 <span class="hljs-string">"fruit1"</span> =&gt; <span class="hljs-string">"Apple"</span>,
 <span class="hljs-string">"fruit2"</span> =&gt; <span class="hljs-string">"Banana"</span>,
 <span class="hljs-string">"fruit3"</span> =&gt; <span class="hljs-string">"Cashew"</span>,
 <span class="hljs-string">"fruit4"</span> =&gt; <span class="hljs-string">"Mango"</span>,
 <span class="hljs-string">"fruit5"</span> =&gt; <span class="hljs-string">"Avocado"</span>,
 <span class="hljs-string">"fruit6"</span> =&gt; <span class="hljs-string">"Pineapple"</span>
];

$checkForCashew = array_search(<span class="hljs-string">'Cashew'</span>, $myFruitsArr);

<span class="hljs-keyword">echo</span> $checkForCashew; <span class="hljs-comment">// fruit3</span>
</code></pre>
<p>And if you use it on a regular array, it will still return the index of the array, which is the key under the hood:</p>
<pre><code class="lang-php">$myFruitsArr = [
 <span class="hljs-string">"Apple"</span>,
 <span class="hljs-string">"Banana"</span>,
 <span class="hljs-string">"Cashew"</span>,
 <span class="hljs-string">"Mango"</span>,
 <span class="hljs-string">"Avocado"</span>,
 <span class="hljs-string">"Pineapple"</span>
];


$CheckForCashew = array_search(<span class="hljs-string">'Cashew'</span>, $myFruitsArr);


<span class="hljs-keyword">echo</span> $CheckForCashew; <span class="hljs-comment">// 2</span>
</code></pre>
<h3 id="heading-the-arraycolumn-function">The <code>array_column()</code> Function</h3>
<p>The <code>array_column()</code> extracts a single column of values from a multi-dimensional array. It returns an array containing the values of a specified column from the input array.</p>
<p>That means <code>array_column</code> is useful when you want to make an array out of the column of an existing array.</p>
<p><code>array_column()</code> takes up to 3 arguments. Here's the syntax:</p>
<pre><code class="lang-php">array_column(parentArray, columKey, indexKey)
</code></pre>
<ul>
<li><p><code>parentArray</code>: usually a multidimensional array, it's the array to extract the column of values from</p>
</li>
<li><p><code>columnKey</code>: the key or index of the column to extract values from. This can be an integer index or a string key representing the column name.</p>
</li>
<li><p><code>indexKey</code> (optional): the column to use as the index for the returned array. If omitted or set to null, numerical indexes are used.</p>
</li>
</ul>
<p>The example below uses the name key of the array to create a new array:</p>
<pre><code class="lang-php">$pupils = [
 [<span class="hljs-string">"id"</span> =&gt; <span class="hljs-number">1</span>, <span class="hljs-string">"name"</span> =&gt; <span class="hljs-string">"John"</span>, <span class="hljs-string">"score"</span> =&gt; <span class="hljs-number">90</span>],
 [<span class="hljs-string">"id"</span> =&gt; <span class="hljs-number">2</span>, <span class="hljs-string">"name"</span> =&gt; <span class="hljs-string">"Jane"</span>, <span class="hljs-string">"score"</span> =&gt; <span class="hljs-number">79</span>],
 [<span class="hljs-string">"id"</span> =&gt; <span class="hljs-number">3</span>, <span class="hljs-string">"name"</span> =&gt; <span class="hljs-string">"Will"</span>, <span class="hljs-string">"score"</span> =&gt; <span class="hljs-number">83</span>],
 [<span class="hljs-string">"id"</span> =&gt; <span class="hljs-number">4</span>, <span class="hljs-string">"name"</span> =&gt; <span class="hljs-string">"Jill"</span>, <span class="hljs-string">"score"</span> =&gt; <span class="hljs-number">92</span>],
 [<span class="hljs-string">"id"</span> =&gt; <span class="hljs-number">5</span>, <span class="hljs-string">"name"</span> =&gt; <span class="hljs-string">"steven"</span>, <span class="hljs-string">"score"</span> =&gt; <span class="hljs-number">100</span>],
];

$arrayFromNameColumn = array_column($pupils, <span class="hljs-string">'name'</span>);

print_r($arrayFromNameColumn);

<span class="hljs-comment">/*
Output:

Array
(
   [0] =&gt; John
   [1] =&gt; Jane
   [2] =&gt; Will
   [3] =&gt; Jill
   [4] =&gt; steven
)
*/</span>
</code></pre>
<p>Remember you can pass in another key in the array to make its values the indexes of the resulting array. I'll use the <code>"id"</code> for that:</p>
<pre><code class="lang-php">$pupils = [
 [<span class="hljs-string">"id"</span> =&gt; <span class="hljs-number">1</span>, <span class="hljs-string">"name"</span> =&gt; <span class="hljs-string">"John"</span>, <span class="hljs-string">"score"</span> =&gt; <span class="hljs-number">90</span>],
 [<span class="hljs-string">"id"</span> =&gt; <span class="hljs-number">2</span>, <span class="hljs-string">"name"</span> =&gt; <span class="hljs-string">"Jane"</span>, <span class="hljs-string">"score"</span> =&gt; <span class="hljs-number">79</span>],
 [<span class="hljs-string">"id"</span> =&gt; <span class="hljs-number">3</span>, <span class="hljs-string">"name"</span> =&gt; <span class="hljs-string">"Will"</span>, <span class="hljs-string">"score"</span> =&gt; <span class="hljs-number">83</span>],
 [<span class="hljs-string">"id"</span> =&gt; <span class="hljs-number">4</span>, <span class="hljs-string">"name"</span> =&gt; <span class="hljs-string">"Jill"</span>, <span class="hljs-string">"score"</span> =&gt; <span class="hljs-number">92</span>],
 [<span class="hljs-string">"id"</span> =&gt; <span class="hljs-number">5</span>, <span class="hljs-string">"name"</span> =&gt; <span class="hljs-string">"steven"</span>, <span class="hljs-string">"score"</span> =&gt; <span class="hljs-number">100</span>],
];

$arrayFromNameColumn = array_column($pupils, <span class="hljs-string">"name"</span>, <span class="hljs-string">"id"</span>);

print_r($arrayFromNameColumn);

<span class="hljs-comment">/*
Output:



Array
(
   [1] =&gt; John
   [2] =&gt; Jane
   [3] =&gt; Will
   [4] =&gt; Jill
   [5] =&gt; steven
)
*/</span>
</code></pre>
<h3 id="heading-the-inarray-function">The <code>in_array()</code> Function</h3>
<p><code>in_array()</code> is used to check if a particular element is in an array. It takes two compulsory parameters and one optional parameter.</p>
<p>Here's the syntax:</p>
<pre><code class="lang-php">in_array(itemToSearch, arrayToSearchThrough, strict)
</code></pre>
<ul>
<li><p><code>itemToSearch</code> is the element you're looking for. It's compulsory.</p>
</li>
<li><p><code>arrayToSearchThrough</code> is the array in which you want to search for <code>itemToSearch</code>. It's also compulsory.</p>
</li>
<li><p><code>strict</code> is a boolean value that lets you specify whether you want the search to be done with loose comparison (<code>==</code>) or strict comparison (<code>===</code>). It defaults to <code>false</code>.</p>
</li>
</ul>
<p>Here's the <code>in_array()</code> function in action:</p>
<pre><code class="lang-php">$myFruitsArr1 = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>];
var_dump(in_array(<span class="hljs-string">"Banana"</span>, $myFruitsArr1)); <span class="hljs-comment">// bool(true)</span>
var_dump(in_array(<span class="hljs-string">"banana"</span>, $myFruitsArr1)); <span class="hljs-comment">// bool(false)</span>
</code></pre>
<p>Because the result of <code>in_array()</code> is a boolean, it's commonly used in conditionals:</p>
<pre><code class="lang-php">$myFruitsArr1 = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Cashew"</span>, <span class="hljs-string">"Mango"</span>];


<span class="hljs-keyword">if</span> (in_array(<span class="hljs-string">"Banana"</span>, $myFruitsArr1)) {
 <span class="hljs-keyword">echo</span> <span class="hljs-string">"Banana is in the array"</span>; <span class="hljs-comment">// Banana is in the array</span>
} <span class="hljs-keyword">else</span> {
 <span class="hljs-keyword">echo</span> <span class="hljs-string">"Banana is not in the array"</span>;
}
</code></pre>
<h2 id="heading-how-to-loop-through-arrays-in-php">How to Loop Through Arrays in PHP</h2>
<p>PHP provides the traditional <code>for</code> loop for iterating through both indexed and associative arrays. You can also use a cleaner <code>forEach()</code> function for the same purpose.</p>
<h3 id="heading-how-to-loop-through-an-indexed-array">How to Loop through an Indexed Array</h3>
<p>Here's the basic syntax for looping through an array with a <code>for</code> loop:</p>
<pre><code class="lang-php"><span class="hljs-keyword">for</span> ($i=<span class="hljs-number">0</span>; $i &lt; count($arr); $i++) {
 <span class="hljs-comment"># do something with $arr ...</span>
}
</code></pre>
<p>And here's that of <code>foreach()</code>:</p>
<pre><code class="lang-php"><span class="hljs-keyword">foreach</span> ($arrs <span class="hljs-keyword">as</span> $arr) {
 <span class="hljs-comment"># do something with $arr</span>
}
</code></pre>
<p>Here's an example using the <code>for</code> loop to loop through an array of strings:</p>
<pre><code class="lang-php">$retiredBallers = [<span class="hljs-string">"Pele"</span>, <span class="hljs-string">"Maradona"</span>, <span class="hljs-string">"Zidane"</span>, <span class="hljs-string">"Lampard"</span>, <span class="hljs-string">"Okocha"</span>];

<span class="hljs-keyword">for</span> ($i = <span class="hljs-number">0</span>; $i &lt; count($retiredBallers); $i++) {
 <span class="hljs-keyword">echo</span> $retiredBallers[$i] . <span class="hljs-string">"&lt;br&gt;"</span>;
}

<span class="hljs-comment">/*
Output:

Pele
Maradona
Zidane
Lampard
Okocha
*/</span>
</code></pre>
<p>You can loop through numbers the same way:</p>
<pre><code class="lang-php"><span class="hljs-keyword">for</span> ($i = <span class="hljs-number">0</span>; $i &lt; count($myNums); $i++) {
 <span class="hljs-keyword">echo</span> $myNums[$i] . <span class="hljs-string">"&lt;br&gt;"</span>;
}

<span class="hljs-comment">/*
Output:

45
8
90
2
5
*/</span>
</code></pre>
<p>You can also print the index for each element of the array:</p>
<pre><code class="lang-php"><span class="hljs-keyword">for</span> ($i = <span class="hljs-number">0</span>; $i &lt; count($myNums); $i++) {
 <span class="hljs-keyword">echo</span> $myNums[$i] . <span class="hljs-string">" is at index "</span> . $i . <span class="hljs-string">"&lt;br&gt;"</span>;
}

<span class="hljs-comment">/*
Output:

45 is at index 0
8 is at index 1
90 is at index 2
2 is at index 3
5 is at index 4
*/</span>
</code></pre>
<p>Don't forget you can use <code>foreach</code> to loop through any array too:</p>
<pre><code class="lang-php"><span class="hljs-keyword">foreach</span> ($retiredBallers <span class="hljs-keyword">as</span> $retiredBaller) {
 <span class="hljs-keyword">echo</span> $retiredBaller . <span class="hljs-string">"&lt;br&gt;"</span>;
}


<span class="hljs-comment">/*
Pele
Maradona
Zidane
Lampard
Okocha
*/</span>
</code></pre>
<p>You can get the index this way as well:</p>
<pre><code class="lang-php"><span class="hljs-keyword">foreach</span> ($retiredBallers <span class="hljs-keyword">as</span> $key =&gt; $retiredBaller) {
 <span class="hljs-keyword">echo</span> $retiredBaller . <span class="hljs-string">" is at index "</span> . $key . <span class="hljs-string">"&lt;br&gt;"</span>;
}


<span class="hljs-comment">/*
Pele is at index 0
Maradona is at index 1
Zidane is at index 2
Lampard is at index 3
Okocha is at index 4
*/</span>
</code></pre>
<h3 id="heading-how-to-loop-through-an-associative-array">How to Loop through an Associative Array</h3>
<p>An associative array can be complex with items nested deep into it. So, you have to get what you want from it instead of displaying everything in it.</p>
<p>Here's how I got the name and country of some retired footballers from a <code>$retiredFootballers</code> array:</p>
<pre><code class="lang-php">$retiredFootballers = [
 [
   <span class="hljs-string">"name"</span> =&gt; <span class="hljs-string">"Pele"</span>,
   <span class="hljs-string">"position"</span> =&gt; <span class="hljs-string">"Forward"</span>,
   <span class="hljs-string">"country"</span> =&gt; <span class="hljs-string">"Brazil"</span>,
   <span class="hljs-string">"club"</span> =&gt; <span class="hljs-string">"Santos"</span>
 ],


 [
   <span class="hljs-string">"name"</span> =&gt; <span class="hljs-string">"Diego Maradona"</span>,
   <span class="hljs-string">"position"</span> =&gt; <span class="hljs-string">"Attacking Midfielder"</span>,
   <span class="hljs-string">"country"</span> =&gt; <span class="hljs-string">"Argentina"</span>,
   <span class="hljs-string">"club"</span> =&gt; <span class="hljs-string">"Napoli"</span>
 ],


 [
   <span class="hljs-string">"name"</span> =&gt; <span class="hljs-string">"Zinedine Zidane"</span>,
   <span class="hljs-string">"position"</span> =&gt; <span class="hljs-string">"Midfielder"</span>,
   <span class="hljs-string">"country"</span> =&gt; <span class="hljs-string">"France"</span>,
   <span class="hljs-string">"club"</span> =&gt; <span class="hljs-string">"Real Madrid"</span>
 ],


 [
   <span class="hljs-string">"name"</span> =&gt; <span class="hljs-string">"Ronaldinho"</span>,
   <span class="hljs-string">"position"</span> =&gt; <span class="hljs-string">"Attacking Midfielder"</span>,
   <span class="hljs-string">"country"</span> =&gt; <span class="hljs-string">"Brazil"</span>,
   <span class="hljs-string">"club"</span> =&gt; <span class="hljs-string">"Barcelona"</span>
 ],


 [
   <span class="hljs-string">"name"</span> =&gt; <span class="hljs-string">"David Beckham"</span>,
   <span class="hljs-string">"position"</span> =&gt; <span class="hljs-string">"Midfielder"</span>,
   <span class="hljs-string">"country"</span> =&gt; <span class="hljs-string">"England"</span>,
   <span class="hljs-string">"club"</span> =&gt; <span class="hljs-string">"Manchester United"</span>
 ],
 [
   <span class="hljs-string">"name"</span> =&gt; <span class="hljs-string">"Jay-Jay Okocha"</span>,
   <span class="hljs-string">"position"</span> =&gt; <span class="hljs-string">"Midfielder"</span>,
   <span class="hljs-string">"country"</span> =&gt; <span class="hljs-string">"Nigeria"</span>,
   <span class="hljs-string">"club"</span> =&gt; <span class="hljs-string">"Bolton Wanderers"</span>
 ]
];


<span class="hljs-keyword">for</span> ($i = <span class="hljs-number">0</span>; $i &lt; count($retiredFootballers); $i++) {
 <span class="hljs-keyword">echo</span> $retiredFootballers[$i][<span class="hljs-string">"name"</span>] . <span class="hljs-string">" is from "</span> . $retiredFootballers[$i][<span class="hljs-string">"country"</span>] . <span class="hljs-string">"&lt;br&gt;"</span>;
 <span class="hljs-keyword">echo</span> <span class="hljs-string">"&lt;hr&gt;"</span>;
}
</code></pre>
<p>Doing the same with <code>foreach()</code> is cleaner because you don't need an <code>$i</code> variable:</p>
<pre><code class="lang-php"><span class="hljs-keyword">foreach</span> ($retiredFootballers <span class="hljs-keyword">as</span> $retiredFootballer) {
 <span class="hljs-keyword">echo</span> $retiredFootballer[<span class="hljs-string">"name"</span>] . <span class="hljs-string">" is from "</span> . $retiredFootballer[<span class="hljs-string">"country"</span>] . <span class="hljs-string">"&lt;br&gt;"</span>;
 <span class="hljs-keyword">echo</span> <span class="hljs-string">"&lt;hr&gt;"</span>;
}
</code></pre>
<h3 id="heading-how-to-loop-through-an-array-inside-the-html-template">How to Loop through an Array Inside the HTML Template</h3>
<p>Any HTML in your PHP file is the template for that PHP file. This means you can do the looping inside the HTML, because you can write PHP inside that HTML.</p>
<p>Here's how you can do that:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
$retiredBallers = [<span class="hljs-string">"Pele"</span>, <span class="hljs-string">"Maradona"</span>, <span class="hljs-string">"Zidane"</span>, <span class="hljs-string">"Lampard"</span>, <span class="hljs-string">"Okocha"</span>];
<span class="hljs-meta">?&gt;</span>

&lt;h1 <span class="hljs-class"><span class="hljs-keyword">class</span>="<span class="hljs-title">text</span>-<span class="hljs-title">center</span> <span class="hljs-title">mt</span>-3 <span class="hljs-title">bd</span>-<span class="hljs-title">highlight</span>"&gt;<span class="hljs-title">Looping</span> <span class="hljs-title">Through</span> <span class="hljs-title">Arrays</span> <span class="hljs-title">in</span> <span class="hljs-title">PHP</span>&lt;/<span class="hljs-title">h1</span>&gt;

 &lt;<span class="hljs-title">h2</span> <span class="hljs-title">class</span>="<span class="hljs-title">mx</span>-5 <span class="hljs-title">mt</span>-5"&gt;<span class="hljs-title">Some</span> <span class="hljs-title">Retired</span> <span class="hljs-title">Footballers</span>&lt;/<span class="hljs-title">h2</span>&gt;

 &lt;<span class="hljs-title">ul</span> <span class="hljs-title">class</span>="<span class="hljs-title">list</span>-<span class="hljs-title">group</span> <span class="hljs-title">mx</span>-5" <span class="hljs-title">style</span>="<span class="hljs-title">width</span>: 25%;"&gt;
   &lt;!-- <span class="hljs-title">The</span> <span class="hljs-title">loop</span> --&gt;
   &lt;?<span class="hljs-title">php</span> <span class="hljs-title">for</span> ($<span class="hljs-title">i</span> = 0; $<span class="hljs-title">i</span> &lt; <span class="hljs-title">count</span>($<span class="hljs-title">retiredBallers</span>); $<span class="hljs-title">i</span>++) : ?&gt;
     &lt;<span class="hljs-title">li</span> <span class="hljs-title">class</span>="<span class="hljs-title">list</span>-<span class="hljs-title">group</span>-<span class="hljs-title">item</span>"&gt; &lt;?= $<span class="hljs-title">retiredBallers</span>[$<span class="hljs-title">i</span>] ?&gt; &lt;/<span class="hljs-title">li</span>&gt;
   &lt;?<span class="hljs-title">php</span> <span class="hljs-title">endfor</span>; ?&gt;
 &lt;/<span class="hljs-title">ul</span>&gt;</span>
</code></pre>
<p>You can do the same with <code>foreach()</code>:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
$retiredBallers = [<span class="hljs-string">"Pele"</span>, <span class="hljs-string">"Maradona"</span>, <span class="hljs-string">"Zidane"</span>, <span class="hljs-string">"Lampard"</span>, <span class="hljs-string">"Okocha"</span>];
<span class="hljs-meta">?&gt;</span>

&lt;h1 <span class="hljs-class"><span class="hljs-keyword">class</span>="<span class="hljs-title">text</span>-<span class="hljs-title">center</span> <span class="hljs-title">mt</span>-3 <span class="hljs-title">bd</span>-<span class="hljs-title">highlight</span>"&gt;<span class="hljs-title">Looping</span> <span class="hljs-title">Through</span> <span class="hljs-title">Arrays</span> <span class="hljs-title">in</span> <span class="hljs-title">PHP</span>&lt;/<span class="hljs-title">h1</span>&gt;

 &lt;<span class="hljs-title">h2</span> <span class="hljs-title">class</span>="<span class="hljs-title">mx</span>-5 <span class="hljs-title">mt</span>-5"&gt;<span class="hljs-title">Some</span> <span class="hljs-title">Retired</span> <span class="hljs-title">Footballers</span>&lt;/<span class="hljs-title">h2</span>&gt;


 &lt;<span class="hljs-title">ul</span> <span class="hljs-title">class</span>="<span class="hljs-title">list</span>-<span class="hljs-title">group</span> <span class="hljs-title">mx</span>-5" <span class="hljs-title">style</span>="<span class="hljs-title">width</span>: 25%;"&gt;
   &lt;!-- <span class="hljs-title">The</span> <span class="hljs-title">loop</span> --&gt;
   &lt;?<span class="hljs-title">php</span> <span class="hljs-title">foreach</span> ($<span class="hljs-title">retiredBallers</span> <span class="hljs-title">as</span> $<span class="hljs-title">retiredBaller</span>) : ?&gt;
     &lt;<span class="hljs-title">li</span> <span class="hljs-title">class</span>="<span class="hljs-title">list</span>-<span class="hljs-title">group</span>-<span class="hljs-title">item</span>"&gt; &lt;?= $<span class="hljs-title">retiredBaller</span> ?&gt; &lt;/<span class="hljs-title">li</span>&gt;
   &lt;?<span class="hljs-title">php</span> <span class="hljs-title">endforeach</span>; ?&gt;
 &lt;/<span class="hljs-title">ul</span>&gt;</span>
</code></pre>
<p>Here's what that looks like in the browser:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/image4.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Looping through arrays using PHP for loop inside HTML</em></p>
<p>Let's use <code>foreach()</code> to display the <code>$retiredFootballers</code> associative array too:</p>
<pre><code class="lang-php">&lt;h1 <span class="hljs-class"><span class="hljs-keyword">class</span>="<span class="hljs-title">text</span>-<span class="hljs-title">center</span> <span class="hljs-title">mt</span>-3 <span class="hljs-title">bd</span>-<span class="hljs-title">highlight</span>"&gt;<span class="hljs-title">Looping</span> <span class="hljs-title">Through</span> <span class="hljs-title">Arrays</span> <span class="hljs-title">in</span> <span class="hljs-title">PHP</span>&lt;/<span class="hljs-title">h1</span>&gt;


 &lt;<span class="hljs-title">h2</span> <span class="hljs-title">class</span>="<span class="hljs-title">mx</span>-5 <span class="hljs-title">mt</span>-5"&gt;<span class="hljs-title">Some</span> <span class="hljs-title">Retired</span> <span class="hljs-title">Footballers</span>&lt;/<span class="hljs-title">h2</span>&gt;


 &lt;<span class="hljs-title">ul</span> <span class="hljs-title">class</span>="<span class="hljs-title">list</span>-<span class="hljs-title">group</span> <span class="hljs-title">mx</span>-5" <span class="hljs-title">style</span>="<span class="hljs-title">width</span>: 25%;"&gt;
   &lt;!-- <span class="hljs-title">The</span> <span class="hljs-title">loop</span> --&gt;
   &lt;?<span class="hljs-title">php</span> <span class="hljs-title">foreach</span> ($<span class="hljs-title">retiredFootballers</span> <span class="hljs-title">as</span> $<span class="hljs-title">retiredFootballer</span>) : ?&gt;
     &lt;<span class="hljs-title">li</span> <span class="hljs-title">class</span>="<span class="hljs-title">list</span>-<span class="hljs-title">group</span>-<span class="hljs-title">item</span>"&gt; &lt;?= $<span class="hljs-title">retiredFootballer</span>["<span class="hljs-title">name</span>"] . " <span class="hljs-title">is</span> <span class="hljs-title">from</span> " . $<span class="hljs-title">retiredFootballer</span>["<span class="hljs-title">country</span>"] ?&gt; &lt;/<span class="hljs-title">li</span>&gt;
   &lt;?<span class="hljs-title">php</span> <span class="hljs-title">endforeach</span>; ?&gt;
 &lt;/<span class="hljs-title">ul</span>&gt;</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/image1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Looping through arrays using PHP foreach function inside HTML</em></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Learning how to work with arrays is a foundational step toward proficiency in PHP and web development. That's why this handbook walked you through the various capabilities of PHP arrays, from creation to manipulation and looping.</p>
<p>You should now be confident using arrays to effectively manage data in PHP, whether for simple lists with indexed arrays, or complex structures with associative and multidimensional arrays.</p>
<p>Moving forward, I encourage you to experiment with various array functions to improve your code and tackle different programming challenges. Also, consider exploring multidimensional and associative arrays for more complex data scenarios.</p>
<p>As you grow more proficient with PHP arrays, integrating them with database operations can further enhance your web applications. A good example is MongoDB, a NoSQL database that integrates seamlessly with PHP. Check out the <a target="_blank" href="https://www.mongodb.com/docs/languages/php/">MongoDB PHP docs</a> for more info.  </p>
<p>Also, look out for the second article of this series.</p>
<p>Keep coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ JavaScript Tips to Help You Build Better Web Development Projects ]]>
                </title>
                <description>
                    <![CDATA[ JavaScript is a widely used web programming language. If you're getting into software engineering or coding in particular and you want to focus on web development, learning JavaScript is probably the best thing to do. Learning JavaScript empowers you... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/javascript-tips-for-better-web-dev-projects/</link>
                <guid isPermaLink="false">66adf1966f5e63db3fc4362c</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Tue, 15 Aug 2023 14:17:37 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/08/start-graph--15-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>JavaScript is a widely used web programming language. If you're getting into software engineering or coding in particular and you want to focus on web development, learning JavaScript is probably the best thing to do.</p>
<p>Learning JavaScript empowers you to create dynamic and interactive web experiences. And it lets you to bring websites and web applications to life by adding functionality, interactivity, and real-time updates for a better user experience. </p>
<p>I recently had a <strong>30 Days of JavaScript Tips</strong> challenge on Twitter (now, X) where I shared 30 different JavaScript tips with my followers daily for 30 days. I decided to compile those tips into one giant tutorial for campers and everyone else on the internet. That's why you're reading this.</p>
<p>Whether you're just getting started with JavaScript or you're already a seasoned JavaScript developer, you will take something away from this article.</p>
<h2 id="heading-what-well-cover">What We'll Cover</h2>
<ul>
<li><a class="post-section-overview" href="#heading-tip-1-use-consoletable-to-display-arrays-and-objects-in-the-console">Tip 1: Use <code>console.table()</code> to Display Arrays and Objects in the Console</a></li>
<li><a class="post-section-overview" href="#heading-tip-2-use-template-interpolation-to-render-strings-instead-of-the-assignment-operator">Tip 2: Use Template Interpolation to Render Strings Instead of the Assignment Operator</a></li>
<li><a class="post-section-overview" href="#heading-tip-3-convert-strings-to-numbers-with-unary-plus-and-number-constructor">Tip 3: Convert Strings to Numbers with Unary Plus and Number Constructor</a></li>
<li><a class="post-section-overview" href="#heading-tip-4-you-dont-need-to-declare-every-variable-with-a-keyword">Tip 4: You Don’t Need to Declare Every Variable with a Keyword</a></li>
<li><a class="post-section-overview" href="#tip5useconsolegroupwithmultipleconsolelogtogrouprelateditemstotheconsole">Tip 5: Use <code>console.group()</code> with Multiple <code>console.log()</code> to Group Related Items to the Console</a></li>
<li><a class="post-section-overview" href="#heading-tip-6-style-your-console-output-with-the-c-specifier">Tip 6: Style your Console Output with the <code>%c</code> Specifier</a></li>
<li><a class="post-section-overview" href="#heading-tip-7-how-mathfloormathrandom-n1-n2-generates-a-random-number-between-n1-and-n2">Tip 7: How <code>Math.floor(Math.random() * n1 + n2)</code> Generates a Random Number Between <code>n1</code> and <code>n2</code></a></li>
<li><a class="post-section-overview" href="#heading-tip-8-methods-of-the-math-object">Tip 8: Methods of the Math Object</a></li>
<li><a class="post-section-overview" href="#heading-tip-9-capitalize-the-first-letter-of-any-word">Tip 9: Capitalize the First Letter of Any Word</a></li>
<li><a class="post-section-overview" href="#heading-tip-10-destructure-arrays-with-default-values-to-avoid-getting-undefined">Tip 10: Destructure Arrays with Default Values to Avoid Getting <code>undefined</code></a></li>
<li><a class="post-section-overview" href="#heading-tip-11-use-the-spread-operator-to-copy-and-merge-arrays">Tip 11: Use the Spread Operator to Copy and Merge Arrays</a></li>
<li><a class="post-section-overview" href="#heading-tip-12-use-arrow-syntax-to-write-shorter-and-more-elegant-functions">Tip 12: Use Arrow Syntax to Write Shorter and More Elegant Functions</a></li>
<li><a class="post-section-overview" href="#heading-tip-13-use-destructuring-to-extract-properties-from-objects">Tip 13: Use Destructuring to Extract Properties from Objects</a></li>
<li><a class="post-section-overview" href="#heading-tip-14-use-the-startswith-and-endswith-string-methods-to-get-the-start-and-end-of-a-string">Tip 14: Use the <code>startsWith()</code> and <code>endsWith()</code> String Methods to Get the Start and End of a String</a></li>
<li><a class="post-section-overview" href="#heading-tip-15-use-the-trim-trimstart-and-trimend-to-handle-white-spaces">Tip 15: Use the <code>trim()</code>, <code>trimStart()</code>, and <code>trimEnd()</code> to Handle White Spaces</a></li>
<li><a class="post-section-overview" href="#heading-tip-16-use-replace-with-the-touppercase-and-tolowercase-methods-to-convert-between-cases">Tip 16: Use <code>replace()</code> with the <code>toUpperCase()</code> and <code>toLowerCase()</code> Methods to Convert Between Cases</a></li>
<li><a class="post-section-overview" href="#tip17usethearrayfrommethodtocreatearraysfromarray-likeobjectsoriterables">Tip 17: Use the <code>Array.from()</code> Method to Create Arrays from Array-like Objects or Iterables</a></li>
<li><a class="post-section-overview" href="#heading-tip-18-use-the-map-method-to-transform-all-the-elements-of-an-array">Tip 18: Use the <code>map()</code> Method to Transform all the Elements of an Array</a></li>
<li><a class="post-section-overview" href="#heading-tip-19-use-the-filter-method-to-filter-through-arrays">Tip 19: Use the <code>filter()</code> Method to Filter Through Arrays</a></li>
<li><a class="post-section-overview" href="#heading-tip-21-use-the-web-audio-api-to-work-with-audio-files">Tip 21: Use the Web Audio API to Work with Audio Files</a></li>
<li><a class="post-section-overview" href="#heading-tip-22-use-the-web-video-api-to-work-with-video-files">Tip 22: Use the Web Video API to Work with Video Files</a></li>
<li><a class="post-section-overview" href="#heading-tip-23-preserve-object-integrity-by-sealing-and-freezing-them">Tip 23: Preserve Object Integrity by Sealing and Freezing Them</a></li>
<li><a class="post-section-overview" href="#tip24use`asyncawait`forasynchronousoperations">Tip 24: Use <code>async...await</code> For Asynchronous Operations</a></li>
<li><a class="post-section-overview" href="#heading-tip-25-clone-objects-with-the-spread-operator-objectassign-and-jsonparse">Tip 25: Clone Objects with the Spread Operator, <code>Object.assign()</code>, and <code>JSON.parse()</code></a></li>
<li><a class="post-section-overview" href="#heading-tip-26-remove-duplicates-from-an-array-with-set-and-map">Tip 26: Remove Duplicates from an Array with Set and Map</a></li>
<li><a class="post-section-overview" href="#heading-tip-27-map-through-and-array-and-flatten-it-with-the-flatmap-method">Tip 27: Map Through and Array and Flatten it with the <code>flatMap()</code> Method</a></li>
<li><a class="post-section-overview" href="#ip28usethepadstartandpadendmethodstopadastringwithacharacter">ip 28: Use the <code>padStart()</code> and <code>padEnd()</code> Methods to Pad a string with a Character</a></li>
<li><a class="post-section-overview" href="#heading-tip-29-use-the-insertadjacenthtml-method-of-dom-to-insert-a-string-into-the-dom">Tip 29: Use the <code>insertAdjacentHTML()</code> method of DOM to Insert a String into the DOM</a></li>
<li><a class="post-section-overview" href="#heading-tip-30-use-the-createtreewalker-dom-method-to-traverse-the-dom">Tip 30: Use the <code>createTreeWalker()</code> DOM Method to Traverse the DOM</a></li>
</ul>
<h2 id="heading-tip-1-use-consoletable-to-display-arrays-and-objects-in-the-console">Tip 1: Use <code>console.table()</code> to Display Arrays and Objects in the Console</h2>
<p><code>console.log</code> will display the array or object as usual, but <code>console.table</code> will tabularize the index and values for you.</p>
<p>Here's how it works with arrays:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myArr = [<span class="hljs-string">'Kolade'</span>, <span class="hljs-string">'Chelsea'</span>, <span class="hljs-number">10</span>, <span class="hljs-literal">true</span>];

<span class="hljs-built_in">console</span>.log(myArr);
<span class="hljs-built_in">console</span>.table(myArr);
</code></pre>
<p>Here's the output of <code>console.log()</code> and <code>console.table()</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/ss1.png" alt="ss1" width="600" height="400" loading="lazy"></p>
<p>You can see that in addition to tabularizing the array for you, it also shows it the way a <code>console.log()</code> would show it.</p>
<p>It works with objects the same way it works with arrays:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myObj = {
  <span class="hljs-attr">name</span>: <span class="hljs-string">'Kolade'</span>,
  <span class="hljs-attr">luckyNum</span>: <span class="hljs-number">10</span>,
  <span class="hljs-attr">lovesFootball</span>: <span class="hljs-literal">true</span>,
};

<span class="hljs-built_in">console</span>.log(myObj);
<span class="hljs-built_in">console</span>.table(myObj);
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/ss2.png" alt="ss2" width="600" height="400" loading="lazy"></p>
<h2 id="heading-tip-2-use-template-interpolation-to-render-strings-instead-of-the-assignment-operator">Tip 2: Use Template Interpolation to Render Strings Instead of the Assignment Operator</h2>
<p>The template interpolation syntax is cleaner and more readable than the regular concatenation with plus (<code>+</code>). With template interpolation, you can conveniently embed variables in strings.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> name = <span class="hljs-string">'John Doe'</span>;
<span class="hljs-keyword">const</span> age = <span class="hljs-number">20</span>;

<span class="hljs-keyword">const</span> plusConcat =
  <span class="hljs-string">'Hi there 👋🏽 \nMy name is '</span> + name + <span class="hljs-string">' and I am '</span> + age + <span class="hljs-string">' years old.'</span>;

<span class="hljs-keyword">const</span> templateLiteralConcat = <span class="hljs-string">`Hi there 👋🏽 \nMy name is, <span class="hljs-subst">${name}</span> and I am <span class="hljs-subst">${age}</span> years old.`</span>;
</code></pre>
<h2 id="heading-tip-3-convert-strings-to-numbers-with-unary-plus-and-number-constructor">Tip 3: Convert Strings to Numbers with Unary Plus and Number Constructor</h2>
<p>The unary plus operator (<code>+</code>) and number constructor (<code>Number()</code>) help you convert strings to numbers.</p>
<p>To convert the string to a number with unary, all you need to do is prepend the string with a plus sign. And to do it with the number constructor, wrap the number in <code>Number()</code></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myNum = <span class="hljs-string">'5'</span>;

convertNum1 = +myNum;
convertNum2 = <span class="hljs-built_in">Number</span>(myNum);

<span class="hljs-built_in">console</span>.log(convertNum1, <span class="hljs-keyword">typeof</span> convertNum1); <span class="hljs-comment">// 5 'number'</span>
<span class="hljs-built_in">console</span>.log(convertNum2, <span class="hljs-keyword">typeof</span> convertNum2); <span class="hljs-comment">// 5 'number'</span>
</code></pre>
<h2 id="heading-tip-4-you-dont-need-to-declare-every-variable-with-a-keyword">Tip 4: You Don’t Need to Declare Every Variable with a Keyword</h2>
<p>Did you know that if you have multiple variables next to each other, you can avoid using <code>const</code>, <code>let</code>, or <code>var</code> to declare every variable after the first one? </p>
<p>The only caveat is that if you're declaring variables without a keyword, you must separate them with a comma (<code>,</code>) instead of a semi-colon.</p>
<p>This is it:</p>
<pre><code class="lang-js"><span class="hljs-comment">// declare multiple variables at once.</span>
<span class="hljs-keyword">let</span> x, y, z;

x = <span class="hljs-number">1</span>;
y = <span class="hljs-number">2</span>;
z = <span class="hljs-number">3</span>;

<span class="hljs-built_in">console</span>.log(x, y, z); <span class="hljs-comment">// 1, 2, 3</span>

<span class="hljs-comment">// declare other variables after the first one without the keyword.</span>
<span class="hljs-keyword">const</span> a = <span class="hljs-string">'Hello'</span>,
  b = <span class="hljs-string">'How are you today?'</span>,
  c = <span class="hljs-string">'Are you coding today?'</span>;

<span class="hljs-built_in">console</span>.log(a); <span class="hljs-comment">// Hello</span>
<span class="hljs-built_in">console</span>.log(b); <span class="hljs-comment">// How are you today?</span>
<span class="hljs-built_in">console</span>.log(c); <span class="hljs-comment">// Are you coding today?</span>
</code></pre>
<p>The above is the same as:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> x;
<span class="hljs-keyword">let</span> y;
<span class="hljs-keyword">let</span> z;

x = <span class="hljs-number">1</span>;
y = <span class="hljs-number">2</span>;
z = <span class="hljs-number">3</span>;

<span class="hljs-built_in">console</span>.log(x, y, z); <span class="hljs-comment">// 1, 2, 3</span>

<span class="hljs-comment">// declare other variables after the first one without the keyword.</span>
<span class="hljs-keyword">const</span> a = <span class="hljs-string">'Hello'</span>;
<span class="hljs-keyword">const</span> b = <span class="hljs-string">'How are you today?'</span>;
<span class="hljs-keyword">const</span> c = <span class="hljs-string">'Are you coding today?'</span>;

<span class="hljs-built_in">console</span>.log(a); <span class="hljs-comment">// Hello</span>
<span class="hljs-built_in">console</span>.log(b); <span class="hljs-comment">// How are you today?</span>
<span class="hljs-built_in">console</span>.log(c); <span class="hljs-comment">// Are you coding today?</span>
</code></pre>
<h2 id="heading-tip-5-use-consolegroup-with-multiple-consolelogs-to-group-related-items-to-the-console">Tip 5: Use <code>console.group()</code> with Multiple <code>console.log()</code>s to Group Related Items to the Console</h2>
<p>When you have multiple related items like username, bio, and so on and you want to log them to the console, you should use <code>console.group()</code> and <code>console.groupEnd()</code> to close the group. </p>
<p>This will give you a drop down list of all the items:</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.group(<span class="hljs-string">'Bio:'</span>);

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'My name is Kolade'</span>);
<span class="hljs-built_in">console</span>.warn(<span class="hljs-string">"I don't like to be late"</span>);
<span class="hljs-built_in">console</span>.error(<span class="hljs-string">'You came late'</span>);

<span class="hljs-built_in">console</span>.groupEnd();
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/ss3.png" alt="ss3" width="600" height="400" loading="lazy"></p>
<h2 id="heading-tip-6-style-your-console-output-with-the-c-specifier">Tip 6: Style your Console Output with the <code>%c</code> Specifier</h2>
<p><code>%c</code> is not a part of JavaScript itself. It's a format specifier provided by modern browsers for styling the console. Whne you want to use it, it has to be the first parameter in the <code>console.log()</code> method.</p>
<p>You can set the styling you want to apply to the console:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> styles = <span class="hljs-string">`padding: 15px;
                background-color: #2ecc71;
                color: black`</span>;

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'%c Hello, Everyone!'</span>, styles);
</code></pre>
<p>Or you can put it in directly:</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(
  <span class="hljs-string">'%c Hello, Everyone!'</span>,
  <span class="hljs-string">'padding: 15px; background-color: #2ecc71; color: black'</span>
);
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/ss4.png" alt="ss4" width="600" height="400" loading="lazy"></p>
<h2 id="heading-tip-7-how-mathfloormathrandom-n1-n2-generates-a-random-number-between-n1-and-n2">Tip 7: How <code>Math.floor(Math.random() * n1 + n2)</code> Generates a Random Number Between <code>n1</code> and <code>n2</code></h2>
<p>You've probably seen how <code>Math.floor(Math.random() * n1 + n2)</code> creates a random number between 2 numbers. You could have even used it yourself. But how does it work?</p>
<p>For example, <code>Math.floor(Math.random() * 100 + 1)</code> would generate a random number between <code>100</code> and <code>1</code>, after it follows these processes:</p>
<ul>
<li><code>Math.random()</code> generates a random floating point number between 0 and 1 – <code>0</code> inclusive but 1 exclusive</li>
<li>With <code>Math.random() * 100</code>, the random number is now between <code>0</code> and <code>99</code> but still has long floating points</li>
<li><code>Math.floor(Math.random() * 100)</code> rounds the floating point number to the nearest integer between <code>0</code> and <code>99</code></li>
<li><code>Math.floor(Math.random() * 100 + 1)</code> adds <code>1</code> to the result and shifts the range to <code>1 - 100</code>.</li>
</ul>
<p>This infographic below also shows you how it works:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/generateRandomNum.png" alt="generateRandomNum" width="600" height="400" loading="lazy"></p>
<h2 id="heading-tip-8-methods-of-the-math-object">Tip 8: Methods of the Math Object</h2>
<p>Here are several methods of the <code>Math</code> object and what they do:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> x;

<span class="hljs-comment">// Get the square root of a number</span>
x = <span class="hljs-built_in">Math</span>.sqrt(<span class="hljs-number">9</span>);

<span class="hljs-comment">// convert a number to absolute value</span>
x = <span class="hljs-built_in">Math</span>.abs(<span class="hljs-number">-5</span>); <span class="hljs-comment">// 5</span>

<span class="hljs-comment">// Round up a number to the nearest whole number</span>
x = <span class="hljs-built_in">Math</span>.round(<span class="hljs-number">4.6</span>);

<span class="hljs-comment">// Round up a number</span>
x = <span class="hljs-built_in">Math</span>.ceil(<span class="hljs-number">4.2</span>); <span class="hljs-comment">// 5</span>

<span class="hljs-comment">// Round down a number</span>
x = <span class="hljs-built_in">Math</span>.floor(<span class="hljs-number">4.9</span>); <span class="hljs-comment">// 4</span>

<span class="hljs-comment">// Exponent of a number</span>
x = <span class="hljs-built_in">Math</span>.pow(<span class="hljs-number">2</span>, <span class="hljs-number">3</span>); <span class="hljs-comment">// 8</span>

<span class="hljs-comment">// Get the minimum number</span>
x = <span class="hljs-built_in">Math</span>.min(<span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">3</span>); <span class="hljs-comment">// 3</span>

<span class="hljs-comment">// Get the maximum number</span>
x = <span class="hljs-built_in">Math</span>.max(<span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">3</span>); <span class="hljs-comment">// 5</span>

<span class="hljs-comment">// Get a random number/decimal between 0 and 1</span>
x = <span class="hljs-built_in">Math</span>.random();

<span class="hljs-comment">// Get a random number between 1 and 200</span>
x = <span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * <span class="hljs-number">200</span> + <span class="hljs-number">1</span>); <span class="hljs-comment">// any number between and 200</span>

<span class="hljs-built_in">console</span>.log(x);
</code></pre>
<h2 id="heading-tip-9-capitalize-the-first-letter-of-any-word">Tip 9: Capitalize the First Letter of Any Word</h2>
<p>You can capitalize the first letter of any word by combining the <code>chartAt()</code>, <code>toUpperCase()</code>, and <code>slice()</code> methods.</p>
<p>With <code>chartAt(0)</code>, you can get the first letter of the word and use the <code>toUpperCase()</code> method with it, then concatenate the rest of the letters with <code>slice(1)</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> str = <span class="hljs-string">'john'</span>;
<span class="hljs-keyword">const</span> capitalizedStr = <span class="hljs-function">(<span class="hljs-params">str</span>) =&gt;</span> str.charAt(<span class="hljs-number">0</span>).toUpperCase() + str.slice(<span class="hljs-number">1</span>);

<span class="hljs-built_in">console</span>.log(capitalizedStr(str)); <span class="hljs-comment">// John</span>
<span class="hljs-built_in">console</span>.log(capitalizedStr(<span class="hljs-string">'doe'</span>)); <span class="hljs-comment">// Doe</span>
</code></pre>
<h2 id="heading-tip-10-destructure-arrays-with-default-values-to-avoid-getting-undefined">Tip 10: Destructure Arrays with Default Values to Avoid Getting <code>undefined</code></h2>
<p>If you destructure with a default value, and the expected value is not present in the array or object during destructuring, the default value will be used instead. This helps prevent errors and ensures that your code gracefully handles missing data.</p>
<p>This is how it works with arrays:</p>
<pre><code class="lang-js"><span class="hljs-comment">// Destructuring without default values</span>
<span class="hljs-keyword">const</span> fruits = [<span class="hljs-string">'Apple'</span>, <span class="hljs-string">'Banana'</span>];
<span class="hljs-keyword">const</span> [firstFruit, secondFruit, thirdFruit] = fruits;

<span class="hljs-built_in">console</span>.log(firstFruit); <span class="hljs-comment">// Apple</span>
<span class="hljs-built_in">console</span>.log(secondFruit); <span class="hljs-comment">// Banana</span>
<span class="hljs-built_in">console</span>.log(thirdFruit); <span class="hljs-comment">// undefined</span>

<span class="hljs-comment">// Destructuring with default values</span>
<span class="hljs-keyword">const</span> [fruit1, fruit2, fruit3 = <span class="hljs-string">'Orange'</span>] = fruits;

<span class="hljs-built_in">console</span>.log(fruit1); <span class="hljs-comment">// Apple</span>
<span class="hljs-built_in">console</span>.log(fruit2); <span class="hljs-comment">// Banana</span>
<span class="hljs-built_in">console</span>.log(fruit3); <span class="hljs-comment">// Orange</span>
</code></pre>
<p>And this is how it works with objects:</p>
<pre><code class="lang-js"><span class="hljs-comment">// Without default values</span>
<span class="hljs-keyword">const</span> person = { <span class="hljs-attr">name</span>: <span class="hljs-string">'John Doe'</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">30</span> };
<span class="hljs-keyword">const</span> { name, age, occupation } = person;
<span class="hljs-built_in">console</span>.log(name); <span class="hljs-comment">// John Doe</span>
<span class="hljs-built_in">console</span>.log(age); <span class="hljs-comment">// 30</span>
<span class="hljs-built_in">console</span>.log(occupation); <span class="hljs-comment">// undefined</span>

<span class="hljs-comment">// With default values</span>
<span class="hljs-keyword">const</span> { firstName = <span class="hljs-string">'John'</span>, lastName = <span class="hljs-string">'Doe'</span>, gender = <span class="hljs-string">'Male'</span> } = person;
<span class="hljs-built_in">console</span>.log(firstName); <span class="hljs-comment">// John</span>
<span class="hljs-built_in">console</span>.log(lastName); <span class="hljs-comment">// Doe</span>
<span class="hljs-built_in">console</span>.log(gender); <span class="hljs-comment">// Male</span>
</code></pre>
<h2 id="heading-tip-11-use-the-spread-operator-to-copy-and-merge-arrays">Tip 11: Use the Spread Operator to Copy and Merge Arrays</h2>
<p>You can use the spread operator in various scenarios, such as copying arrays, merging arrays, cloning objects, and passing multiple arguments to functions.</p>
<p>Here's how to use it to copy and merge arrays:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> originalArray = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];
<span class="hljs-keyword">const</span> copiedArray = [...originalArray];

<span class="hljs-built_in">console</span>.log(copiedArray); <span class="hljs-comment">// [1, 2, 3]</span>

<span class="hljs-comment">// merge two or more arrays</span>
<span class="hljs-keyword">const</span> arr1 = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];
<span class="hljs-keyword">const</span> arr2 = [<span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>];

<span class="hljs-keyword">const</span> mergedArray = [...arr1, ...arr2];

<span class="hljs-built_in">console</span>.log(mergedArray); <span class="hljs-comment">// [1, 2, 3, 4, 5, 6</span>
</code></pre>
<p>Here's how you can clone objects with it:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> originalObj = { <span class="hljs-attr">name</span>: <span class="hljs-string">'John'</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">30</span> };
<span class="hljs-keyword">const</span> clonedObj = { ...originalObj };

<span class="hljs-built_in">console</span>.log(clonedObj); <span class="hljs-comment">// { name: 'John', age: 30 }</span>
</code></pre>
<p>And below is how you can use it to pass multiple arguments into any function:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addNumbers</span>(<span class="hljs-params">a, b, c</span>) </span>{
  <span class="hljs-keyword">return</span> a + b + c;
}

<span class="hljs-keyword">const</span> numbers = [<span class="hljs-number">10</span>, <span class="hljs-number">12</span>, <span class="hljs-number">8</span>];
<span class="hljs-keyword">const</span> sum = addNumbers(...numbers);

<span class="hljs-built_in">console</span>.log(sum); <span class="hljs-comment">// 30</span>
</code></pre>
<h2 id="heading-tip-12-use-arrow-syntax-to-write-shorter-and-more-elegant-functions">Tip 12: Use Arrow Syntax to Write Shorter and More Elegant Functions</h2>
<p>Arrow functions provide a shorter syntax compared to traditional function expressions and have some unique features. Understanding arrow functions is essential for modern JavaScript development.</p>
<pre><code class="lang-js"><span class="hljs-comment">// Traditional Function Expression</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">add1</span>(<span class="hljs-params">a, b</span>) </span>{
  <span class="hljs-keyword">return</span> a + b;
}

<span class="hljs-comment">// Arrow Function</span>
<span class="hljs-keyword">const</span> add2 = <span class="hljs-function">(<span class="hljs-params">a, b</span>) =&gt;</span> a + b;

<span class="hljs-built_in">console</span>.log(add1(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>)); <span class="hljs-comment">// 3</span>
<span class="hljs-built_in">console</span>.log(add2(<span class="hljs-number">5</span>, <span class="hljs-number">8</span>)); <span class="hljs-comment">// 13</span>

<span class="hljs-comment">// Using Traditional Function Expression</span>
<span class="hljs-keyword">const</span> numbers1 = [<span class="hljs-number">3</span>, <span class="hljs-number">4</span>];
<span class="hljs-keyword">const</span> numbers2 = [<span class="hljs-number">2</span>, <span class="hljs-number">8</span>];

<span class="hljs-keyword">const</span> squared1 = numbers1.map(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">num</span>) </span>{
  <span class="hljs-keyword">return</span> num * num;
});

<span class="hljs-comment">// Using Arrow Function</span>
<span class="hljs-keyword">const</span> squared2 = numbers2.map(<span class="hljs-function">(<span class="hljs-params">num</span>) =&gt;</span> num * num);

<span class="hljs-built_in">console</span>.log(squared1); <span class="hljs-comment">// [ 9, 16 ]</span>
<span class="hljs-built_in">console</span>.log(squared2); <span class="hljs-comment">// [ 4, 64 ]</span>
</code></pre>
<h2 id="heading-tip-13-use-destructuring-to-extract-properties-from-objects">Tip 13: Use Destructuring to Extract Properties from Objects</h2>
<p>Object destructuring is a powerful feature in JavaScript. It allows you to extract properties from objects and assign them to variables in a more concise and readable way compared to the traditional dot notation way.</p>
<p>Here's how to extract properties with destructuring:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> person = {
  <span class="hljs-attr">name</span>: <span class="hljs-string">'John Doe'</span>,
  <span class="hljs-attr">age</span>: <span class="hljs-number">30</span>,
  <span class="hljs-attr">gender</span>: <span class="hljs-string">'male'</span>,
};

<span class="hljs-comment">// Traditional way</span>
<span class="hljs-keyword">const</span> name2 = person.name;
<span class="hljs-keyword">const</span> age2 = person.age;
<span class="hljs-keyword">const</span> gender2 = person.gender;

<span class="hljs-built_in">console</span>.log(name, age, gender); <span class="hljs-comment">// John Doe 30 male</span>

<span class="hljs-comment">// with destructuring</span>
<span class="hljs-keyword">const</span> { name, age, gender } = person;

<span class="hljs-built_in">console</span>.log(name, age, gender);
<span class="hljs-comment">// John Doe 30 male</span>
</code></pre>
<h2 id="heading-tip-14-use-the-startswith-and-endswith-string-methods-to-get-the-start-and-end-of-a-string">Tip 14: Use the <code>startsWith()</code> and <code>endsWith()</code> String Methods to Get the Start and End of a String</h2>
<p>The <code>startsWith()</code> and <code>endsWith()</code> methods help you determine if a string begins or ends with a specific substring. Since they both return <code>true</code> or <code>false</code>, they are handy for various string manipulations and conditional checks.</p>
<p>Here's their basic usage:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> message = <span class="hljs-string">'Hello world'</span>;

<span class="hljs-built_in">console</span>.log(message.startsWith(<span class="hljs-string">'H'</span>)); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(message.startsWith(<span class="hljs-string">'h'</span>)); <span class="hljs-comment">// false</span>
<span class="hljs-built_in">console</span>.log(message.endsWith(<span class="hljs-string">'d'</span>)); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(message.endsWith(<span class="hljs-string">'D'</span>)); <span class="hljs-comment">// false</span>
</code></pre>
<p>With the two methods, you can programmatically extract a certain text or filename, as you can see below:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> files = [
  <span class="hljs-string">'text.txt'</span>,
  <span class="hljs-string">'document.txt'</span>,
  <span class="hljs-string">'image.jpg'</span>,
  <span class="hljs-string">'script.js'</span>,
  <span class="hljs-string">'docs.txt'</span>,
];

<span class="hljs-comment">// Get .txt files</span>
<span class="hljs-keyword">const</span> textFiles = files.filter(<span class="hljs-function">(<span class="hljs-params">file</span>) =&gt;</span> file.endsWith(<span class="hljs-string">'.txt'</span>));
<span class="hljs-built_in">console</span>.log(textFiles); [ <span class="hljs-string">'text.txt'</span>, <span class="hljs-string">'document.txt'</span>, <span class="hljs-string">'docs.txt'</span> ]
</code></pre>
<p>Both the <code>startsWith()</code> and <code>endsWith()</code> methods also support optional start and end positions to limit the range of the string where the check is performed:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> text = <span class="hljs-string">'Welcome to freeCodeCamp'</span>;

<span class="hljs-built_in">console</span>.log(text.startsWith(<span class="hljs-string">'W'</span>, <span class="hljs-number">0</span>)); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(text.startsWith(<span class="hljs-string">'freeCodeCamp'</span>, <span class="hljs-number">11</span>)); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(text.endsWith(<span class="hljs-string">'f'</span>, <span class="hljs-number">11</span>)); <span class="hljs-comment">// false</span>
</code></pre>
<h2 id="heading-tip-15-use-the-trim-trimstart-and-trimend-to-handle-white-spaces">Tip 15: Use the <code>trim()</code>, <code>trimStart()</code>, and <code>trimEnd()</code> to Handle White Spaces</h2>
<p>The <code>trim()</code> method gets rid of white spaces at both ends of the string. The <code>trimStart()</code> gets rid of white spaces at the start of the string. And <code>trimEnd()</code> removes white spaces at the end of the string.</p>
<p>These three methods are useful when you need to clean up user inputs or remove leading/trailing whitespace from strings.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> greet = <span class="hljs-string">'   Hello world!   '</span>;
<span class="hljs-built_in">console</span>.log(greet.trim());
<span class="hljs-comment">// Hello world!</span>

<span class="hljs-keyword">const</span> greet2 = <span class="hljs-string">'   Hello world!   '</span>;
<span class="hljs-built_in">console</span>.log(greet2.trimStart());
<span class="hljs-comment">// Output: 'Hello, world!   '</span>

<span class="hljs-keyword">const</span> text = <span class="hljs-string">'   Hello world!   '</span>;
<span class="hljs-built_in">console</span>.log(text.trimEnd());
<span class="hljs-comment">// Output: '   Hello world!'</span>

<span class="hljs-keyword">const</span> input = <span class="hljs-string">'   '</span>;
<span class="hljs-keyword">if</span> (input.trim() === <span class="hljs-string">''</span>) {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'The input is empty but has whitespace characters.'</span>);
} <span class="hljs-keyword">else</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'The input contains non-whitespace characters.'</span>);
}

<span class="hljs-comment">// Output: The input is empty but has whitespace characters.</span>
</code></pre>
<h2 id="heading-tip-16-use-replace-with-the-touppercase-and-tolowercase-methods-to-convert-between-cases">Tip 16: Use <code>replace()</code> with the <code>toUpperCase()</code> and <code>toLowerCase()</code> Methods to Convert Between Cases</h2>
<p>The <code>toUpperCase ()</code> and <code>toLowerCase()</code> methods convert a string to uppercase and lowercase, while <code>replace()</code> takes a string and replaces it with a specified string.</p>
<p><code>replace()</code> can also take regular expressions. So you can tailor that regex for a particular part of the string then use the <code>toLowerCase()</code> and <code>toUpperCase()</code> methods to convert between cases.</p>
<p>In the code snippet below, I used the regex <code>(^|\s)\w/</code> to look for the first word and every other word after a space, then convert them to uppercase letters:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">toTitleCase</span>(<span class="hljs-params">str</span>) </span>{
  <span class="hljs-keyword">return</span> str.toLowerCase().replace(<span class="hljs-regexp">/(^|\s)\w/g</span>, <span class="hljs-function">(<span class="hljs-params">match</span>) =&gt;</span> match.toUpperCase());
}

<span class="hljs-built_in">console</span>.log(toTitleCase(<span class="hljs-string">'welcome to twitter (now x)!'</span>));
<span class="hljs-comment">// Welcome To Twitter (now X)!</span>
</code></pre>
<p>I was also able to convert to <strong>snake_case</strong> by using the regex <code>/\s+/g</code> to look for every space and replace them with underscore (<code>_</code>)</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">toSnakeCase</span>(<span class="hljs-params">str</span>) </span>{
  <span class="hljs-keyword">return</span> str.toLowerCase().replace(<span class="hljs-regexp">/\s+/g</span>, <span class="hljs-string">'_'</span>);
}

<span class="hljs-built_in">console</span>.log(toSnakeCase(<span class="hljs-string">'Convert this to snake case'</span>));
<span class="hljs-comment">// convert_this_to_snake_case</span>
</code></pre>
<p>Don’t forget you can convert to cases without <code>replace()</code> and regex:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">toSentenceCase</span>(<span class="hljs-params">str</span>) </span>{
  <span class="hljs-keyword">return</span> str.charAt(<span class="hljs-number">0</span>).toUpperCase() + str.slice(<span class="hljs-number">1</span>).toLowerCase();
}

<span class="hljs-built_in">console</span>.log(toSentenceCase(<span class="hljs-string">'hELLo TwEePs! HOW ARE YOU TODAY?'</span>));
<span class="hljs-comment">// Hello tweeps! how are you today?</span>
</code></pre>
<p>If you want to learn more about regular expressions, you can <a target="_blank" href="https://www.freecodecamp.org/news/regular-expressions-for-javascript-developers/">read my book on them here for free</a>.</p>
<h2 id="heading-tip-17-use-the-arrayfrom-method-to-create-arrays-from-array-like-objects-or-iterables">Tip 17: Use the <code>Array.from()</code> Method to Create Arrays from Array-like Objects or Iterables</h2>
<p>Array-like objects or iterables include the multiple arguments you pass to function, and the DOM items you select with the <code>querySelectorAll()</code> method, for instance, list items.</p>
<p>This is how I created an array from a function argument and used the <code>reduce()</code> array method on them:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sumArguments</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">// The "arguments" object is array-like</span>
  <span class="hljs-keyword">const</span> argsArray = <span class="hljs-built_in">Array</span>.from(<span class="hljs-built_in">arguments</span>);
  <span class="hljs-keyword">return</span> argsArray.reduce(<span class="hljs-function">(<span class="hljs-params">acc, num</span>) =&gt;</span> acc + num, <span class="hljs-number">0</span>);
}

<span class="hljs-keyword">const</span> result = sumArguments(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>);
<span class="hljs-built_in">console</span>.log(result); <span class="hljs-comment">// Output: 15</span>
</code></pre>
<p>And this is how I created an array from from a set of list items selected with <code>quersySelectorAll()</code>:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>List item 1<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>List item 2<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>List item 3<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>List item 4<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</code></pre>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> listItems = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">'li'</span>);
<span class="hljs-keyword">const</span> itemsArray = <span class="hljs-built_in">Array</span>.from(listItems);

itemsArray.forEach(<span class="hljs-function">(<span class="hljs-params">item</span>) =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(item.textContent);
});
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/ss5.png" alt="ss5" width="600" height="400" loading="lazy"></p>
<h2 id="heading-tip-18-use-the-map-method-to-transform-all-the-elements-of-an-array">Tip 18: Use the <code>map()</code> Method to Transform all the Elements of an Array</h2>
<p>The <code>map()</code> method is a higher-order array method. It allows you to transform elements of an array into new values, creating a new array with the same length as the original but with modified elements.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> numbers = [<span class="hljs-number">1</span>, <span class="hljs-number">4</span>, <span class="hljs-number">9</span>, <span class="hljs-number">16</span>, <span class="hljs-number">25</span>];

<span class="hljs-keyword">const</span> squareRoots = numbers.map(<span class="hljs-function">(<span class="hljs-params">num</span>) =&gt;</span> <span class="hljs-built_in">Math</span>.sqrt(num));
<span class="hljs-built_in">console</span>.log(squareRoots); <span class="hljs-comment">//[1, 2, 3, 4, 5]</span>

<span class="hljs-keyword">const</span> names = [<span class="hljs-string">'john'</span>, <span class="hljs-string">'jane'</span>, <span class="hljs-string">'smith'</span>];

<span class="hljs-keyword">const</span> capitalizedNames = names.map(<span class="hljs-function">(<span class="hljs-params">name</span>) =&gt;</span> name.toUpperCase());
<span class="hljs-built_in">console</span>.log(capitalizedNames); <span class="hljs-comment">// ['JOHN', 'JANE', 'SMITH']</span>
</code></pre>
<p>It is very common to use <code>map()</code> for showing items coming from an API or the ones you created yourself:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"item-list"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</code></pre>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> items = [<span class="hljs-string">'Item 1'</span>, <span class="hljs-string">'Item 2'</span>, <span class="hljs-string">'Item 3'</span>];

<span class="hljs-keyword">const</span> itemList = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#item-list'</span>);

<span class="hljs-comment">// Use map() to generate a list of &lt;li&gt; elements</span>
<span class="hljs-keyword">const</span> liElements = items.map(<span class="hljs-function">(<span class="hljs-params">item</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> li = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'li'</span>);
  li.textContent = item;
  li.style.color = <span class="hljs-string">'crimson'</span>;
  <span class="hljs-keyword">return</span> li;
});

<span class="hljs-comment">// Append the &lt;li&gt; elements to the &lt;ul&gt;</span>
liElements.forEach(<span class="hljs-function">(<span class="hljs-params">li</span>) =&gt;</span> {
  itemList.appendChild(li);
});
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/ss6.png" alt="ss6" width="600" height="400" loading="lazy"></p>
<h2 id="heading-tip-19-use-the-filter-method-to-filter-through-arrays">Tip 19: Use the <code>filter()</code> Method to Filter Through Arrays</h2>
<p>The <code>filter()</code> method is another array method that lets you create a new array with some elements that pass a specific test.</p>
<p>Here is a basic example in which I got all the even and odd numbers in an array:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> nums = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>, <span class="hljs-number">8</span>, <span class="hljs-number">9</span>, <span class="hljs-number">10</span>, <span class="hljs-number">11</span>, <span class="hljs-number">12</span>, <span class="hljs-number">13</span>, <span class="hljs-number">14</span>, <span class="hljs-number">15</span>];

<span class="hljs-keyword">const</span> oddNums = nums.filter(<span class="hljs-function">(<span class="hljs-params">num</span>) =&gt;</span> num % <span class="hljs-number">2</span> !== <span class="hljs-number">0</span>);
<span class="hljs-keyword">const</span> evenNumbers = nums.filter(<span class="hljs-function">(<span class="hljs-params">num</span>) =&gt;</span> num % <span class="hljs-number">2</span> === <span class="hljs-number">0</span>);

<span class="hljs-built_in">console</span>.log(evenNumbers); <span class="hljs-comment">// [2, 4, 6, 8, 10, 12, 14]</span>
<span class="hljs-built_in">console</span>.log(oddNums); <span class="hljs-comment">// [1,  3,  5,  7, 9, 11, 13, 15]</span>
</code></pre>
<p>And here is a more complex example where I got all products less than $500:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> products = [
  { <span class="hljs-attr">id</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">'Laptop'</span>, <span class="hljs-attr">price</span>: <span class="hljs-number">1000</span> },
  { <span class="hljs-attr">id</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">'Phone'</span>, <span class="hljs-attr">price</span>: <span class="hljs-number">500</span> },
  { <span class="hljs-attr">id</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">'Tablet'</span>, <span class="hljs-attr">price</span>: <span class="hljs-number">300</span> },
  { <span class="hljs-attr">id</span>: <span class="hljs-number">4</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">'Headphones'</span>, <span class="hljs-attr">price</span>: <span class="hljs-number">100</span> },
];

<span class="hljs-keyword">const</span> cheapProducts = products.filter(<span class="hljs-function">(<span class="hljs-params">product</span>) =&gt;</span> product.price &lt; <span class="hljs-number">500</span>);

<span class="hljs-built_in">console</span>.log(cheapProducts);
<span class="hljs-comment">/*
[
  { id: 3, name: 'Tablet', price: 300 },
  { id: 4, name: 'Headphones', price: 100 }
]
*/</span>
</code></pre>
<h2 id="heading-tip-20-use-the-foreach-method-to-loop-through-arrays">Tip 20: Use the <code>forEach()</code> Method to Loop Through Arrays</h2>
<p>The <code>forEach()</code> method provides a cleaner and more expressive way to loop through arrays compared to traditional for loops.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> fruits = [<span class="hljs-string">'apple'</span>, <span class="hljs-string">'banana'</span>, <span class="hljs-string">'orange'</span>];

<span class="hljs-comment">// with for loop</span>
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; fruits.length; i++) {
  <span class="hljs-built_in">console</span>.log(fruits[i]);
}

<span class="hljs-comment">// with forEach() – cleaner!</span>
fruits.forEach(<span class="hljs-function">(<span class="hljs-params">fruit</span>) =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(fruit);
});

<span class="hljs-comment">/*
Output: 
apple
banana
orange
*/</span>
</code></pre>
<h2 id="heading-tip-21-use-the-web-audio-api-to-work-with-audio-files">Tip 21: Use the Web Audio API to Work with Audio Files</h2>
<p>The Web Audio API provides methods and properties for playing, pausing, controlling volume, and performing other audio-related tasks.</p>
<p>To play audio files or create a music player with the audio API, you have to use it in combination with the audio tag (<code>&lt;audio&gt;</code>).</p>
<p>Here's how I play, pause, and control the volume of a song:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Audio API<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">audio</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"my-audio"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"audio-file.mp3"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">audio</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"controls"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"play"</span>&gt;</span>Play<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"pause"</span>&gt;</span>Pause<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"range"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"volume"</span> <span class="hljs-attr">min</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">max</span>=<span class="hljs-string">"1"</span> <span class="hljs-attr">step</span>=<span class="hljs-string">"0.01"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"1"</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> audioElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#my-audio'</span>);
<span class="hljs-keyword">const</span> playBtn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#play'</span>);
<span class="hljs-keyword">const</span> pauseBtn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#pause'</span>);
<span class="hljs-keyword">const</span> volume = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#volume'</span>);

<span class="hljs-comment">// play audio with the play() method</span>
playBtn.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> audioElement.play());

<span class="hljs-comment">// pause audio with the pause() method</span>
pauseBtn.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> audioElement.pause());

<span class="hljs-comment">//adjust volume with the volume property</span>
volume.addEventListener(<span class="hljs-string">'change'</span>, <span class="hljs-function">() =&gt;</span> (audioElement.volume = volume.value));
</code></pre>
<p>Read more on the web audio API on <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API">MDN</a>.</p>
<h2 id="heading-tip-22-use-the-web-video-api-to-work-with-video-files">Tip 22: Use the Web Video API to Work with Video Files</h2>
<p>The web video API lets you play video files with themethods and properties built in to it. </p>
<p>Just like the audio API, you can play, pause, control volume of a video with the video API. You also have to use it in combination with the video tag (<code>&lt;video&gt;</code>).</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Video API<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">video</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"my-video"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"video-file.mp4"</span> <span class="hljs-attr">poster</span>=<span class="hljs-string">"snail.jpg"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"500"</span>
&lt;/<span class="hljs-attr">video</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"controls"</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"current-time"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"play"</span>&gt;</span>Play<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"pause"</span>&gt;</span>Pause<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> videoElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#my-video'</span>);
<span class="hljs-keyword">const</span> playBtn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#play'</span>);
<span class="hljs-keyword">const</span> pauseBtn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#pause'</span>);
<span class="hljs-keyword">const</span> videoTime = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#current-time'</span>);

<span class="hljs-comment">// play video with the play() method</span>
playBtn.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> videoElement.play());

<span class="hljs-comment">// pause video with the pause() method</span>
pauseBtn.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> videoElement.pause());

<span class="hljs-comment">// show video time with the currentTime property</span>
videoElement.addEventListener(<span class="hljs-string">'timeupdate'</span>, <span class="hljs-function">() =&gt;</span> {
  videoTime.innerText = videoElement.currentTime.toFixed(<span class="hljs-number">2</span>);
});
</code></pre>
<p>Read more on the web video API on <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Video_and_audio_APIs">MDN</a>.</p>
<h2 id="heading-tip-23-preserve-object-integrity-by-sealing-and-freezing-them">Tip 23: Preserve Object Integrity by Sealing and Freezing Them</h2>
<p>To avoid tampering with your objects, you can seal them with <code>Object.seal</code> and freeze them with <code>Object.freeze()</code>.</p>
<p>When you seal an object, you won't be able to add and remove properties anymore:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> person1 = {
  <span class="hljs-attr">name</span>: <span class="hljs-string">'Kolade'</span>,
  <span class="hljs-attr">luckyNum</span>: <span class="hljs-number">10</span>,
  <span class="hljs-attr">footballFan</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">club</span>: <span class="hljs-string">'Chelsea'</span>,
};

<span class="hljs-comment">// seal the object with Object.seal()</span>
<span class="hljs-built_in">Object</span>.seal(person1);

<span class="hljs-built_in">console</span>.log(person1.name); <span class="hljs-comment">// Kolade</span>

person1.favPet = <span class="hljs-string">'Cat'</span>; <span class="hljs-comment">// You can't add entries to a sealed object</span>
<span class="hljs-built_in">console</span>.log(person1.favPet); <span class="hljs-comment">// undefined</span>

<span class="hljs-keyword">delete</span> person1.club; <span class="hljs-comment">// You can't remove entries from a sealed object</span>
<span class="hljs-built_in">console</span>.log(person1.club); <span class="hljs-comment">// Chelsea</span>

<span class="hljs-comment">// You can still edit the property values</span>
person1.name = <span class="hljs-string">'Kolade Chris'</span>;
<span class="hljs-built_in">console</span>.log(person1.name); <span class="hljs-comment">// Kolade Chris</span>

<span class="hljs-comment">// check if the object is sealed and frozen with isSealed() and isFrozen()</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">Object</span>.isSealed(person1)); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">Object</span>.isFrozen(person1)); <span class="hljs-comment">// false</span>
</code></pre>
<p>When you freeze an object, you can't add entries, and the object is sealed as well. This means you can't add to it and remove from it:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> person2 = {
  <span class="hljs-attr">name</span>: <span class="hljs-string">'Jane'</span>,
  <span class="hljs-attr">luckyNum</span>: <span class="hljs-number">11</span>,
  <span class="hljs-attr">footballFan</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">club</span>: <span class="hljs-string">'Man United'</span>,
};

<span class="hljs-comment">// freeze the object with Object.freeze()</span>
<span class="hljs-built_in">Object</span>.freeze(person2);

<span class="hljs-built_in">console</span>.log(person2.name); <span class="hljs-comment">// Jane</span>

person2.favPet = <span class="hljs-string">'Cat'</span>; <span class="hljs-comment">// You can't add entries to a frozen object</span>
<span class="hljs-built_in">console</span>.log(person2.favPet); <span class="hljs-comment">// undefined</span>

person2.name = <span class="hljs-string">'Jane Doe'</span>;
<span class="hljs-built_in">console</span>.log(person2.name); <span class="hljs-comment">// Jane – nothing changes</span>

<span class="hljs-keyword">delete</span> person2.club; <span class="hljs-comment">// You can't remove entries from a frozen object</span>
<span class="hljs-built_in">console</span>.log(person2.club); <span class="hljs-comment">// Man United</span>

<span class="hljs-comment">// check if the object is frozen and sealed with isFrozen() and isSealed()</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">Object</span>.isFrozen(person2)); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">Object</span>.isSealed(person2)); <span class="hljs-comment">// true</span>
<span class="hljs-comment">// isSealed() returns true because a frozen object is also a sealed object</span>
</code></pre>
<p>The difference between <code>Object.freeze()</code> and <code>Object.seal()</code> is that <code>Object.seal()</code> allows you to modify the entries while <code>Object.freeze()</code> does not. This makes <code>Object.freeze()</code> stronger.</p>
<h2 id="heading-tip-24-use-asyncawait-for-asynchronous-operations">Tip 24: Use <code>async...await</code> For Asynchronous Operations</h2>
<p>The <code>async await</code> syntax is more straightforward and cleaner to work with. So, instead of chaining multiple <code>.then()</code> while working with asynchronous data or operations that return a <code>Promise</code>, you should use <code>async await</code>.</p>
<p>Here's what chaining multiple <code>.then()</code>s looks like:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchData1</span>(<span class="hljs-params"></span>) </span>{
  fetch(<span class="hljs-string">'https://jsonplaceholder.typicode.com/users'</span>)
    .then(<span class="hljs-function">(<span class="hljs-params">res</span>) =&gt;</span> res.json())
    .then(<span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(data))
    .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> <span class="hljs-built_in">console</span>.error(<span class="hljs-string">`There was an error: <span class="hljs-subst">${error}</span>`</span>));
}
</code></pre>
<p>Here's how you can refactor the same code to use <code>async await</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchData2</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'https://jsonplaceholder.typicode.com/users'</span>);
  <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> response.json();
  <span class="hljs-built_in">console</span>.log(data);
}
</code></pre>
<p>You can't use <code>catch()</code> with <code>async await</code>, so you should use <code>try catch</code> to handle errors:</p>
<pre><code class="lang-js"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchData3</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'https://jsonplaceholder.typicode.com/users'</span>);
    <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> response.json();
    <span class="hljs-built_in">console</span>.log(data);
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">`There was an error: <span class="hljs-subst">${error}</span>`</span>);
  }
}
</code></pre>
<p>You can also use arrow functions with <code>async await</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> fetchData4 = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'https://jsonplaceholder.typicode.com/users'</span>);
    <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> response.json();
    <span class="hljs-built_in">console</span>.log(data);
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">`There was an error: <span class="hljs-subst">${error}</span>`</span>);
  }
};
</code></pre>
<h2 id="heading-tip-25-clone-objects-with-the-spread-operator-objectassign-and-jsonparse">Tip 25: Clone Objects with the Spread Operator, <code>Object.assign()</code>, and <code>JSON.parse()</code></h2>
<p>There are several ways and hacks with which you can clone objects, but the most commonly used ways are using the spread syntax (<code>…</code>), <code>Object.assign()</code> and <code>JSON.parse()</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> originalObject = {
  <span class="hljs-attr">name</span>: <span class="hljs-string">'Kolade'</span>,
  <span class="hljs-attr">luckyNum</span>: <span class="hljs-number">10</span>,
  <span class="hljs-attr">isFootballFan</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">club</span>: <span class="hljs-string">'Chelsea'</span>,
};

<span class="hljs-comment">// clone with spread operator</span>
<span class="hljs-keyword">const</span> clonedObject1 = { ...originalObject };

<span class="hljs-comment">// clone with Object.assign()</span>
<span class="hljs-keyword">const</span> clonedObject2 = <span class="hljs-built_in">Object</span>.assign({}, originalObject);

<span class="hljs-comment">// deep cloning with JSON.stringify() and JSON.parse()</span>
<span class="hljs-keyword">const</span> clonedObject3 = <span class="hljs-built_in">JSON</span>.parse(<span class="hljs-built_in">JSON</span>.stringify(originalObject));
<span class="hljs-built_in">console</span>.table(clonedObject1);
<span class="hljs-built_in">console</span>.table(clonedObject1);
<span class="hljs-built_in">console</span>.table(clonedObject1);
</code></pre>
<p>You can also create a deep clone of an object with the <code>structuredClone()</code>. <code>structuredClone()</code> was added to the JavaScript language in ECMAScript 2019.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> clonedObject4 = structuredClone(originalObject);
<span class="hljs-built_in">console</span>.table(clonedObject4);
</code></pre>
<p>Read more about the <code>structuredClone()</code> method on <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/structuredClone">MDN</a>.</p>
<h2 id="heading-tip-26-remove-duplicates-from-an-array-with-set-and-map">Tip 26: Remove Duplicates from an Array with Set and Map</h2>
<p><code>Set</code> and <code>Map</code> are built-in data structures for storing collections of values, each with their own specific characteristics and use cases.</p>
<p>Both <code>Set</code> and <code>Map</code> do not allow duplicate values, so you can use them to remove duplicates from an array by spreading the array into them:</p>
<pre><code class="lang-js"><span class="hljs-comment">// create unique arrays with Set()</span>
<span class="hljs-keyword">const</span> arrayWithDuplicates = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>];
<span class="hljs-keyword">const</span> uniqueArray = [...new <span class="hljs-built_in">Set</span>(arrayWithDuplicates)];

<span class="hljs-built_in">console</span>.log(uniqueArray); <span class="hljs-comment">// [1, 2, 3, 4, 5]</span>

<span class="hljs-comment">// create unique arrays with Map()</span>
<span class="hljs-keyword">const</span> fruitsWithDuplicates2 = [
  <span class="hljs-string">'Mango'</span>,
  <span class="hljs-string">'Cashew'</span>,
  <span class="hljs-string">'Barley'</span>,
  <span class="hljs-string">'Mango'</span>,
  <span class="hljs-string">'Barley'</span>,
  <span class="hljs-string">'Berry'</span>,
  <span class="hljs-string">'Cashew'</span>,
];
<span class="hljs-keyword">const</span> uniqueFruitsWithDuplicates2 = [
  ...new <span class="hljs-built_in">Map</span>(fruitsWithDuplicates2.map(<span class="hljs-function">(<span class="hljs-params">item</span>) =&gt;</span> [item, <span class="hljs-literal">true</span>])).keys(),
];

<span class="hljs-built_in">console</span>.log(uniqueFruitsWithDuplicates2);
<span class="hljs-comment">// [ 'Mango', 'Cashew', 'Barley', 'Berry' ]</span>
</code></pre>
<h2 id="heading-tip-27-map-through-and-array-and-flatten-it-with-the-flatmap-method">Tip 27: Map Through and Array and Flatten it with the <code>flatMap()</code> Method</h2>
<p>If you want to map through a multidimensional array and you want to make sure all deeply nested items are aggregated into a single array, you can use the <code>flatMap()</code> method. This will flatten the array and map through it as well.</p>
<p>This is how you can achieve that by chaining <code>.flat()</code> to <code>.map()</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> numbers = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>];

<span class="hljs-keyword">const</span> doubledAndSquared = numbers.map(<span class="hljs-function">(<span class="hljs-params">num</span>) =&gt;</span> [num * <span class="hljs-number">2</span>, num * num]);
<span class="hljs-keyword">const</span> flattenedArr = doubledAndSquared.flat();

<span class="hljs-built_in">console</span>.log(doubledAndSquared); <span class="hljs-comment">// [ [ 2, 1 ], [ 4, 4 ], [ 6, 9 ], [ 8, 16 ], [ 10, 25 ] ]</span>
<span class="hljs-built_in">console</span>.log(flattenedArr); <span class="hljs-comment">//  [2, 1, 4, 4, 6, 9, 8, 16, 10, 25]</span>
</code></pre>
<p>And this is how you can use <code>flatMap()</code> to do the same thing:</p>
<pre><code class="lang-js"><span class="hljs-comment">// combine map and flat</span>
<span class="hljs-keyword">const</span> combinedMapAndFlat = numbers.flatMap(<span class="hljs-function">(<span class="hljs-params">num</span>) =&gt;</span> [num * <span class="hljs-number">2</span>, num * num]);

<span class="hljs-built_in">console</span>.log(combinedMapAndFlat); <span class="hljs-comment">// Output: [2, 1, 4, 4, 6, 9, 8, 16, 10, 25];</span>
</code></pre>
<p>How cool is that?</p>
<h2 id="heading-tip-28-use-the-padstart-and-padend-methods-to-pad-a-string-with-a-character">Tip 28: Use the <code>padStart()</code> and <code>padEnd()</code> Methods to Pad a string with a Character</h2>
<p>The <code>padStart()</code> and <code>padEnd()</code> are string methods that allow you to pad a string with a specified character to reach a target length. These methods are particularly handy for formatting strings and aligning text in columns.</p>
<p>Here is the basic usage:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> originalString = <span class="hljs-string">'Hello'</span>;
<span class="hljs-keyword">const</span> paddedString = originalString.padStart(<span class="hljs-number">10</span>, <span class="hljs-string">'*'</span>);
<span class="hljs-built_in">console</span>.log(paddedString); <span class="hljs-comment">// *****Hello</span>

<span class="hljs-keyword">const</span> originalString2 = <span class="hljs-string">'World'</span>;
<span class="hljs-keyword">const</span> paddedString2 = originalString2.padEnd(<span class="hljs-number">10</span>, <span class="hljs-string">'-'</span>);
<span class="hljs-built_in">console</span>.log(paddedString2); <span class="hljs-comment">// World-----</span>

<span class="hljs-comment">// combine both padStart() and padEnd()</span>
<span class="hljs-keyword">const</span> text = <span class="hljs-string">'Hello'</span>;
<span class="hljs-keyword">const</span> paddedText = text.padStart(<span class="hljs-number">10</span>, <span class="hljs-string">'-'</span>).padEnd(<span class="hljs-number">15</span>, <span class="hljs-string">'+'</span>);
<span class="hljs-built_in">console</span>.log(paddedText); <span class="hljs-comment">// -----Hello+++++</span>
</code></pre>
<p>Here's how you can use both methods to align items in the console:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> products = [
  { <span class="hljs-attr">name</span>: <span class="hljs-string">'Apples'</span>, <span class="hljs-attr">price</span>: <span class="hljs-number">1.5</span> },
  { <span class="hljs-attr">name</span>: <span class="hljs-string">'Bananas'</span>, <span class="hljs-attr">price</span>: <span class="hljs-number">0.75</span> },
  { <span class="hljs-attr">name</span>: <span class="hljs-string">'Oranges'</span>, <span class="hljs-attr">price</span>: <span class="hljs-number">2</span> },
];

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Product      Price'</span>);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'-------------------'</span>);

products.forEach(<span class="hljs-function">(<span class="hljs-params">{ name, price }</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> paddedName = name.padEnd(<span class="hljs-number">10</span>, <span class="hljs-string">' '</span>);
  <span class="hljs-keyword">const</span> formattedPrice = price.toFixed(<span class="hljs-number">2</span>).padStart(<span class="hljs-number">8</span>, <span class="hljs-string">' '</span>);
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${paddedName}</span><span class="hljs-subst">${formattedPrice}</span>`</span>);
});

<span class="hljs-comment">/*
Output:

Product      Price
-------------------
Apples        1.50
Bananas       0.75
Oranges       2.00
*/</span>
</code></pre>
<p>And a better usage is formatting the time of a music or video player in the <code>00:00</code> of <code>00:00</code> format:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">formatTime</span>(<span class="hljs-params">currentTime, totalTime</span>) </span>{
  <span class="hljs-comment">// Helper function to pad a number with leading zeros</span>
  <span class="hljs-keyword">const</span> padWithZero = <span class="hljs-function">(<span class="hljs-params">num</span>) =&gt;</span> num.toString().padStart(<span class="hljs-number">2</span>, <span class="hljs-string">'0'</span>);

  <span class="hljs-comment">// Format current time in minutes:seconds</span>
  <span class="hljs-keyword">const</span> formattedCurrentTime = <span class="hljs-string">`<span class="hljs-subst">${padWithZero(
    <span class="hljs-built_in">Math</span>.floor(currentTime / <span class="hljs-number">60</span>)
  )}</span>:<span class="hljs-subst">${padWithZero(<span class="hljs-built_in">Math</span>.floor(currentTime % <span class="hljs-number">60</span>))}</span>`</span>;

  <span class="hljs-comment">// Format total time in minutes:seconds</span>
  <span class="hljs-keyword">const</span> formattedTotalTime = <span class="hljs-string">`<span class="hljs-subst">${padWithZero(
    <span class="hljs-built_in">Math</span>.floor(totalTime / <span class="hljs-number">60</span>)
  )}</span>:<span class="hljs-subst">${padWithZero(<span class="hljs-built_in">Math</span>.floor(totalTime % <span class="hljs-number">60</span>))}</span>`</span>;

  <span class="hljs-comment">// Combine formatted current time and total time with "of" in between</span>
  <span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">${formattedCurrentTime}</span> of <span class="hljs-subst">${formattedTotalTime}</span>`</span>;
}

<span class="hljs-comment">// Example time values</span>
<span class="hljs-keyword">const</span> currentTimeInSeconds = <span class="hljs-number">125</span>; <span class="hljs-comment">// Example of a current time in seconds</span>
<span class="hljs-keyword">const</span> totalTimeInSeconds = <span class="hljs-number">3600</span>; <span class="hljs-comment">// Example of a total time in seconds</span>

<span class="hljs-comment">// Format the time and display the result</span>
<span class="hljs-keyword">const</span> formattedTime = formatTime(currentTimeInSeconds, totalTimeInSeconds);
<span class="hljs-built_in">console</span>.log(formattedTime); <span class="hljs-comment">// 02:05 of 60:00</span>
</code></pre>
<h2 id="heading-tip-29-use-the-insertadjacenthtml-method-of-dom-to-insert-a-string-into-the-dom">Tip 29: Use the <code>insertAdjacentHTML()</code> method of DOM to Insert a String into the DOM</h2>
<p>The <code>insertAdjacentHTML()</code> method of the DOM lets you insert a string of HTML at a specified position relative to a given element. This position could be 'beforeend', 'afterend', 'beforebegin', or 'afterbegin'.</p>
<p>Here's how it works:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"content"</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This is an example.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"add-button"</span>&gt;</span>Add Paragraph<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> addButton = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'add-button'</span>);
<span class="hljs-keyword">const</span> content = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'content'</span>);

addButton.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
   <span class="hljs-keyword">const</span> newParagraphHTML = <span class="hljs-string">'&lt;p&gt;This is a new paragraph.&lt;/p&gt;'</span>;
   content.insertAdjacentHTML(<span class="hljs-string">'afterend'</span>, newParagraphHTML);
});
</code></pre>
<h2 id="heading-tip-30-use-the-createtreewalker-dom-method-to-traverse-the-dom">Tip 30: Use the <code>createTreeWalker()</code> DOM Method to Traverse the DOM</h2>
<p>The <code>createTreeWalker()</code> method allows you to traverse through the nodes of the DOM tree and perform actions on them based on specific criteria.</p>
<p>This method can be useful for complex document structures or specialized traversal needs.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"content"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This is a <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>paragraph<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> with some <span class="hljs-tag">&lt;<span class="hljs-name">em</span>&gt;</span>emphasis<span class="hljs-tag">&lt;/<span class="hljs-name">em</span>&gt;</span>.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>List item 1<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>List item 2<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>List item 3<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>List item 4<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Use <code>createTreeWalker()</code> to traverse and show all text nodes:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> content = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'content'</span>);
<span class="hljs-keyword">const</span> treeWalker = <span class="hljs-built_in">document</span>.createTreeWalker(content, NodeFilter.SHOW_TEXT);

<span class="hljs-keyword">let</span> node;
<span class="hljs-keyword">while</span> ((node = treeWalker.nextNode())) {
  <span class="hljs-built_in">console</span>.log(node.nodeValue.trim());
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/ss7.png" alt="ss7" width="600" height="400" loading="lazy"></p>
<p><strong>N.B</strong>: White spaces qualify as a text node – that's why you can see the spaces in the output</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Every code example in this article is from my 30 Days of JavaScript challenge on Twitter (now, X). You can checkout <a target="_blank" href="https://twitter.com/Ksound22">my Twitter profile</a>.</p>
<p>I hope these tips help you understand some nuances of JavaScript and let you get some things done in your web projects.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The Regular Expressions Book – RegEx for JavaScript Developers [Full Book] ]]>
                </title>
                <description>
                    <![CDATA[ If you want to master regular expressions and understand how they work in JavaScript, this book's for you. Regular expressions can be intimidating when you first encounter them. When I started learning to code, I gave up on regular expressions twice.... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/regular-expressions-for-javascript-developers/</link>
                <guid isPermaLink="false">66adf1f6f452caf50fb1fe18</guid>
                
                    <category>
                        <![CDATA[ book ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Regex ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Regular Expressions ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Wed, 26 Jul 2023 15:27:12 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/Regex-for-JavaScript-Developers-Cover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you want to master regular expressions and understand how they work in JavaScript, this book's for you.</p>
<p>Regular expressions can be intimidating when you first encounter them. When I started learning to code, I gave up on regular expressions twice.</p>
<p>While that was partly because I was intimidated by regular expressions at first, the tutorials and courses I used never taught them in a way I could understand. </p>
<p>In fact, before some tutorials start teaching regex, they complain about regex and how tough they can be. And there's no better way to discourage a learner than that.</p>
<p>In this book, you won't just see how to use regex in a regex testing tool like <strong>regexpal</strong> or <strong>regex101</strong>. You'll also see how they works in JavaScript. This is what many courses and tutorials tailored for regex in JavaScript lack. As you see how they work using a regex tester, you'll also see how they work in JavaScript.</p>
<p>You can also apply what you learn in this book to other programming languages like Python, PHP, and so on. All you need to do is to know about how the regex engine of that language works. You'll also need to understand the methods and functions the language uses for working with regular expressions.</p>
<p>To get the most out of this book, make sure you read it in order because each chapter builds upon the previous ones. I have also arranged the chapters according to how difficult they are. So, you will find simpler concepts first and more advanced concepts later.</p>
<p>Happy reading!</p>
<h2 id="heading-table-of-contents">Table Of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-chapter-1-introduction-to-regular-expressions">Chapter 1: Introduction to Regular Expressions</a><ul>
<li><a class="post-section-overview" href="#heading-what-are-regular-expressions">What are Regular Expressions?</a></li>
<li><a class="post-section-overview" href="#heading-a-brief-history-of-regular-expressions">A Brief History of Regular Expressions</a></li>
<li><a class="post-section-overview" href="#heading-what-are-the-uses-of-regular-expressions">What are the Uses of Regular Expressions?</a></li>
<li><a class="post-section-overview" href="#heading-flavors-of-regular-expressions">Flavors of Regular Expressions</a></li>
<li><a class="post-section-overview" href="#heading-tools-for-working-with-regular-expressions">Tools for Working with Regular Expressions</a></li>
<li><a class="post-section-overview" href="#heading-basic-concepts-of-regular-expressions">Basic Concepts of Regular Expressions</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-chapter-2-how-to-match-literal-characters-and-character-sets-in-regular-expressions">Chapter 2: How to Match Literal Characters and Character Sets in Regular Expressions</a><ul>
<li><a class="post-section-overview" href="#heading-what-are-literal-characters-in-regular-expressions">What are Literal Characters in Regular Expressions?</a></li>
<li><a class="post-section-overview" href="#heading-how-to-match-literal-characters-in-regex-testers">How to Match Literal Characters in RegEx Testers</a></li>
<li><a class="post-section-overview" href="#heading-character-set-matching">Character Set Matching</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-chapter-3-regular-expressions-flags">Chapter 3: Regular Expressions Flags</a><ul>
<li><a class="post-section-overview" href="#heading-the-global-flag">The <code>global</code> Flag</a></li>
<li><a class="post-section-overview" href="#heading-the-case-insensitive-flag">The <code>case-insensitive</code> Flag</a></li>
<li><a class="post-section-overview" href="#heading-the-multi-line-and-single-line-flags">The <code>multi-line</code> and <code>single-line</code> Flags</a></li>
<li><a class="post-section-overview" href="#heading-the-unicode-flag">The <code>unicode</code> Flags</a></li>
<li><a class="post-section-overview" href="#heading-the-sticky-flag">The <code>sticky</code> Flags</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-chapter-4-how-to-use-regular-expressions-in-javascript">Chapter 4: How to Use Regular Expressions in JavaScript </a><ul>
<li><a class="post-section-overview" href="#heading-how-to-create-regular-expressions-in-javascript">How to Create Regular Expressions in JavaScript</a></li>
<li><a class="post-section-overview" href="#heading-methods-of-the-regexp-constructor">Methods of the <code>RegExp()</code> Constructor</a></li>
<li><a class="post-section-overview" href="#heading-properties-of-the-regexp-constructor">Properties of the <code>RegExp()</code> Constructor</a></li>
<li><a class="post-section-overview" href="#heading-string-methods-for-working-with-regular-expressions">String Methods for Working with Regular Expressions</a></li>
<li><a target="_blank" href="howtomatchliteralcharactersinjavascriptregularexpressions">How to Match Literal Characters in JavaScript Regular Expressions</a></li>
<li><a class="post-section-overview" href="#heading-how-to-use-character-sets-in-javascript-regular-expressions">How to Use Character Sets in JavaScript Regular Expressions</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-chapter-5-metacharacters-quantifiers-repeated-matches-and-optional-matches">Chapter 5: Metacharacters, Quantifiers, Repeated Matches, and Optional Matches</a><ul>
<li><a class="post-section-overview" href="#heading-what-are-metacharacters">What are Metacharacters?</a></li>
<li><a class="post-section-overview" href="#heading-the-word-and-non-word-metacharacters">The Word and Non-word Metacharacters</a></li>
<li><a class="post-section-overview" href="#heading-the-anchor-metacharacters">The Anchor Metacharacters</a></li>
<li><a class="post-section-overview" href="#heading-the-digit-and-non-digit-metacharacters">The Digit and Non-digit Metacharacters</a></li>
<li><a class="post-section-overview" href="#heading-the-square-brackets-metacharacter">The Square Brackets Metacharacter</a></li>
<li><a class="post-section-overview" href="#heading-the-word-boundary-and-non-word-boundary-metacharacters">The Word Boundary and Non-word Boundary Metacharacters</a></li>
<li><a class="post-section-overview" href="#heading-the-parenthesis-metacharacter">The Parenthesis Metacharacter</a></li>
<li><a class="post-section-overview" href="#heading-the-space-and-non-space-metacharacters">The Space and Non-space Metacharacters</a></li>
<li><a class="post-section-overview" href="#heading-the-pipe-metacharacter">The Pipe Metacharacter</a></li>
<li><a class="post-section-overview" href="#heading-how-to-match-repeated-characters-with-quantifiers">How to Match Repeated Characters With Qunatifiers</a></li>
<li><a class="post-section-overview" href="#heading-how-to-specify-match-quantity-with-the-curly-braces-metacharacter">How to Specify Match Quantity with the Curly Braces Metacharacter</a></li>
<li><a class="post-section-overview" href="#heading-the-wildcard-metacharacter">The Wildcard Metacharacter</a></li>
<li><a class="post-section-overview" href="#heading-greediness-and-laziness-in-regular-expressions">Greediness and Laziness in Regular Expressions</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-chapter-6-grouping-and-capturing-in-regex">Chapter 6: Grouping and Capturing in Regex</a><ul>
<li><a class="post-section-overview" href="#heading-how-to-reference-captured-groups-with-backreferences">How to Reference Captured Groups with Backreferences</a></li>
<li><a class="post-section-overview" href="#heading-how-to-use-the-d-flag-and-hasindices-property-with-groups">How to Use the <code>d</code> Flag and <code>hasIndices</code> Property With Groups</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-chapter-7-lookaround-groups-lookaheads-and-lookbehinds">Chapter 7: Lookaround Groups: Lookaheads and Lookbehinds</a> <ul>
<li><a class="post-section-overview" href="#heading-what-are-lookaround-groups">What are Lookaround Groups?</a></li>
<li><a class="post-section-overview" href="#heading-what-is-a-lookahead-group">What is a Lookahead Group?</a></li>
<li><a class="post-section-overview" href="#heading-what-is-a-lookbehind-group">What is a Lookbehind Group?</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-chapter-8-regex-best-practices-and-troubleshooting">Chapter 8: Regex Best Practices and Troubleshooting</a><ul>
<li><a class="post-section-overview" href="#heading-best-practices-to-consider-while-writing-regular-expressions">Best Practices to Consider While Writing Regular Expressions</a></li>
<li><a class="post-section-overview" href="#heading-how-to-write-accurate-regular-expressions">How to Write Accurate Regular Expressions</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-chapter-9-applications-of-regular-expressions">Chapter 9: Applications of Regular Expressions</a><ul>
<li><a class="post-section-overview" href="#heading-a-better-way-to-match-dates">A Better Way to Match Dates</a> </li>
<li><a class="post-section-overview" href="#heading-how-to-match-us-zip-codes">How to Match US Zip Codes</a></li>
<li><a class="post-section-overview" href="#heading-how-to-match-email-addresses">How to Match Email Addresses</a></li>
<li><a class="post-section-overview" href="#heading-how-to-match-passwords">How to Match Passwords</a></li>
<li><a class="post-section-overview" href="#heading-form-validation-with-regex">Form Validation with Regex</a></li>
<li><a class="post-section-overview" href="#heading-article-table-of-contents-generator">Article Table of Contents Generator</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-glossary-and-references">Glossary and References</a><ul>
<li><a class="post-section-overview" href="#heading-glossary-of-terms">Glossary of Terms</a> </li>
<li><a class="post-section-overview" href="#heading-quick-reference-of-metacharacters-and-quantifiers">Quick Reference of Metacharacters and Quantifiers</a> </li>
</ul>
</li>
</ul>
<h2 id="heading-chapter-1-introduction-to-regular-expressions">Chapter 1: Introduction to Regular Expressions</h2>
<h3 id="heading-what-are-regular-expressions">What are Regular Expressions?</h3>
<p>You might see this written as regular expressions, regex, or RegExp – but all refer to the same thing. </p>
<p>Regex are a sequence of characters for matching a part of a string or the whole string. Matching strings with regular expressions might require more than just "characters". Many times, you will need to use a special set of characters called "metacharacters" and "quantifiers". </p>
<p>Because regular expressions are a powerful tool, you can use then to do much more than just "matching strings" when you combine regex with programming languages. </p>
<p>Almost all the main programming languages of the modern era have built-in support for regular expressions. Some programming languages might even have specific libraries that help you work more conveniently with regex.</p>
<p>Apart from using regular expressions in programming languages, other tools that let you use regular expressions are:</p>
<ul>
<li><p><strong>Text Editors and IDEs</strong>: for search and search and replace in VS Code, Visual Studio, Notepad++, Sublime Text, and others.</p>
</li>
<li><p><strong>Browser Developer Tools</strong>: mostly in-browser search (with extensions or add-ons) and search within the developer tools.</p>
</li>
<li><p><strong>Database Tools</strong>: for data mining.</p>
</li>
<li><p><strong>RegEx Testers</strong>: you can paste in text and write the regular expressions to match them – which is a very good way to learn regular expressions. This book explores that option quite a bit.</p>
</li>
</ul>
<h3 id="heading-a-brief-history-of-regular-expressions">A Brief History of Regular Expressions</h3>
<p>Regular expressions have a rich and fascinating history that has already spanned more than seven decades. This history continues to evolve alongside the development of computer science and programming languages.</p>
<p>The concept of regular expressions traces back to the 1950s. American mathematician Stephen Cole Kleene introduced them as a notation for defining patterns in formal languages. Kleene's work also formed the foundation for theoretical computer science.</p>
<p>In the early 1960s, the first implementations of regular expressions emerged. Ken Thompson, a computer scientist at Bell Labs, developed a text editor named <strong>QED</strong> that utilized regular expressions for pattern matching. QED's capabilities provided a way to search and manipulate texts more efficiently.</p>
<p>The concept gained further popularity when Thompson and Dennis Ritchie created the Unix operating system in the early 1970s. </p>
<p>They incorporated regular expressions into various Unix utilities, most notably the <strong>ed text editor</strong> and later the <strong>sed stream editor</strong>. These tools allowed users to perform complex text manipulation tasks, significantly enhancing the efficiency and power of text processing.</p>
<p>In 1973, Thompson collaborated with Alfred Aho and Peter Weinberger to develop a new tool called <strong>grep</strong> (global regular expression print) as part of the Unix toolkit. </p>
<p>Grep allowed users to search files for specific patterns using regular expressions. The simplicity and effectiveness of grep made it a widely adopted tool. It also established regular expressions as a standard feature in Unix-based systems.</p>
<p>As computer systems and programming languages evolved, regular expressions became integrated into various software development environments. In the late 1970s, the AWK programming language was created. AWK inspired Larry Wall to create Perl and make it available to the public in 1987.</p>
<p>Wall recognized the value of regular expressions for text manipulation and integrated regex into Perl. </p>
<p>Perl's integration of regular expressions into its syntax made it a popular language for text matching and data extraction tasks. This integration formed the foundation of  <strong>PCRE</strong> (Perl-compatible regular expressions), a flavor and library of regular expressions you can use in some programming languages such as Perl, Python, PHP, Java, and others.</p>
<p>Regular expressions continued to evolve and find applications beyond Unix and Perl. In the 1980s, the International Organization for Standardization (ISO) developed the POSIX standard, which included a specification for regular expressions. This standardization ensured compatibility and consistency across different implementations and systems.</p>
<p>With the rise of the internet and the World Wide Web in the 1990s, regular expressions found widespread use in web development and data processing. They became an essential component of many scripting languages, providing developers with powerful tools for text processing, form validation, and data extraction from web pages. </p>
<p>For example, JavaScript had always had a version of PCRE built in for working with regular expressions. But by 1999, with the release of ECMAScript, the <code>RegExp()</code> constructor was introduced. This gave JavaScript developers the ability to start using regular expressions directly in their code, in the JavaScript way.</p>
<p>In the early 2000s, tools and libraries specifically focused on regular expressions emerged, making it easier for developers to work with them. Libraries like PCRE (Perl Compatible Regular Expressions) provided enhanced features and better performance, further expanding the usage and capabilities of regular expressions.</p>
<p>Today, regular expressions are an integral part of programming languages and text-processing tools like your code editor. They are supported by almost all major programming languages, including Java, C#, Ruby, and PHP. </p>
<p>Integrated development environments (IDEs) and code editors like Visual Studio, VS Code, and Notepad++ also now include regex-based search and search and replace functionalities, simplifying the process of finding and manipulating texts in code. </p>
<p>The history of regular expressions demonstrates their evolution from theoretical concepts to practical tools that have revolutionized text processing and pattern matching. </p>
<p>From the early developments at Bell Labs and Unix to their integration into popular programming languages, regular expressions have become an essential tool in the hands of developers and system administrators. Regex empowers them to handle complex text-based tasks efficiently. </p>
<p>With the ongoing advancements in computing and the continuous demand for efficient text processing, regular expressions will likely remain a fundamental part of the technology landscape for years to come.</p>
<h3 id="heading-what-are-the-uses-of-regular-expressions">What are the Uses of Regular Expressions?</h3>
<p>Regular expressions are quite versatile and flexible. This makes it possible to apply them to various tasks in various domains such as computer programming, data processing, text editing, and web development.</p>
<p>Those applications and uses include but are not limited to the following:</p>
<p><strong>String Matching</strong>: This is one of the most common ways developers use regular expressions. This is also a good way to learn regular expressions. </p>
<p>You can paste some texts into a regex engine and write the regex to match a part of the text or the whole text. You can also search for strings that contain specific character sequences, start or end with certain characters, or match complex patterns. </p>
<p>This makes regular expressions valuable for tasks like searching for keywords, validating input against specific patterns, or filtering data based on string patterns</p>
<p><strong>Password Strength Validation</strong>: You can use regular expressions for validating the strength of passwords in websites and applications. </p>
<p>By defining a set of rules using regular expressions, developers can enforce specific password requirements, such as a minimum number of characters, a combination of uppercase and lowercase letters, numbers, and special characters. </p>
<p><strong>Form Validation</strong>: Validating inputs of a form or standalone inputs is another popular way developers use regular expressions. </p>
<p>Regular expressions provide a concise and efficient way to ensure that input data follows specific patterns or formats. Whether it's validating usernames, email addresses, phone numbers, credit card numbers, postal codes, or other inputs, regular expressions can help you enforce validation rules and maintain data integrity.</p>
<p><strong>Text Search and Manipulation</strong>: Regular expressions excel at searching for specific patterns within text and performing manipulations based on those matches. They are a powerful tool for tasks such as data mining, log analysis, and text processing. </p>
<p>Whether you need to find occurrences of particular words or phrases, extract structured data from text, analyze content, or perform string matching, regular expressions offer efficient pattern-matching capabilities</p>
<p><strong>Working with URLs and URIs</strong>: Since URLs and URIs are an integral part of web development, regular expressions can help in validating, parsing, and manipulating them. This enables developers to ensure the correctness and structure of web addresses, validate whether a string is a valid URL, and help extract specific components such as the domain, path, query parameters, or fragments. </p>
<p>This functionality is particularly useful in tasks like URL routing, rewriting, or extracting data from query parameters.</p>
<p><strong>Search and Replace in IDEs and Text Editors</strong>: Regular expressions offer sophisticated search capabilities. This enables developers to locate specific patterns (such as words with specific prefixes or sequences of characters) and then replace the matches with a specified text. This is built into modern text editors like VS Code and Notepad++.</p>
<p><strong>Data Extraction and Scraping</strong>: Regular expressions play a significant role in data extraction and web scraping. They allow developers to extract specific information from unstructured or semi-structured text by defining patterns to match desired data. </p>
<p>They are also valuable when extracting data from sources like HTML or XML documents, as they enable efficient retrieval of information based on defined patterns.</p>
<p><strong>Syntax Highlighting</strong>: Regular expressions are commonly used in IDEs and text editors to provide syntax highlighting. This ends up helping users to visually distinguish different parts of a code or document by assigning colors or formatting to keywords, strings, comments, and other language-specific constructs. </p>
<p>Regular expressions are used to identify and match these language-specific patterns, making code more readable and enhancing the overall editing experience.</p>
<h3 id="heading-flavors-of-regular-expressions">Flavors of Regular Expressions</h3>
<p>The term "flavors of regular expressions" refers to the specific implementation and syntax variations of regular expressions in different programming languages, libraries, or tools. </p>
<p>While the core concept of regular expressions remains the same, the details of how regular expressions are written and interpreted can vary between different environments.</p>
<p>Each flavor of regular expressions may have its own set of metacharacters, syntax rules, and additional features beyond the basic functionality. </p>
<p>These differences can include variations in the syntax for character classes, metacharacters, capturing groups, and assertions, as well as additional capabilities like named capturing groups, look-ahead, and look-behinds.</p>
<p>There are many flavors of regular expressions available today. Some of them are:</p>
<ul>
<li><p><strong>Basic Regular Expressions (BRE)</strong>: this flavor is commonly found in Unix tools such as <strong>sed</strong> and <strong>grep</strong>. It uses a limited set of metacharacters and features. The wildcard (<code>.</code>) and zero or more (<code>*</code>) metacharacters are available in it.</p>
</li>
<li><p><strong>Extended Regular Expressions (ERE)</strong>: ERE is an extension of BRE. It provides additional metacharacters and features. In addition to the metacharacters available in BRE, ERE introduces features like grouping with parentheses ( <code>( )</code>), alternation with the pipe symbol (<code>|</code>), and the use of curly braces (<code>{}</code>) to specify repetition ranges.</p>
</li>
<li><p><strong>Perl-Compatible Regular Expressions (PCRE)</strong>: PCRE is a popular flavor supported by various programming languages such as Perl, Python, PHP, and JavaScript. PCRE extends the basic regular expression syntax with powerful features like lookahead and look-behind assertions, backreferences, non-capturing groups, and the use of <code>\b</code> for word boundaries.</p>
</li>
<li><p><strong>JavaScript Regular Expressions</strong>: JavaScript has its regular expression flavor which is similar to PCRE but with a few differences. It supports basic features like character classes with square brackets (<code>[ ]</code>), metacharacters (<code>*</code>, <code>+</code>, <code>?</code>, and others), and capturing groups  (<code>( )</code>). JavaScript also provides additional features like the global flag <code>/g</code> to perform multiple matches, and the ignore case flag <code>/i</code> for case-insensitive matching</p>
</li>
<li><p><strong>Python Regular Expressions</strong>: Python's <code>re</code> module implements a flavor that is similar to PCRE but with a few variations. It supports features such as character classes <code>[ ]</code>, metacharacters (<code>*</code>, <code>+</code>, and <code>?</code>), and capturing groups (<code>( )</code>). The <code>re</code> module also has a unique raw string syntax (<code>r' '</code>) to simplify working with backslashes.</p>
</li>
</ul>
<p>It's important to be aware of the flavor of regular expressions you are using when working with regular expressions in different programming languages or tools. This ensures that you use the correct syntax and take advantage of any unique features or capabilities provided by that particular flavor.</p>
<p><strong>N.B.</strong>: Don’t bother so much about the metacharacters (and quantifiers) mentioned in this part. You will see them in action in chapter 5 of this book.</p>
<h3 id="heading-tools-for-working-with-regular-expressions">Tools for Working with Regular Expressions</h3>
<p>Regular expression tools are the programming languages, libraries and frameworks, command line utilities, online regex testers, text editors and IDEs, and applications designed to help you create, test, and apply regular expressions in your day-to-day work life.</p>
<p>There are many tools available for working with regular expressions. Let me take you through them under regex testers, programming languages, libraries, text editors and IDEs, and command line tools.</p>
<h4 id="heading-regex-testers">RegEx Testers</h4>
<p>RegEx testers are the online testing environments specifically built for creating and testing regular expressions against some test strings. Examples include regex101.com, regexr.com, and regexpal.com.</p>
<p>The UIs of these regex testers usually have an input for the regular expressions you want to write, and another for the text you want to test the regex against. </p>
<p>This is how the UI of regexpal.com looks:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/regexpal-ui.png" alt="regexpal-ui" width="600" height="400" loading="lazy"></p>
<p>More advanced ones like regex101.com let you select the flavor of regular expressions you want to work with, an explanation of the regex, and match information. </p>
<p>Here’s what the UI of regex101.com looks like:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/regex101-ui-1.png" alt="regex101-ui-1" width="600" height="400" loading="lazy"></p>
<p>One of the good things about these online regex testers is that they are helpful for learning regular expressions. A lot of them provide real-time matching and cheatsheets you can quickly look at. Many devs who use regex have used them. </p>
<p>Apart from learning, you can also use them by creating your regex with them and pasting them into wherever you want to use the regex. This is how I create my regex.</p>
<h4 id="heading-programming-languages">Programming Languages</h4>
<p>Almost all modern programming languages have built-in support for regular expressions. And so they all have methods for creating and testing regular expressions. </p>
<p>For example, JavaScript has the <code>RegExp()</code> constructor for working with regular expressions, Python has the <code>re</code> module, Java has the <code>java.util.regex</code> package, and Perl has regex built into it directly.</p>
<h4 id="heading-libraries-and-frameworks">Libraries and Frameworks</h4>
<p>Many programming languages have standalone libraries and frameworks that make it easier to create regular expressions. </p>
<p>There is <code>XRegExp</code> for JavaScript, PCRE (Perl Compatible Regular Expressions) for Perl, Go-Restructure for Golang, and Verbal Expressions, a cross-platform regex library.</p>
<h4 id="heading-text-editors-and-ides">Text Editors and IDEs</h4>
<p>Many text editors and IDEs such as VS Code, Visual Studio, Notpad++, Atom, Sublime Text, IntelliJ IDEA, and others have built-in support for regular expressions. </p>
<p>The commonest thing developers use this for is search, and search and replace. Also, the syntax highlighting in those text editors and IDEs is often implemented with regular expressions.</p>
<h4 id="heading-command-line-tools">Command Line Tools</h4>
<p>Unix command line tools like grep and sed allow you to perform regex operations on text files and streams. With this, you can search, filter, and manipulate multiple files. </p>
<p>Using these Unix tools, options for customizing search behaviors and customizing complex text transformations are also available to you.</p>
<h3 id="heading-basic-concepts-of-regular-expressions">Basic Concepts of Regular Expressions</h3>
<p>The basic concepts and syntax of regular expressions are the building blocks involved in creating, testing, and applying patterns for searching, matching, and manipulating strings. </p>
<p>This includes concepts like <strong>literal characters</strong>, <strong>metacharacters</strong>, <strong>quantifiers</strong>, <strong>character classes</strong>, <strong>anchors and boundaries</strong>, and <strong>escape characters</strong>. The more advanced ones are <strong>groupings</strong>, <strong>backreferences</strong>, <strong>look-ahead assertions</strong>, and <strong>look-behind assertions</strong>.</p>
<p>Regular expressions users utilize many of these concepts to construct efficient regular expressions for working with text. On many occasions, the basic ones are enough. But if you want to create more advanced regular expressions, then the more advanced ones will also be useful for you.</p>
<p>This book won’t leave any of the concepts behind. I will show you how you can utilize them in regex testers and how you can use them in JavaScript since that’s what this book is meant for.</p>
<h2 id="heading-chapter-2-how-to-match-literal-characters-and-character-sets-in-regular-expressions">Chapter 2: How to Match Literal Characters and Character Sets in Regular Expressions</h2>
<h3 id="heading-what-are-literal-characters-in-regular-expressions">What are Literal Characters in Regular Expressions?</h3>
<p>Literal characters are characters you can match as they appear in a test string. They could be letters, numbers, spaces, or even symbols. In other words, they are non-special characters that represent themselves.</p>
<p>This means if you want to match literal characters, you should construct your regex pattern in the same way as the test string appears. </p>
<p>For example, if you want to match the word <code>hello</code>, your regex pattern can be <code>hello</code>. And if you want to match the <code>h</code> in the word <code>hatch</code>, all you need as the pattern is <code>h</code>. </p>
<p>This <code>h</code> would match the first occurrence of the letter <code>h</code> in the test string <code>hatch</code>. If you want it to match the other letter <code>h</code> as well, you need the "g" flag, or global flag. You will learn about the flags and modifiers in the next chapter of this book.</p>
<p>That is not the case for some symbols, though. That’s because some symbols are special characters of regular expressions (metacharacters and quantifiers). So, if you want to match those characters, you have to escape them with a backslash (<code>\</code>). This book will also teach you all you need to know about metacharacters because there's a whole chapter for them.</p>
<h3 id="heading-how-to-match-literal-characters-in-regex-testers">How to Match Literal Characters in RegEx Testers</h3>
<p>Provided you want to match the word <code>hello</code>, then <code>hello</code> should be your regex pattern:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/hello-match-1.png" alt="hello-match-1" width="600" height="400" loading="lazy"></p>
<p>If you want to match the text <code>freeCodeCamp</code>, you can construct your regex to be <code>freeCodeCamp</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/fcc-match-1.png" alt="fcc-match-1" width="600" height="400" loading="lazy"></p>
<p>So, what if you want to match <code>hello freeCodeCamp</code>? Then you just use <code>hello freeCodeCamp</code> as the pattern:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/hello-fcc-match.png" alt="hello-fcc-match" width="600" height="400" loading="lazy"></p>
<p>If you want to match the letter <code>e</code> in the text <code>freeCodeCamp</code>, <code>e</code> is the pattern to use:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/e-in-fcc.png" alt="e-in-fcc" width="600" height="400" loading="lazy"></p>
<p>And if you want to match <code>h</code> in the text <code>hatch</code>, <code>h</code> is the pattern you should use:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/h-in-hatch.png" alt="h-in-hatch" width="600" height="400" loading="lazy"></p>
<p>You can see that in the text <code>freeCodeCamp</code>, the other <code>e</code>s after the first occurrence were not returned as matches – same with the last <code>h</code> in the word <code>hatch</code>. You will learn how to match every occurrence of a letter in a text in the next chapter.</p>
<h3 id="heading-character-set-matching">Character Set Matching</h3>
<p>A character set, also called character class, is a set of characters that will successfully match a certain character in a test string. This set of characters is enclosed in square brackets. </p>
<p>For instance, the pattern <code>[abc]</code> will match any of <code>a</code>, <code>b</code>, and <code>c</code>, while <code>[xyz]</code> will match any of <code>x</code>, <code>y</code>, and <code>z</code>.</p>
<p>Here are some examples of character sets and what they do:</p>
<ul>
<li><code>[abc]</code>: matches either <code>a</code>, <code>b</code>, or <code>c</code></li>
<li><code>[aeiou]</code>: matches any vowel character</li>
<li><code>[a-z]</code>: matches any lowercase letter from <code>a</code> to <code>z</code></li>
<li><code>[A-Z]</code>: matches any uppercase letter from <code>A</code> to <code>Z</code></li>
<li><code>[0-9]</code>: matches any digit from 0 to 9</li>
</ul>
<p>Inside the square brackets, you don’t need to escape metacharacters because they lose their special meaning. The only symbol that has a meaning in the square brackets is a hyphen (<code>-</code>), which you can use to specify ranges, as I have done with some examples of character sets. </p>
<p>You will also learn about ranges in this book. On some occasions, a backslash <code>\</code> does not lose its special meaning in a character set.</p>
<p>As with literal character matching, only the first occurrence of the character set will return as a match, every other occurrence will be ignored. In the next chapter, you will learn how to match multiple occurrences of a character with the <code>g</code> flag.</p>
<p>Here’s how each of the above character sets works in a regex testing tool:</p>
<p><code>[abc]</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/-abc--match.png" alt="-abc--match" width="600" height="400" loading="lazy"></p>
<p><code>[aeiou]</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/vowels-match.png" alt="vowels-match" width="600" height="400" loading="lazy"></p>
<p><code>[a-z]</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/lcase-set-match.png" alt="lcase-set-match" width="600" height="400" loading="lazy"></p>
<p><code>[A-Z]</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/ucase-set-match.png" alt="ucase-set-match" width="600" height="400" loading="lazy"></p>
<p><code>[0-9]</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/number-set-match.png" alt="number-set-match" width="600" height="400" loading="lazy"></p>
<p>You can also define your unique character class based on what you want. Character sets are useful when you want to match some characters in a particular position in a text.</p>
<p>For instance, the pattern <code>br[ao]ke</code> will match both <code>brake</code> and <code>broke</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/brakebroke-match.png" alt="brakebroke-match" width="600" height="400" loading="lazy"></p>
<p>The pattern <code>gr[ae]y</code> will match both <code>gray</code> and <code>grey</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/graygrey-match.png" alt="graygrey-match" width="600" height="400" loading="lazy"></p>
<p><strong>N.B.</strong>: I turned on the <code>g</code> flag so you can see all the matches, and how powerful character sets are. We will take a look at the <code>g</code> and other flags in the next chapter.</p>
<p>Since there are always multiple ways of doing the same thing in programming, there are also certain character sets called "shorthand character sets" that you can use instead of character sets. </p>
<p>Since these shorthand character sets are a subset of metacharacters, you will learn about them under the chapter dedicated to metacharacters.</p>
<h2 id="heading-chapter-3-regular-expressions-flags">Chapter 3: Regular Expressions Flags</h2>
<p>Also called modifiers, flags are special characters you can place at the end or within a regular expressions pattern to alter its default behavior. </p>
<p>JavaScript developers tend to refer to these characters as "flags", but in Python they are used interchangeably. </p>
<p>In Python, you can place flags within a regex pattern, but in JavaScript, flags are always placed at the end of the regex pattern.</p>
<p>Here are the flags you can use in regular expressions:</p>
<ul>
<li><code>global</code> flag</li>
<li><code>case insensitive</code> flag</li>
<li><code>multi-line</code> flag</li>
<li><code>single-line</code> flag</li>
<li><code>unicode</code> flag</li>
<li><code>sticky</code> flag</li>
</ul>
<p>In many regex engines, you can turn on any flag you want to use. In regex101.com, you can turn on a flag by clicking on the slash symbol (<code>/</code>) right inside the pattern input: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/turn-on-a-flag-101.png" alt="turn-on-a-flag-101" width="600" height="400" loading="lazy"></p>
<p>You can then select any flag you want to use:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/select-flag-101.png" alt="select-flag-101" width="600" height="400" loading="lazy"></p>
<p><strong>N.B.</strong>: If the flavor of regex you selected in regex101.com is not ECMAScript, the set of flags presented to you might be different.</p>
<p>If you are using regexpal.com, click on "flags" above the regex pattern input:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/turn-on-flag-pal.png" alt="turn-on-flag-pal" width="600" height="400" loading="lazy"></p>
<p>Select any flag you want by clicking on it:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/select-flag-pal.png" alt="select-flag-pal" width="600" height="400" loading="lazy"></p>
<p>Now, let's take a detailed look at each of the regex flags and how they work in a regex engine.</p>
<h3 id="heading-the-global-flag">The <code>global</code> Flag</h3>
<p>The <code>global</code> flag is denoted by the letter <code>g</code>. With it, you get to perform a global match with your pattern. </p>
<p>Remember in the previous chapter of this book, some patterns I defined stopped when they found the first match, even if there were more. That’s because by default, regular expressions only find the first match in a text. But with the <code>g</code> flag, all occurrences of the match are returned.</p>
<p>Another good thing about using the <code>g</code> flag is that you can iterate over the matches you get with the pattern in JavaScript. The iteration continues until there’s nothing to match. You will learn about multiple ways you can iterate over matches soon.</p>
<p>To let you see how the <code>g</code> flag works, I’ll use the <code>hatch</code> and <code>freeCodeCamp</code> examples from the previous chapter.</p>
<p>If you want to match the letters <code>h</code> in the word <code>hatch</code> with the pattern <code>h</code>, both the first and the last <code>h</code>s will be returned as matches as long as you have the <code>g</code> flag on:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/h-in-hatch-g-match.png" alt="h-in-hatch-g-match" width="600" height="400" loading="lazy"></p>
<p>And if you want to match <code>e</code> in <code>freeCodeCamp</code> with the pattern <code>e</code> and you turn on the <code>g</code> flag, the second and third <code>e</code>s are returned as a match too:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/e-in-fcc-g-match.png" alt="e-in-fcc-g-match" width="600" height="400" loading="lazy"></p>
<h3 id="heading-the-case-insensitive-flag">The <code>case-insensitive</code> Flag</h3>
<p>The <code>case insensitive</code> flag is denoted by <code>i</code>. As the name implies, it lets you perform case-insensitive matching.</p>
<p>By default, regular expressions perform case-sensitive matching. But with the <code>i</code> flag you can perform case-insensitive matching, so you won’t bother about casing in your patterns.</p>
<p>With this, uppercase or lowercase will be ignored. That means <code>Hello</code> and <code>hello</code> will be treated as the same thing:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/hello-insensitive.png" alt="hello-insensitive" width="600" height="400" loading="lazy"></p>
<p><code>freeCodeCamp</code> and <code>freecodecamp</code> are treated the same, too:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/fcc-insensitive.png" alt="fcc-insensitive" width="600" height="400" loading="lazy"></p>
<p><code>RegEx</code> and <code>regex</code> are also the same thing:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/regex-insensitive.png" alt="regex-insensitive" width="600" height="400" loading="lazy"></p>
<p>Another thing is that if you’re using a character class, for example <code>[a-z]</code>, it would match uppercase letters too if you turn on the <code>case-insensitive</code> flag.</p>
<p>So, the pattern <code>[a-z]</code> also matches uppercase letters with the <code>case-insensitive</code> flag turned on:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/carset-insensitive.png" alt="carset-insensitive" width="600" height="400" loading="lazy"></p>
<h3 id="heading-the-multi-line-and-single-line-flags">The <code>multi-line</code> and <code>single-line</code> Flags</h3>
<p>Denoted by <code>m</code>, the <code>multi-line</code> flag tells the regular expressions engine that the test string is more than one line. Since the <code>multi-line</code> flag influences the behavior of the start and end anchor metacharacters (<code>^</code> and <code>$</code>), you’ll learn more about it under the anchors and word boundaries chapter.</p>
<p>The <code>single-line</code> flag is denoted by <code>s</code>. Just like the <code>multi-line</code> flag, the <code>single-line</code> flag also works with a metacharacter called the wildcard (<code>.</code>).  You will see the <code>single-line</code> flag in action under the chapter for metacharacters.</p>
<h3 id="heading-the-unicode-flag">The <code>Unicode</code> Flag</h3>
<p>The Unicode flag enables full Unicode matching in the regular expressions engine that supports it. It is denoted by <code>u</code>.</p>
<p>By default, JavaScript and many other programming languages treat strings as a sequence of 16-bit code units. With the <code>u</code> flag, regex patterns can match against Unicode code points instead of code units. This allows handling characters like emojis, certain symbols, and characters from non-Latin scripts. So, when you set the flag, it modifies the behavior of certain escape sequences and metacharacters to work with regular expressions.</p>
<p>For example, the escape sequence <code>\u{1F602}</code> will match the literal character <code>u{1F602}</code> if you don’t turn on the <code>u</code> flag:
<img src="https://www.freecodecamp.org/news/content/images/2023/07/u-flag-literal-match.png" alt="u-flag-literal-match" width="600" height="400" loading="lazy"></p>
<p>But if you turn on the <code>u</code> flag, the same pattern matches the face with tears emoji:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/u-flag-emoji-match.png" alt="u-flag-emoji-match" width="600" height="400" loading="lazy"></p>
<p>That is one way to match emojis and other Unicode characters. Take the Unicode of the emoji and put the hexadecimal in curly braces, then precede the two with <code>\u</code>.</p>
<p>For instance, the Unicode of growing heart is <code>U+1F497</code>, the pattern to match it would be <code>\u{1F497}</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/growing-heart-match.png" alt="growing-heart-match" width="600" height="400" loading="lazy"></p>
<p>You will see more examples of how the flag works in the chapter on how to use regular expressions in JavaScript.</p>
<h3 id="heading-the-sticky-flag">The <code>sticky</code> Flag</h3>
<p>The sticky flag is denoted by <code>y</code>. It’s a feature of JavaScript regular expressions implemented in ECMAScript 6. The <code>y</code> flag limits matching to the current position in the string, which you can specify with the <code>lastIndex</code> property of the <code>RegExp()</code> constructor.</p>
<p>When you use the <code>y</code> flag, it uses the <code>lastIndex</code> property to determine where the next search will start. The pattern matches only if it occurs exactly at the lastIndex position or at the beginning of the string.</p>
<p>Unlike the global (<code>g</code>) flag, the <code>y</code> flag does not find all matches but stops after the first successful match.</p>
<p>In a regex engine like regex101.com, the <code>y</code> flag usually anchors to the start of the test string and stops there:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/anchor-flag-match.png" alt="anchor-flag-match" width="600" height="400" loading="lazy"></p>
<p>Since the <code>y</code> flag typically works with the <code>lastIndex</code> property of JavaScript regular expressions, we will look at more examples in the chapter on how to use regular expressions in JavaScript – specifically when we look at the <code>sticky</code> of the regular expressions constructor.</p>
<p>You can also combine multiple flags to write more complex syntax. For example, you can use the <code>g</code> flag with the <code>i</code> flag for global and case-insensitive matching:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/g-and-i-flag.png" alt="g-and-i-flag" width="600" height="400" loading="lazy"></p>
<h2 id="heading-chapter-4-how-to-use-regular-expressions-in-javascript">Chapter 4: How to Use Regular Expressions in JavaScript</h2>
<h3 id="heading-how-to-create-regular-expressions-in-javascript">How to Create Regular Expressions in JavaScript</h3>
<p>There are two ways you can create regular expressions in JavaScript. The first is with <strong>regex literal syntax</strong> and the second is with the <code>RegExp()</code> constructor.</p>
<p>To create a regular expression with the regex literal syntax, you have to enclose the pattern inside two forward slashes (<code>/</code>) like this:</p>
<pre><code class="lang-js">/regex pattern/
</code></pre>
<p>If you want to use one or more flags, it has to be after the second slash:</p>
<pre><code class="lang-js">/regex pattern/flag
</code></pre>
<p>Depending on your use case, you might have to assign the regex to a variable:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> regex = <span class="hljs-regexp">/regex pattern/</span>flag
</code></pre>
<p>The flag could be any of the flags available in the JavaScript regular expressions engine.</p>
<p>If you want to create regular expressions with the <code>RegExp()</code> constructor, you have to use the <code>new</code> keyword, then put the pattern and the flag inside the <code>RegExp()</code> brackets. </p>
<p>This is what the syntax looks like:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> regex = <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(<span class="hljs-string">"regex pattern"</span>, <span class="hljs-string">"flag"</span>);
</code></pre>
<p>Since <code>RegExp()</code> is a constructor, there are some methods and properties available in it with which you can work with regular expressions. Whether you create your pattern with the literal syntax <code>//</code> or the <code>RegExp()</code> constructor, the methods and properties are available for it.</p>
<h3 id="heading-methods-of-the-regexp-constructor">Methods of the <code>RegExp()</code> Constructor</h3>
<p>The methods of the <code>RegExp()</code> constructor are defined on the <code>RegExp.prototype</code>. You can quickly check the methods (and properties) by typing <code>RegExp().__proto__</code> and hitting <code>ENTER</code> in your browser console. These methods include <code>test()</code>, <code>exec()</code>, and <code>toString()</code>. </p>
<p>Apart from those three, some methods take regular expressions as a parameter. But it is better to discuss them under "string methods for working with regular expressions" because, at their core, they are string methods that take regular expressions as a parameter.</p>
<p>Let’s take a look at what <code>test()</code>, <code>exec()</code>, and <code>toString()</code> do.</p>
<h4 id="heading-the-test-method">The <code>test()</code> Method</h4>
<p>The <code>test()</code> method tests for a match between a regular expression and the test string and returns a boolean as the result. If there's a match, it returns <code>true</code>, and if there's no match, it returns <code>false</code>.</p>
<p>In the example below, there's a match for the pattern <code>/freeCodeCamp/</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/freeCodeCamp/</span>;
<span class="hljs-keyword">const</span> testStr =
  <span class="hljs-string">"freeCodeCamp doesn't charge you any money, that's why it's called freeCodeCamp."</span>;

<span class="hljs-built_in">console</span>.log(re.test(testStr)); <span class="hljs-comment">//true</span>
</code></pre>
<p>But in the example below, there's no match for the pattern <code>/fcc/</code>, so the <code>test()</code> method returns <code>false</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/fcc/</span>;
<span class="hljs-keyword">const</span> testStr =
  <span class="hljs-string">"freeCodeCamp doesn't charge you any money, that's why it's called freeCodeCamp."</span>;

<span class="hljs-built_in">console</span>.log(re.test(testStr)); <span class="hljs-comment">//false</span>
</code></pre>
<p>Apart from testing random patterns against a string, the <code>test()</code> method can be useful in form validation. </p>
<h4 id="heading-the-exec-method">The <code>exec()</code> Method</h4>
<p>The <code>exec()</code> method executes a search for a match in a test string and returns an array containing a piece of detailed information about the first match. If there's no match, it returns <code>null</code>.</p>
<p>That detailed information contains the <strong>first match</strong>, <strong>the index of the match</strong>, <strong>captured groups</strong> (if any), and the <strong>length</strong>.</p>
<p>Here's an example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/freeCodeCamp/</span>;
<span class="hljs-keyword">const</span> testStr =
  <span class="hljs-string">"freeCodeCamp doesn't charge you any money, that's why it's called freeCodeCamp."</span>;

<span class="hljs-built_in">console</span>.log(re.exec(testStr));
</code></pre>
<p>And here’s a screenshot of the result:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/exec-res.png" alt="exec-res" width="600" height="400" loading="lazy"></p>
<p>If you want to make the <code>exec()</code> method return all the matches, you can use the <code>g</code> flag on the pattern and then loop through with a <code>while</code> loop:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/freeCodeCamp/g</span>;
<span class="hljs-keyword">const</span> testStr =
  <span class="hljs-string">"freeCodeCamp is a great place to start learning to code from scratch. freeCodeCamp doesn't charge you any money, that's why it's called freeCodeCamp."</span>;

<span class="hljs-keyword">let</span> match;

<span class="hljs-keyword">while</span> ((match = re.exec(testStr)) !== <span class="hljs-literal">null</span>) {
  <span class="hljs-built_in">console</span>.log(match[<span class="hljs-number">0</span>]);
}
</code></pre>
<p>Here's what the result looks like in the console:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/exec-multi-res.png" alt="exec-multi-res" width="600" height="400" loading="lazy"></p>
<p>You can go further by accessing the index of the matches this way:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/freeCodeCamp/g</span>;
<span class="hljs-keyword">const</span> testStr =
  <span class="hljs-string">"freeCodeCamp is a great place to start learning to code from scratch. freeCodeCamp doesn't charge you any money, that's why it's called freeCodeCamp."</span>;

<span class="hljs-keyword">let</span> match;

<span class="hljs-keyword">while</span> ((match = re.exec(testStr)) !== <span class="hljs-literal">null</span>) {
  <span class="hljs-built_in">console</span>.log(match[<span class="hljs-number">0</span>]);

  <span class="hljs-comment">//   Access the indices of the matches</span>
  <span class="hljs-built_in">console</span>.log(match.index);
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/exec-indices-res.png" alt="exec-indices-res" width="600" height="400" loading="lazy"></p>
<p>If there's no match, <code>exec()</code> returns null:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/fcc/</span>;
<span class="hljs-keyword">const</span> testStr =
  <span class="hljs-string">"freeCodeCamp doesn't charge you any money, that's why it's called freeCodeCamp."</span>;

<span class="hljs-built_in">console</span>.log(re.exec(testStr)); <span class="hljs-comment">//null</span>
</code></pre>
<h4 id="heading-the-tostring-method">The <code>toString()</code> Method</h4>
<p>The <code>toString()</code> method converts a regex pattern to a string. In JavaScript, the <code>toString()</code> method is in every object. Regular expressions are treated as an object behind the scenes, that's why you can create them with the <code>new</code> keyword.</p>
<p>Using this method on a regex pattern converts the pattern to a string:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> pattern = <span class="hljs-regexp">/freeCodeCamp/</span>;
<span class="hljs-keyword">const</span> strPattern = pattern.toString();

<span class="hljs-built_in">console</span>.log(strPattern, <span class="hljs-keyword">typeof</span> strPattern); <span class="hljs-comment">// /freeCodeCamp/ string</span>
</code></pre>
<p>Even if you create the pattern with the <code>RegExp()</code> constructor, you get the result the same way:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> pattern = <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(<span class="hljs-string">'freeCodeCamp'</span>);
<span class="hljs-keyword">const</span> strPattern = pattern.toString();

<span class="hljs-built_in">console</span>.log(strPattern, <span class="hljs-keyword">typeof</span> strPattern); <span class="hljs-comment">// /freeCodeCamp/ string</span>
</code></pre>
<p>And if you have a flag in the pattern, it would be returned as a part of the string:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> pattern = <span class="hljs-regexp">/freeCodeCamp/gi</span>;
<span class="hljs-keyword">const</span> strPattern = pattern.toString();

<span class="hljs-built_in">console</span>.log(strPattern, <span class="hljs-keyword">typeof</span> strPattern); <span class="hljs-comment">// /freeCodeCamp/gi string</span>
</code></pre>
<h3 id="heading-properties-of-the-regexp-constructor">Properties of the <code>RegExp()</code> Constructor</h3>
<p>The properties of the <code>RegExp()</code> constructor are defined on the <code>RegExp.prototype</code>. They include:</p>
<ul>
<li><code>RegExp.prototype.global</code></li>
<li><code>RegExp.prototype.source</code></li>
<li><code>RegExp.prototype.flags</code></li>
<li><code>RegExp.prototype.multiline</code></li>
<li><code>RegExp.prototype.ignoreCase</code></li>
<li><code>RegExp.prototype.dotAll</code></li>
<li><code>RegExp.prototype.sticky</code></li>
<li><code>RegExp.prototype.unicode</code></li>
</ul>
<p>In short, there are the <code>global</code>, <code>source</code>, <code>flags</code>, <code>multiline</code>, <code>ignoreCase</code>, <code>dotAll</code>, <code>sticky</code>, and <code>unicode</code>.</p>
<p>Most of the properties check whether a certain flag is used or not. Let's take a look at how each of the properties works. </p>
<h4 id="heading-the-global-property">The <code>global</code> Property</h4>
<p>The global property checks whether the <code>g</code> flag is used with a regex pattern or not. If the pattern has the <code>g</code> flag, it returns <code>true</code>, otherwise it returns <code>false</code>. </p>
<p>Remember the <code>global</code> (<code>g</code>) flag indicates that the regex pattern should not just return the first match but all the matches.</p>
<p>Here's how the <code>global</code> property works in code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re1 = <span class="hljs-regexp">/freeCodeCamp/g</span>;
<span class="hljs-keyword">const</span> re2 = <span class="hljs-regexp">/freeCodeCamp/</span>;
<span class="hljs-keyword">const</span> re3 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(<span class="hljs-string">'freeCodeCamp'</span>);
<span class="hljs-keyword">const</span> re4 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(<span class="hljs-string">'freeCodeCamp'</span>, <span class="hljs-string">'g'</span>);

<span class="hljs-built_in">console</span>.log(re1.global); <span class="hljs-comment">//true</span>
<span class="hljs-built_in">console</span>.log(re2.global); <span class="hljs-comment">//false</span>
<span class="hljs-built_in">console</span>.log(re3.global); <span class="hljs-comment">//false</span>
<span class="hljs-built_in">console</span>.log(re4.global); <span class="hljs-comment">//true</span>
</code></pre>
<h4 id="heading-the-flag-property">The <code>flag</code> Property</h4>
<p>The flag property returns the flags you use in the regex pattern in alphabetical order. That is, <code>g</code> before <code>i</code>, <code>i</code> before <code>m</code>, <code>m</code> before <code>y</code>, and so on.</p>
<p>In the code below, you can see that the <code>g</code> flag comes before <code>i</code>, and <code>m</code> comes before <code>y</code>: </p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re1 = <span class="hljs-regexp">/freeCodeCamp/gi</span>;
<span class="hljs-keyword">const</span> re2 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(<span class="hljs-string">'freeCodeCamp'</span>, <span class="hljs-string">'my'</span>);

<span class="hljs-built_in">console</span>.log(re1.flags); <span class="hljs-comment">//gi</span>
<span class="hljs-built_in">console</span>.log(re2.flags); <span class="hljs-comment">//my</span>
</code></pre>
<h4 id="heading-the-source-property">The <code>source</code> Property</h4>
<p>The <code>source</code> property returns the regex pattern as a string. So, it acts like the <code>toString()</code> method.</p>
<p>The difference between the <code>source</code> property and the <code>toString()</code> method is that the <code>source</code> property excludes the flag you use with the pattern. Also, the <code>source</code> property does not show the literal forward slashes you use for creating the regex.</p>
<p>In the code below, you can see the forward slashes don’t get printed, the flags are omitted too, and the <code>type</code> is a string:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re1 = <span class="hljs-regexp">/freeCodeCamp/gi</span>;
<span class="hljs-keyword">const</span> re2 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(<span class="hljs-string">'freeCodeCamp'</span>, <span class="hljs-string">'my'</span>);

<span class="hljs-keyword">const</span> re1Source = re1.source;
<span class="hljs-keyword">const</span> re2Source = re2.source;

<span class="hljs-built_in">console</span>.log(re1Source, <span class="hljs-keyword">typeof</span> re1Source); <span class="hljs-comment">// freeCodeCamp string</span>
<span class="hljs-built_in">console</span>.log(re2Source, <span class="hljs-keyword">typeof</span> re2Source); <span class="hljs-comment">// freeCodeCamp string</span>
</code></pre>
<h4 id="heading-the-multiline-property">The <code>multiline</code> Property</h4>
<p>The <code>multiline</code> flag is another boolean property of the <code>RegExp()</code> constructor. It specifies whether the <code>multiline</code> flag is used with the pattern or not by returning <code>true</code> or <code>false</code>. </p>
<p>Remember the <code>multiline</code> (<code>m</code>) flag indicates that the test string should be treated as a text that has more than one line.</p>
<p>Here's how the <code>multiline</code> property works in action:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re1 = <span class="hljs-regexp">/freeCodeCamp/gi</span>;
<span class="hljs-keyword">const</span> re2 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(<span class="hljs-string">'freeCodeCamp'</span>, <span class="hljs-string">'my'</span>);

<span class="hljs-keyword">const</span> re1Source = re1.multiline;
<span class="hljs-keyword">const</span> re2Source = re2.multiline;

<span class="hljs-built_in">console</span>.log(re1Source); <span class="hljs-comment">//false</span>
<span class="hljs-built_in">console</span>.log(re2Source); <span class="hljs-comment">// true</span>
</code></pre>
<h4 id="heading-the-ignorecase-property">The ignoreCase Property</h4>
<p>The <code>ignoreCase</code> property specifies whether the case-insensitive flag (<code>i</code>) is used in the regex pattern. It returns <code>true</code> if you use the <code>i</code> flag and <code>false</code> if you don’t use it.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re1 = <span class="hljs-regexp">/freeCodeCamp/i</span>;
<span class="hljs-keyword">const</span> re2 = <span class="hljs-regexp">/freeCodeCamp/</span>;
<span class="hljs-keyword">const</span> re3 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(<span class="hljs-string">'freeCodeCamp'</span>, <span class="hljs-string">'i'</span>);
<span class="hljs-keyword">const</span> re4 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(<span class="hljs-string">'freeCodeCamp'</span>);

<span class="hljs-built_in">console</span>.log(re1.ignoreCase); <span class="hljs-comment">//true</span>
<span class="hljs-built_in">console</span>.log(re2.ignoreCase); <span class="hljs-comment">// false</span>
<span class="hljs-built_in">console</span>.log(re3.ignoreCase); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(re4.ignoreCase); <span class="hljs-comment">// false</span>
</code></pre>
<h4 id="heading-the-unicode-property">The <code>Unicode</code> Property</h4>
<p>The <code>unicode</code> property helps you check whether the Unicode (<code>u</code>) flag is used in the regex pattern or not. If it finds the <code>u</code> flag, it returns <code>true</code>, otherwise it returns <code>false</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re1 = <span class="hljs-regexp">/\u{1F1F3}\u{1F1EC}/u</span>; <span class="hljs-comment">//matches the Nigerian flag emoji</span>
<span class="hljs-keyword">const</span> re2 = <span class="hljs-regexp">/\u{1F1F3}\u{1F1EC}/</span>;
<span class="hljs-keyword">const</span> re3 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(<span class="hljs-string">'\u{1F1F3}\u{1F1EC}'</span>, <span class="hljs-string">'u'</span>);
<span class="hljs-keyword">const</span> re4 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(<span class="hljs-string">'\u{1F1F3}\u{1F1EC}'</span>);

<span class="hljs-built_in">console</span>.log(re1.unicode); <span class="hljs-comment">//true</span>
<span class="hljs-built_in">console</span>.log(re2.unicode); <span class="hljs-comment">// false</span>
<span class="hljs-built_in">console</span>.log(re3.unicode); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(re4.unicode); <span class="hljs-comment">// false</span>
</code></pre>
<h4 id="heading-the-sticky-property">The <code>sticky</code> Property</h4>
<p>The sticky property indicates whether the sticky (<code>y</code>) flag is set in the regular expression or not. Even though that's what it does, it's still a bit tricky to understand because of the <code>lastIndex</code> property.</p>
<p>When the <code>y</code> flag is set, the regex engine in use will attempt to match the pattern starting at the exact position specified by the <code>lastIndex</code> property (without using the <code>g</code> flag). If a match is found, the <code>lastIndex</code> property is updated to the position immediately after the end of the match.</p>
<p>To help you understand that better, here's a code snippet with comments:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/xyz/y</span>;
<span class="hljs-keyword">const</span> str = <span class="hljs-string">'xyzxyz'</span>;

re.lastIndex = <span class="hljs-number">0</span>;
<span class="hljs-built_in">console</span>.log(re.test(str)); <span class="hljs-comment">// true – there's a match at index 0 to 2</span>
<span class="hljs-built_in">console</span>.log(re.lastIndex); <span class="hljs-comment">// 3</span>

re.lastIndex = <span class="hljs-number">1</span>;
<span class="hljs-built_in">console</span>.log(re.test(str)); <span class="hljs-comment">// false – no match at the specified index</span>
<span class="hljs-built_in">console</span>.log(re.lastIndex); <span class="hljs-comment">// 0 – resets to 0 because there's no match at the specified index</span>

re.lastIndex = <span class="hljs-number">3</span>;
<span class="hljs-built_in">console</span>.log(re.test(str)); <span class="hljs-comment">// true – there's a match at index 3 to 5</span>
<span class="hljs-built_in">console</span>.log(re.lastIndex); <span class="hljs-comment">// 6</span>

re.lastIndex = <span class="hljs-number">6</span>;
<span class="hljs-built_in">console</span>.log(re.test(str)); <span class="hljs-comment">// false</span>
<span class="hljs-built_in">console</span>.log(re.lastIndex); <span class="hljs-comment">// 0 – resets to 0 because there's no match at the specified index</span>
</code></pre>
<p><strong>N.B.</strong>: The <code>dotAll</code> property works with the wildcard (<code>.</code>) metacharacter. Due to that, you will see how it works in detail in the chapter on metacharacters. Also, <code>hasIndices</code> works with captures. So, you will see how to use it under the chapter on grouping and capturing.</p>
<h3 id="heading-string-methods-for-working-with-regular-expressions">String Methods for Working with Regular Expressions</h3>
<p>JavaScript provides some inbuilt methods for working with strings. Some of these methods take regular expressions as a parameter. These methods include <code>match()</code>, <code>matchAll()</code>, <code>replace()</code>, <code>replaceAll()</code>, <code>split()</code>, and <code>search()</code>.</p>
<p>Let's look at each of them one by one.</p>
<h4 id="heading-the-search-method">The <code>search()</code> Method</h4>
<p>The <code>search()</code> method searches for the match of a regular expression in a string and returns the index of the match. </p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr =
  <span class="hljs-string">"fCC is the abbreviation for freeCodeCamp. freeCodeCamp doesn't charge you any money, that's why it's called freeCodeCamp. Learn to code for free today."</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/freeCodeCamp/</span>;
<span class="hljs-keyword">const</span> searchFCC = myStr.search(re);

<span class="hljs-built_in">console</span>.log(searchFCC); <span class="hljs-comment">//28</span>
</code></pre>
<p>If the <code>search()</code> method finds no match, it returns <code>-1</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr =
  <span class="hljs-string">"fCC is the abbreviation for freeCodeCamp. freeCodeCamp doesn't charge you any money, that's why it's called freeCodeCamp. Learn to code for free today."</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/FCC/</span>;
<span class="hljs-keyword">const</span> searchFCC = myStr.search(re);

<span class="hljs-built_in">console</span>.log(searchFCC); <span class="hljs-comment">//-1</span>
</code></pre>
<p>You might be thinking using the <code>g</code> flag with the pattern would return the indices of all the matches, but this isn't the case. The <code>g</code> flag does not affect the <code>search()</code> method:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr =
  <span class="hljs-string">"fCC is the abbreviation for freeCodeCamp. freeCodeCamp doesn't charge you any money, that's why it's called freeCodeCamp. Learn to code for free today."</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/freeCodeCamp/g</span>; <span class="hljs-comment">//pattern with g flag</span>
<span class="hljs-keyword">const</span> searchFCC = myStr.search(re);

<span class="hljs-built_in">console</span>.log(searchFCC); <span class="hljs-comment">//28</span>
</code></pre>
<p>If you want to get the indices of all the matches, you should use the <code>match()</code> or <code>matchAll()</code> method.</p>
<h4 id="heading-the-match-method">The <code>match()</code> Method</h4>
<p>The <code>match()</code> method lets you specify a regex pattern as the parameter, then it runs through the string you use it against and returns an array containing the substring(s) that match the regex pattern.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> my_str = <span class="hljs-string">'freeCodeCamp'</span>;
match = my_str.match(<span class="hljs-regexp">/free/</span>);

<span class="hljs-built_in">console</span>.log(match); <span class="hljs-comment">// [ 'free', index: 0, input: 'freeCodeCamp', groups: undefined ]</span>
</code></pre>
<p>You can also separate the regex pattern into a separate variable:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> my_str = <span class="hljs-string">'freeCodeCamp'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/free/</span>;
<span class="hljs-keyword">const</span> match = my_str.match(re);

<span class="hljs-built_in">console</span>.log(match); <span class="hljs-comment">// [ 'free', index: 0, input: 'freeCodeCamp', groups: undefined ]</span>
</code></pre>
<p>If <code>match()</code> finds multiple matches, it returns all of them in the array, provided you use the <code>g</code> flag in the pattern: </p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> my_str =
  <span class="hljs-string">"freeCodeCamp doesn't charge you any money, that's why it's called freeCodeCamp. Learn to code for free today."</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/free/g</span>;
<span class="hljs-keyword">const</span> match = my_str.match(re);

<span class="hljs-built_in">console</span>.log(match); <span class="hljs-comment">// ['free', 'free', 'free']</span>
</code></pre>
<p>If you expand the array, this is what it looks like:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/match-method-matches.png" alt="match-method-matches" width="600" height="400" loading="lazy"></p>
<p>Since the result is an array, you should probably use <code>console.table()</code> instead of <code>console.log()</code> so you can see the indices of the matches:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> my_str =
  <span class="hljs-string">"freeCodeCamp doesn't charge you any money, that's why it's called freeCodeCamp. Learn to code for free today."</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/free/g</span>;
<span class="hljs-keyword">const</span> match = my_str.match(re);

<span class="hljs-built_in">console</span>.table(match);
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/match-console-table.png" alt="match-console-table" width="600" height="400" loading="lazy"></p>
<p>If the <code>match()</code> method finds no match, it returns <code>null</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> my_str = <span class="hljs-string">'freeCodeCamp'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/ref/</span>;
<span class="hljs-keyword">const</span> match = my_str.match(re);

<span class="hljs-built_in">console</span>.log(match); <span class="hljs-comment">// null</span>
</code></pre>
<h4 id="heading-the-matchall-method">The <code>matchAll()</code> Method</h4>
<p><code>matchAll()</code> is a hybrid of the <code>match()</code> method. It returns an iterator of all the substrings that match the regular expressions you provide. This means you have to use it with the <code>global</code> (<code>g</code>) flag.</p>
<p>Because it returns the iterator of all matches, <code>matchAll()</code> is a great option for looping through the matches of regular expressions. </p>
<p>An alternative to iterating through the matches of a regular expression is using the <code>exec()</code> method and <code>g</code> flag, then looping with a <code>while</code> loop this way:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> my_str =
  <span class="hljs-string">"freeCodeCamp doesn't charge you any money, that's why it's called freeCodeCamp. Learn to code for free today."</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/free/g</span>;

<span class="hljs-keyword">let</span> match;
<span class="hljs-keyword">while</span> ((match = re.exec(my_str))) {
  <span class="hljs-built_in">console</span>.log(match[<span class="hljs-number">0</span>]); <span class="hljs-comment">//</span>
}

<span class="hljs-comment">// free</span>
<span class="hljs-comment">// free</span>
<span class="hljs-comment">// free</span>
</code></pre>
<p>With the <code>matchAll()</code> method, you don’t need the <code>exec()</code> and <code>while</code> loop. All you need is a <code>for…of</code> loop to get the matches:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> my_str =
  <span class="hljs-string">"freeCodeCamp doesn't charge you any money, that's why it's called freeCodeCamp. Learn to code for free today."</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/free/g</span>;
<span class="hljs-keyword">const</span> matches = my_str.matchAll(re);

<span class="hljs-built_in">console</span>.log(matches); <span class="hljs-comment">// RegExpStringIterator {}</span>

<span class="hljs-comment">//loop through the matches with a for...of loop</span>
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> match <span class="hljs-keyword">of</span> matches) {
  <span class="hljs-built_in">console</span>.log(match);
}
</code></pre>
<p>This returns each <code>match</code>, their index, the test string, the length, and groups in their respective arrays:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/matchAll-console.png" alt="matchAll-console" width="600" height="400" loading="lazy"></p>
<p>You can modify the console log to get only the matches and their index this way:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> my_str =
  <span class="hljs-string">"freeCodeCamp doesn't charge you any money, that's why it's called freeCodeCamp. Learn to code for free today."</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/free/g</span>;
<span class="hljs-keyword">const</span> matches = my_str.matchAll(re);

<span class="hljs-built_in">console</span>.log(matches); <span class="hljs-comment">// RegExpStringIterator {}</span>

<span class="hljs-comment">//loop through the matches with a for...of loop</span>
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> match <span class="hljs-keyword">of</span> matches) {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Found a match <span class="hljs-subst">${match[<span class="hljs-number">0</span>]}</span> at index <span class="hljs-subst">${match.index}</span>`</span>);
}

<span class="hljs-comment">/*
Output:
Found a match free at index 0
Found a match free at index 66
Found a match free at index 98
*/</span>
</code></pre>
<p>You can also use the <code>Array.from()</code> method to do the same thing:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> my_str =
  <span class="hljs-string">"freeCodeCamp doesn't charge you any money, that's why it's called freeCodeCamp. Learn to code for free today."</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/free/g</span>;

<span class="hljs-built_in">Array</span>.from(my_str.matchAll(re), <span class="hljs-function">(<span class="hljs-params">match</span>) =&gt;</span>
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Found a match <span class="hljs-subst">${match[<span class="hljs-number">0</span>]}</span> at index <span class="hljs-subst">${match.index}</span>`</span>)
);

<span class="hljs-comment">/*
Output:
Found a match free at index 0
Found a match free at index 66
Found a match free at index 98
*/</span>
</code></pre>
<p>If the <code>matchAll()</code> method finds no match, it returns an empty iterator. And if you decide to loop through that empty iterator, there'll be nothing to see in the console.</p>
<h4 id="heading-the-replace-method">The <code>replace()</code> Method</h4>
<p>The <code>replace()</code> method does what its name implies. It searches for matches of a specified string or regular expression in a string and replaces them with the specified replacement string. It returns a new string with the replacements applied.</p>
<p>The <code>replace()</code> method is not as straightforward as <code>match()</code> and <code>matchAll()</code> because it accepts two parameters – a regular expression and the replacement string. Any substring of the test string that matches the regular expressions is then replaced with the replacement string.</p>
<p>If the regular expression does not include the global (<code>g</code>) flag, only the first match is replaced:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr =
  <span class="hljs-string">'Elephants are very large animals. They are large to the extent that they can uproot a large tree.'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/large/</span>;
<span class="hljs-keyword">const</span> replaceLarge = myStr.replace(re, <span class="hljs-string">'massive'</span>);

<span class="hljs-built_in">console</span>.log(replaceLarge); <span class="hljs-comment">// Elephants are very massive animals. They are large to the extent that they can uproot a large tree.</span>
</code></pre>
<p>If you use the <code>g</code> flag in the pattern, all the matches are replaced:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr =
  <span class="hljs-string">'Elephants are very large animals. They are large to the extent that they can uproot a large tree.'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/large/g</span>;
<span class="hljs-keyword">const</span> replaceLarge = myStr.replace(re, <span class="hljs-string">'massive'</span>);

<span class="hljs-built_in">console</span>.log(replaceLarge); <span class="hljs-comment">// Elephants are very massive animals. They are massive to the extent that they can uproot a massive tree.</span>
</code></pre>
<h4 id="heading-the-replaceall-method">The <code>replaceAll()</code> Method</h4>
<p>The <code>replaceAll()</code> method is relatively new because it became available in ECMAScript 2021. It is a hybrid of <code>replace()</code>.</p>
<p>Both <code>replace()</code> and <code>replaceAll()</code> do the same thing by taking a regular expression and a replacement string as parameters, and replacing all matches with the specified replacement string. </p>
<p>But unlike <code>replace()</code> which will only replace the first match if you don’t use the <code>g</code> flag, <code>replaceAll()</code> replaces all the matches by default:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr =
  <span class="hljs-string">'Elephants are very large animals. They are large to the extent that they can uproot a large tree.'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/large/g</span>;
<span class="hljs-keyword">const</span> replaceLarge = myStr.replaceAll(re, <span class="hljs-string">'massive'</span>);

<span class="hljs-built_in">console</span>.log(replaceLarge); <span class="hljs-comment">// Elephants are very massive animals. They are massive to the extent that they can uproot a massive tree.</span>
</code></pre>
<p>If you don’t use the <code>g</code> flag with <code>replaceAll()</code>, it throws a <code>TypeError</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr =
  <span class="hljs-string">'Elephants are very large animals. They are large to the extent that they can uproot a large tree.'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/large/</span>;
<span class="hljs-keyword">const</span> replaceLarge = myStr.replaceAll(re, <span class="hljs-string">'massive'</span>);

<span class="hljs-built_in">console</span>.log(replaceLarge); <span class="hljs-comment">// Uncaught TypeError: String.prototype.replaceAll called with a non-global RegExp argument</span>
<span class="hljs-comment">//    at String.replaceAll (&lt;anonymous&gt;)</span>
</code></pre>
<h4 id="heading-the-split-method">The <code>split()</code> Method</h4>
<p>The <code>split()</code> method takes a string or regex and splits the string you use it against into an array based on the string or regex you pass into it. The <code>split()</code> method also takes an optional <code>limit</code> parameter, a positive number. When you specify the <code>limit</code>, the splitting stops at that limit.</p>
<p>Wherever the <code>split()</code> finds a match, it creates a new item in the array. Here's how it works:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr = <span class="hljs-string">"Codes don't lie. You're the one doing something wrong."</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/\s/</span>; <span class="hljs-comment">// "\s" means white space - spacebar, backspace, tab, ENTER.</span>

<span class="hljs-keyword">const</span> splitedStr = myStr.split(re);
<span class="hljs-built_in">console</span>.log(splitedStr);

<span class="hljs-comment">/* 
Output:
[
  'Codes',  "don't",
  'lie.',   "You're",
  'the',    'one',
  'doing',  'something',
  'wrong.'
]
*/</span>
</code></pre>
<p>Here's how to use the <code>split()</code> method with the <code>limit</code> parameter:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr = <span class="hljs-string">"Codes don't lie. You're the one doing something wrong."</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/\s/</span>; <span class="hljs-comment">// "\s" means white space - spacebar, backspace, tab, ENTER.</span>

<span class="hljs-keyword">const</span> splitedStr = myStr.split(re, <span class="hljs-number">5</span>); <span class="hljs-comment">// 5 is the limit here</span>
<span class="hljs-built_in">console</span>.log(splitedStr);

<span class="hljs-comment">/*
output: [ 'Codes', "don't", 'lie.', "You're", 'the' ]
*/</span>
</code></pre>
<h3 id="heading-how-to-match-literal-characters-in-javascript-regular-expressions">How to Match Literal Characters in JavaScript Regular Expressions</h3>
<p>As I pointed out earlier, literal characters are texts or strings you will write patterns for as they are.</p>
<p>If you want to match the text <code>hello</code>, <code>/hello/</code> should be your pattern. You can then use the <code>i</code> flag with it to match both <code>hello</code> and <code>Hello</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> testString = <span class="hljs-string">'hello'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/hello/</span>;
<span class="hljs-keyword">const</span> re2 = <span class="hljs-regexp">/hello/i</span>;

<span class="hljs-built_in">console</span>.log(re.test(testString)); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(re2.test(testString)); <span class="hljs-comment">// true</span>
</code></pre>
<p>If you want to match <code>freeCodeCamp</code>, the pattern should be just that. You can also create a pattern that matches <code>freeCodeCamp</code> in any case:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> testString = <span class="hljs-string">'freeCodeCamp'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/freeCodeCamp/</span>;
<span class="hljs-keyword">const</span> re2 = <span class="hljs-regexp">/freeCodeCamp/i</span>; <span class="hljs-comment">// match freeCodeCamp in any case</span>

<span class="hljs-built_in">console</span>.log(re.test(testString)); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(re2.test(testString)); <span class="hljs-comment">// true</span>
</code></pre>
<p>You can also match digits using literal characters:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> num = <span class="hljs-number">10234</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/2/</span>;

<span class="hljs-built_in">console</span>.log(re.test(num)); <span class="hljs-comment">//true</span>
</code></pre>
<h3 id="heading-how-to-use-character-sets-in-javascript-regular-expressions">How to Use Character Sets in JavaScript Regular Expressions</h3>
<p>As a reminder, a character set is a group of characters enclosed in square brackets. They provide a way to specify a set of characters from which the regex engine can match a single character at a specific position in a test string. </p>
<p>Character sets allow you to specify a range of characters, individual characters, or a combination of both.</p>
<p>Here are common examples of popular character sets in regular expressions:</p>
<ul>
<li><code>[abc]</code>: matches either <code>a</code>, <code>b</code>, or <code>c</code></li>
<li><code>[aeiou]</code>: matches any vowel character</li>
<li><code>[a-z]</code>: matches any lowercase letter from <code>a</code> to <code>z</code></li>
<li><code>[A-Z]</code>: matches any uppercase letter from <code>A</code> to <code>Z</code></li>
<li><code>[0-9]</code>: matches any digit from 0 to 9</li>
</ul>
<p>Let's look at how to match each of the above character sets in JavaScript regular expressions:</p>
<pre><code class="lang-js"><span class="hljs-comment">// uppercase character set</span>
<span class="hljs-keyword">const</span> hcaseRe = <span class="hljs-regexp">/[A-Z]/</span>;
<span class="hljs-keyword">const</span> hcaseStr = <span class="hljs-string">'freeCodeCamp is cool'</span>;

<span class="hljs-built_in">console</span>.log(hcaseRe.test(hcaseStr)); <span class="hljs-comment">//true</span>

<span class="hljs-comment">// vowels character set</span>
<span class="hljs-keyword">const</span> vowelsRe = <span class="hljs-regexp">/[aeiou]/</span>;
<span class="hljs-keyword">const</span> vowelsStr = <span class="hljs-string">'Imagine how pronunciation would have been without vowels'</span>;

<span class="hljs-built_in">console</span>.log(vowelsRe.test(vowelsStr)); <span class="hljs-comment">//true</span>

<span class="hljs-comment">// [abc] character set</span>
<span class="hljs-keyword">const</span> abcSetRe = <span class="hljs-regexp">/[abc]/</span>;
<span class="hljs-keyword">const</span> abcSetStr = <span class="hljs-string">'freeCodeCamp is totally free'</span>;

<span class="hljs-built_in">console</span>.log(abcSetRe.test(abcSetStr)); <span class="hljs-comment">//true</span>

<span class="hljs-comment">// number character set</span>
<span class="hljs-keyword">const</span> numRe = <span class="hljs-regexp">/[0-9]/</span>;
<span class="hljs-keyword">const</span> numStr = <span class="hljs-string">'Thank God for Arabic numerals 0 to 9.'</span>;

<span class="hljs-built_in">console</span>.log(numRe.test(numStr)); <span class="hljs-comment">//true</span>
</code></pre>
<h2 id="heading-chapter-5-metacharacters-quantifiers-repeated-matches-and-optional-matches">Chapter 5: Metacharacters, Quantifiers, Repeated Matches, and Optional Matches</h2>
<h3 id="heading-what-are-metacharacters">What are Metacharacters?</h3>
<p>In regular expressions, metacharacters are characters that have special meanings beyond their literal meaning. </p>
<p>Metacharacters are the backbone of regular expressions. They serve as the building blocks for constructing better regex patterns and defining the behavior of the regular expression engine you're using, but with an extra learning curve.</p>
<p>This part of the book is where you will learn about topics such as:</p>
<ul>
<li>Anchors</li>
<li>Word boundaries</li>
<li>How to specify character ranges</li>
<li>How to match every occurrence with the wildcard</li>
<li>Alternation</li>
<li>Greediness and laziness of regular expressions and how to prevent greediness</li>
</ul>
<p>And lots more.</p>
<p>If you want to match any metacharacter as a literal character, you have to escape it with a backslash (<code>\</code>). And if there's a metacharacter represented by a word, you have to escape it with the backslash too. So, the backslash is also a separate metacharacter.</p>
<p>There's a metacharacter to negate most metacharacters. For instance, <code>\b</code> and <code>\s</code> represent the word boundary and space metacharacters. If you want to negate them, you can use <code>\B</code> and <code>\S</code> respectively. That's the pattern most metacharacters follow – the small letter is the metacharacter and the capital letter negates it.</p>
<p>Metacharacters are categorized into single and double metacharacters. As the name implies, single metacharacters have a "single" character and double metacharacters have a "double" character. </p>
<p>Most metacharacters are also called shorthand character classes. As we look at each metacharacter, you will see whether it is a single or double metacharacter.</p>
<h3 id="heading-the-word-and-non-word-metacharacters">The Word and Non-word Metacharacters</h3>
<p>Represented by <code>\w</code>, the word metacharacter is a shorthand character class that matches all word characters. Word characters are alphanumeric characters and underscores. So, they are <code>a-z</code>, A-Z, <code>0-9</code>, and underscore (<code>_</code>).</p>
<p>Here's what happens when you use <code>\w</code> in a regex tester:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/w-matches.png" alt="w-matches" width="600" height="400" loading="lazy"></p>
<p>And here’s how it works in JavaScript:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> testStr =
  <span class="hljs-string">'Every alphanumeric character (a to z and 0 to 9) and underscore (_) is a word character'</span>;
<span class="hljs-keyword">const</span> wordCharacterRe = <span class="hljs-regexp">/\w/g</span>;

<span class="hljs-built_in">console</span>.log(testStr.match(wordCharacterRe));
</code></pre>
<p>Since word characters are alphanumeric characters and underscores, you can simulate the <code>\w</code> metacharacter by putting all the examples in a character set:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> testStr =
  <span class="hljs-string">'Every alphanumeric character (a to z and 0 to 9) and underscore (_) is a word character'</span>;
<span class="hljs-keyword">const</span> wordCharacterRe = <span class="hljs-regexp">/[a-z A-Z 0-9_]/g</span>;

<span class="hljs-built_in">console</span>.log(testStr.match(wordCharacterRe));
</code></pre>
<p>The non-word metacharacter is the opposite of the word metacharacter and it is represented by an escaped capital letter W (<code>\W</code>). </p>
<p>The non-word metacharacter matches every other character apart from alphanumeric characters and the underscore. That includes spaces, punctuation marks, and symbols:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/w-matches-1.png" alt="w-matches-1" width="600" height="400" loading="lazy"></p>
<p>Here it is in action in some JavaScript code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> testStr =
  <span class="hljs-string">'Every character apart from alphanumeric characters (a to z and 0 to 9) and underscore (_) is a non-word character'</span>;
<span class="hljs-keyword">const</span> nonWordCharacterRe = <span class="hljs-regexp">/\W/g</span>;

<span class="hljs-built_in">console</span>.log(testStr.match(nonWordCharacterRe));
</code></pre>
<p>Since you can represent the word metacharacter by putting all the characters in a character set, you may be wondering how you can do the same for the non-word metacharacter. </p>
<p>That's where the negated character set comes in. The caret (<code>^</code>) is used for negation. It is one of the two <strong>anchor metacharacters</strong>, which we'll look at next.</p>
<h3 id="heading-the-anchor-metacharacters">The Anchor Metacharacters</h3>
<p>Caret (<code>^</code>) and dollar sign (<code>$</code>) are the two anchor metacharacters. They are both single metacharacters.</p>
<p>The caret anchors the regex pattern to the start of a line or string, so you can call it a "start of line anchor". </p>
<p>For example, if you want to match the text "freeCodeCamp" and you want to make sure it's at the start of the line or a string, you can use the caret this way:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/fcc-anchor-match.png" alt="fcc-anchor-match" width="600" height="400" loading="lazy"></p>
<p>If the <code>freeCodeCamp</code> text is not at the start of the line, there won't be a match:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/fcc-anchor-no-match.png" alt="fcc-anchor-no-match" width="600" height="400" loading="lazy"></p>
<p>Here are the two cases in JavaScript code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> testStr =
  <span class="hljs-string">"freeCodeCamp doesn't charge you any money. That's why it's called freeCodeCamp because. Learn to code for free today."</span>; <span class="hljs-comment">// has "freeCodeCamp" at the start of the line</span>

<span class="hljs-keyword">const</span> testStr2 =
  <span class="hljs-string">"It's called freeCodeCamp because freeCodeCamp doesn't charge you any money. Learn to code for free today."</span>; <span class="hljs-comment">// does not have "freeCodeCamp" at the start of the line</span>

<span class="hljs-keyword">const</span> startAnchorRe = <span class="hljs-regexp">/^freeCodeCamp/</span>;

<span class="hljs-built_in">console</span>.log(startAnchorRe.test(testStr)); <span class="hljs-comment">//true</span>
<span class="hljs-built_in">console</span>.log(startAnchorRe.test(testStr2)); <span class="hljs-comment">//false</span>
</code></pre>
<p>The dollar sign metacharacter is the opposite of the caret. It anchors the regex pattern to the end of the line or string. So, there will only be a match if the target text is at the end of the line.</p>
<p>To use the <code>$</code> metacharacter, it has to be the last character in your pattern:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/dollar-meta-match.png" alt="dollar-meta-match" width="600" height="400" loading="lazy"></p>
<p>If the target string has more than one line and the target text is at the end of each line, the last one matches:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/dollar-last-match.png" alt="dollar-last-match" width="600" height="400" loading="lazy"></p>
<p>To correct this behavior, you have to use both the <code>g</code> and <code>m</code> flags:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/dollar-multiple-match.png" alt="dollar-multiple-match" width="600" height="400" loading="lazy"></p>
<p>Here are all the cases in JavaScript code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> testStr =
  <span class="hljs-string">"The lion is not the king of the jungle because of its strength, the lion is the king of the jungle because it's never intimidated"</span>;

<span class="hljs-keyword">const</span> testStr2 = <span class="hljs-string">`The lion is not the king of the jungle because of its strength, the lion is the king of the jungle because it's never intimidated

This is another line that ends with intimidated

And this is the last line that ends with intimidated

And this is the last line that ends with intimidated`</span>;

<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/intimidated$/</span>;
<span class="hljs-keyword">const</span> re2 = <span class="hljs-regexp">/intimidated$/gm</span>;

<span class="hljs-built_in">console</span>.log(re.test(testStr)); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(re.test(testStr2)); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(re2.test(testStr2)); <span class="hljs-comment">// true</span>
</code></pre>
<p>If the target text is not at the end of the line, there won't be any match:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> testStr =
  <span class="hljs-string">"A lion can never be intimidated because it's the king of the jungle"</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/intimidated$/</span>;

<span class="hljs-built_in">console</span>.log(re.test(testStr)); <span class="hljs-comment">// false</span>
</code></pre>
<p>When you use both the dollar and caret metacharacters with the <code>g</code> and <code>m</code> flags, they don’t just match at the start and end of a line, they find the matches at the start and end of each line:</p>
<pre><code class="lang-js"><span class="hljs-comment">//dollar with g and m flags</span>
<span class="hljs-keyword">const</span> testStr1 = <span class="hljs-string">`The lion is not the king of the jungle because of its strength, the lion is the king of the jungle because it's never intimidated

Another line with intimidated

And another line with intimidated`</span>;

<span class="hljs-keyword">const</span> re1 = <span class="hljs-regexp">/intimidated$/gm</span>;
<span class="hljs-keyword">const</span> matches1 = testStr1.match(re1);

<span class="hljs-built_in">console</span>.log(matches1); <span class="hljs-comment">// [ 'intimidated', 'intimidated', 'intimidated' ]</span>

<span class="hljs-comment">// caret with g and m flags</span>
<span class="hljs-keyword">const</span> testStr = <span class="hljs-string">`freeCodeCamp doesn't charge you any money. That's why it's called freeCodeCamp because. Learn to code for free today.

freeCodeCamp starts this line

freeCodeCamp starts this line too
`</span>;

<span class="hljs-keyword">const</span> re2 = <span class="hljs-regexp">/^freeCodeCamp/gm</span>;
<span class="hljs-keyword">const</span> matches2 = testStr.match(re2);

<span class="hljs-built_in">console</span>.log(matches2); <span class="hljs-comment">// [ 'freeCodeCamp', 'freeCodeCamp', 'freeCodeCamp' ]</span>
</code></pre>
<p>As I pointed out earlier, the caret metacharacter is typically used for negating a character set or any other character. With that, you tell the regex engine in use not to match that character or each of the character sets.</p>
<p>For example, if you have the pattern <code>[^a]</code>, then all letters "a" in the test string won't be returned as matches:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/unmatch-As.png" alt="unmatch-As" width="600" height="400" loading="lazy"></p>
<p>If you have the pattern <code>[^aeiou]</code>, all the vowels in the test string won't be returned as matches:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/unmatch-vowels.png" alt="unmatch-vowels" width="600" height="400" loading="lazy"></p>
<p>If you have the pattern <code>[^a-zA-Z0-9_]</code>, that's equivalent to the non-word metacharacter (<code>\W</code>):</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/non-word-char-class.png" alt="non-word-char-class" width="600" height="400" loading="lazy"></p>
<h3 id="heading-the-digit-and-non-digit-metacharacters">The Digit and Non-digit Metacharacters</h3>
<p>The digit metacharacter is represented by <code>\d</code>. You can negate it with <code>\D</code>, so <code>\D</code> is the non-digit metacharacter.</p>
<p><code>\d</code> matches all numbers (0 to 9), so it is a shorthand character class for <code>[0-9]</code>. So, if you have a string and you want to extract the numbers from it, you can use the <code>\d</code> metacharacter. But you have to use it with the <code>g</code> flag so it matches every number in the test string:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/Screenshot-2023-07-25-at-12.27.21.png" alt="Screenshot-2023-07-25-at-12.27.21" width="600" height="400" loading="lazy"></p>
<p>You can use the <code>match()</code> method to extract the numbers in JavaScript too:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> testStr =
  <span class="hljs-string">'Arabic numerals are 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9. From those ten numbers, you can write any number you want, including nonillion and decillion.'</span>;

<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/\d/g</span>;

<span class="hljs-built_in">console</span>.log(testStr.match(re));

<span class="hljs-comment">/* output
[
  '0', '1', '2', '3',
  '4', '5', '6', '7',
  '8', '9'
]
*/</span>
</code></pre>
<p>A more straightforward example is matching dates since dates are mostly in numbers. For example, if you want to match a date in the format <code>dd/mm/yyyy</code>, you can match it with the pattern <code>/\d\d\/\d\d\/\d\d\d\d/</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> date = <span class="hljs-string">'22/04/2023'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/\d\d\/\d\d\/\d\d\d\d/</span>;

<span class="hljs-built_in">console</span>.log(re.test(date)); <span class="hljs-comment">// true</span>
</code></pre>
<p>Since you can also have a period or hyphen as the separator of a date, you can account for those too by putting all the possible separators in a character set:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> slashSeparatedSate = <span class="hljs-string">'22/04/2023'</span>;
<span class="hljs-keyword">const</span> hyphenSeparatedDate = <span class="hljs-string">'22-04-2023'</span>;
<span class="hljs-keyword">const</span> periodSeparatedDate = <span class="hljs-string">'22.04.2023'</span>;

<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/\d\d[/.-]\d\d[/.-]\d\d\d\d/</span>;

<span class="hljs-built_in">console</span>.log(re.test(slashSeparatedSate)); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(re.test(hyphenSeparatedDate)); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(re.test(periodSeparatedDate)); <span class="hljs-comment">// true</span>
</code></pre>
<p><strong>N.B.</strong>: The pattern above matches a date but also an invalid date like <code>99/45/2022</code>. A better way to match dates is provided in the applications of the regex chapter.</p>
<p>Another example is matching phone numbers. For example, US phone numbers are in the format <code>(123) 456-7890</code>. You can use the pattern <code>/\(\d\d\d\) \d\d\d-\d\d\d\d/</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> USPhone = <span class="hljs-string">'(123) 456-7890'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/\(\d\d\d\) \d\d\d-\d\d\d\d/</span>;

<span class="hljs-built_in">console</span>.log(re.test(USPhone)); <span class="hljs-comment">// true</span>
</code></pre>
<p>The non-digit metacharacter is the opposite of the digit metacharacter. It matches all non-digit characters. That is, alphabets, spaces, and symbols. In other words, it is the shorthand character class for <code>[^0-9]</code>.</p>
<p>If you want to extract all non-digit characters in a string, you can use the <code>\D</code> metacharacter:
<img src="https://www.freecodecamp.org/news/content/images/2023/07/D-matches.png" alt="D-matches" width="600" height="400" loading="lazy"></p>
<p>This is it in JavaScript code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> testStr =
  <span class="hljs-string">'Arabic numerals are 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9. From those ten numbers, you can write any number you want, including nonillion and decillion.'</span>;

<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/\D/g</span>;

<span class="hljs-built_in">console</span>.log(testStr.match(re));

<span class="hljs-comment">/* output
A total of 137 matches is too much to show here, but you can test it out yourself.
*/</span>
</code></pre>
<h3 id="heading-the-square-brackets-metacharacter">The Square Brackets Metacharacter</h3>
<p>You've already seen the square brackets (<code>[]</code>) metacharacter in action. Square brackets are used for specifying a character class, or character set. And if you want to match them as a literal character, then you have to escape them.</p>
<p>One thing to have in mind is that some metacharacters lose their meanings inside the character set. The exceptions to this are:</p>
<ul>
<li>The caret (<code>^</code>) which you can use to negate a character set</li>
<li>The hyphen (<code>-</code>) which you can use to specify ranges</li>
</ul>
<p><strong>N.B.</strong>: Sometimes, you might encounter a situation where you have to escape some metacharacters inside a character set.</p>
<p>If you want to match any of those characters in a character set, you have to escape it. If you are just passing the three of those characters in directly, you don't need to escape them if the caret is not the first character.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> testStr =
  <span class="hljs-string">'If you want to match the caret (^), hyphen and (-) symbols in a character set, you might not have to escape them.'</span>;

<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/[-^]/g</span>;

<span class="hljs-built_in">console</span>.log(testStr.match(re)); <span class="hljs-comment">// [ '^', '-' ]</span>
</code></pre>
<p>But if the caret is the first character in the character set alongside some word and non-word character, you should escape it, otherwise it will negate all other characters:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/unescaped-caret.png" alt="unescaped-caret" width="600" height="400" loading="lazy"></p>
<h3 id="heading-the-word-boundary-and-non-word-boundary-metacharacters">The Word Boundary and Non-word Boundary Metacharacters</h3>
<p>The word boundary metacharacter is represented by <code>\b</code> and the non-word boundary metacharacter is represented by <code>\B</code>. Both let you match a specific part of a string where a word character and a non-word character exist.</p>
<p>Word boundary (<code>\b</code>) matches a position between a word character (<code>\w</code>) and a non-word character (<code>\W</code>), and vice versa. It can be useful when you want to match a certain word in a string, or if you want to make sure a particular word or character is in a string.</p>
<p>Here's an example in a regex tester:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/b-match.png" alt="b-match" width="600" height="400" loading="lazy"></p>
<p>And the same example in JavaScript code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr =
  <span class="hljs-string">'A Tiger can do everything a lion does, apart from being a family man.'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/\blion\b/</span>;

<span class="hljs-built_in">console</span>.log(myStr.match(re));

<span class="hljs-comment">/*
Output:
[
  'lion',
  index: 28,
  input: 'A Tiger can do everything a lion does, apart from being a family man.',
  groups: undefined
]
*/</span>
</code></pre>
<p>If you use a <code>g</code> flag with the pattern and use the <code>match()</code> method, all the matches will be returned – as expected:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr =
  <span class="hljs-string">'A Tiger can do everything a lion does, apart from being a family man. Not even a tiger can intimidate a lion within his family.'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/\blion\b/g</span>;

<span class="hljs-built_in">console</span>.log(myStr.match(re)); <span class="hljs-comment">// [ 'lion', 'lion' ]</span>
</code></pre>
<p>On the other hand, the non-word boundary (<code>\B</code>) is the opposite of the word boundary (<code>\b</code>). So, it matches everywhere a word boundary won't return a match. For example, "thin" in "everything":</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/thing-everything.png" alt="thing-everything" width="600" height="400" loading="lazy"></p>
<p>And also "code" in "freeCodeCamp" when you use the case insensitive (<code>i</code>) flag:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/code-freeCodeCamp.png" alt="code-freeCodeCamp" width="600" height="400" loading="lazy"></p>
<p>You can see that the first "code" in the text wasn't the match returned. That's the power of word and non-word boundary metacharacters.</p>
<p>Here's what the two reveal in JavaScript code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr1 =
  <span class="hljs-string">'A Tiger can do everything a lion does, apart from being a family man.'</span>;
<span class="hljs-keyword">const</span> myStr2 = <span class="hljs-string">'Learn to code for free on freeCodeCamp.'</span>;

<span class="hljs-keyword">const</span> re1 = <span class="hljs-regexp">/\Bthin\B/</span>;
<span class="hljs-keyword">const</span> re2 = <span class="hljs-regexp">/\Bcode\B/i</span>;

<span class="hljs-built_in">console</span>.log(myStr1.match(re1));
<span class="hljs-built_in">console</span>.log(myStr2.match(re2));

<span class="hljs-comment">/*
Output:
[
  'thin',
  index: 20,
  input: 'A Tiger can do everything a lion does, apart from being a family man.',
  groups: undefined
]
[
  'Code',
  index: 30,
  input: 'Learn to code for free on freeCodeCamp.',
  groups: undefined
]
*/</span>
</code></pre>
<h3 id="heading-the-parenthesis-metacharacter">The Parenthesis Metacharacter</h3>
<p>The parenthesis metacharacters (<code>(</code> and <code>)</code>) let you create grouping and capturing. With them, you can treat any group of characters as a single unit and apply a common modifier or quantifier to them. </p>
<p>Parenthesis is also used for creating both lookahead and lookbehind assertions.</p>
<p>When you create the group and assertions, you can reference them later in the same pattern with a backslash and the order in which they appear. For example, you can reference the first group by specifying <code>\1</code> in the pattern.</p>
<p>In this book, a whole chapter is dedicated to grouping and capturing. There, you will learn more about grouping and capturing so you can see the parenthesis metacharacters in action.</p>
<h3 id="heading-the-space-and-non-space-metacharacters">The Space and Non-space Metacharacters</h3>
<p>It is impossible for text to make sense without spaces. Not just a "space", but also other space characters like tabs, carriage returns, and new lines. This is why the space and non-space metacharacters are made available in regular expressions.</p>
<p>The space metacharacter is represented by <code>\s</code> and the non-space metacharacter is represented by <code>\S</code>.</p>
<p><code>\s</code> matches all space characters:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/s-match.png" alt="s-match" width="600" height="400" loading="lazy"></p>
<p>And <code>\S</code> matches all non-space metacharacters:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/S-matches.png" alt="S-matches" width="600" height="400" loading="lazy"></p>
<p>Here's how both the <code>\s</code> and <code>\S</code> metacharacters work in JavaScript code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr = <span class="hljs-string">'Learn to code for free on freeCodeCamp'</span>;
<span class="hljs-keyword">const</span> spaceRe = <span class="hljs-regexp">/\s/g</span>;
<span class="hljs-keyword">const</span> nonSpaceRe = <span class="hljs-regexp">/\S/g</span>;

<span class="hljs-built_in">console</span>.log(myStr.match(spaceRe)); <span class="hljs-comment">// [' ', ' ', ' ', ' ', ' ', ' '];</span>

<span class="hljs-built_in">console</span>.log(myStr.match(nonSpaceRe)); 
<span class="hljs-comment">// [</span>
<span class="hljs-comment">// 'L', 'e', 'a', 'r', 'n', 't',</span>
<span class="hljs-comment">// 'o', 'c', 'o', 'd', 'e', 'f',</span>
<span class="hljs-comment">// 'o', 'r', 'f', 'r', 'e', 'e',</span>
<span class="hljs-comment">// 'o', 'n', 'f', 'r', 'e', 'e',</span>
<span class="hljs-comment">// 'C', 'o', 'd', 'e', 'C', 'a',</span>
<span class="hljs-comment">// 'm', 'p'</span>
<span class="hljs-comment">// ]</span>
</code></pre>
<p>One cool thing you can do with <code>\s</code> in JavaScript is to replace all spaces with say, a hyphen, or any other thing you want:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr = <span class="hljs-string">'Learn to code for free on freeCodeCamp'</span>;
<span class="hljs-keyword">const</span> replaceHyphen = myStr.replace(spaceRe, <span class="hljs-string">'-'</span>);

<span class="hljs-built_in">console</span>.log(replaceHyphen); <span class="hljs-comment">// Learn-to-code-for-free-on-freeCodeCamp</span>
</code></pre>
<p>The space metacharacter does not just match the spacebar you press on the keyboard of your device. It also matches:</p>
<ul>
<li>A tab character</li>
<li>A carriage return character</li>
<li>A new line character</li>
<li>A vertical tab character</li>
<li>And a form feed character</li>
</ul>
<p>Here's an example:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/s-match-all.png" alt="s-match-all" width="600" height="400" loading="lazy"></p>
<p>You can't see the match for the carriage return but it's there:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/s-match-all-view-1.png" alt="s-match-all-view-1" width="600" height="400" loading="lazy"></p>
<p>If you want to match each of those space characters, they also have their unique metacharacters:</p>
<ul>
<li><code>\t</code> for tab</li>
<li><code>\r</code> for carriage return</li>
<li><code>\n</code> for new line</li>
<li><code>\v</code> for vertical tab</li>
<li><code>\f</code> for form feed.</li>
</ul>
<p>You should be aware that most of the time, <code>\s</code> is all you need because it can do the matching for any space character.</p>
<h3 id="heading-the-pipe-metacharacter">The Pipe Metacharacter</h3>
<p>Also known as the <code>OR</code> operator, the pipe metacharacter is represented by the pipe symbol (<code>|</code>). It lets you specify multiple alternatives for matching. </p>
<p>The pipe matches the character preceding it, or the character that follows it. For example, if you have <code>website|web\sapp</code> as your pattern, then one or both of <code>website</code> and <code>web app</code> will be returned as the match:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/web-webapp-alt.png" alt="web-webapp-alt" width="600" height="400" loading="lazy"></p>
<p>The evaluation goes from left to right. If a match is found on the left, it returns the match. And if there's no match on the left, the character on the right-hand side is evaluated for a possible match. If both characters on the left and right are in the test string, then both are returned as matches.</p>
<p>You can also have more than two characters separated by the pipe symbols. For instance, the pattern <code>/o|a|i|re/</code> would match <code>o</code>, <code>a</code>, <code>i</code>, and <code>re</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/a-o-i-alt-match.png" alt="a-o-i-alt-match" width="600" height="400" loading="lazy"></p>
<p>There's no limit to the characters you can separate with it.</p>
<p>You can see I used the <code>g</code> flag in those examples. If you don’t use the <code>g</code> flag and both the left and right characters are matches, only the first match in the test string will be returned:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/first-occur-i-o-a.png" alt="first-occur-i-o-a" width="600" height="400" loading="lazy"></p>
<p>Here's a clearer example:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/clearer-alt.png" alt="clearer-alt" width="600" height="400" loading="lazy"></p>
<p>Here's how using the <code>OR</code> operator works with the <code>g</code> flag in code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr = <span class="hljs-string">'The website and web app are running fine'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/website|web\sapp/g</span>;

<span class="hljs-built_in">console</span>.log(myStr.match(re)); <span class="hljs-comment">// returns [ 'website', 'web app' ] because of the g flag</span>
</code></pre>
<p>And here's how it works without the <code>g</code> flag:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr = <span class="hljs-string">'The website and web app are running fine'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/website|web\sapp/</span>;

<span class="hljs-keyword">const</span> matches = myStr.match(re);

<span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> match <span class="hljs-keyword">of</span> matches) {
  <span class="hljs-built_in">console</span>.log(match); <span class="hljs-comment">// returns "website" and ignores web app because there's no g flag</span>
}
</code></pre>
<h3 id="heading-how-to-match-repeated-characters-with-quantifiers">How to Match Repeated Characters With Quantifiers</h3>
<p>Repeated characters occur when the same character exists in multiple numbers consecutively.</p>
<p>When you have a repeated character in your test string, you don't need to repeat a particular character in your pattern to match it. That's because there are metacharacters available for <strong>one or more matches</strong>, <strong>zero or more matches</strong>, and <strong>zero or one matches</strong>, AKA <strong>optional matches</strong>.</p>
<h4 id="heading-one-or-more-matches-with-the-addition-sign-metacharacter">One or More Matches with the Addition Sign Metacharacter</h4>
<p>As you can guess, the addition sign metacharacter is represented with a plus (<code>+</code>). You can also call it the "one or more quantifier".</p>
<p>If you want a particular character to be repeated one or many times, that's what the addition sign metacharacter does. </p>
<p>For example, the pattern, <code>/fe+d/</code> will match any word with one letter <code>e</code> or multiple letters <code>e</code> that occur consecutively. For instance, <code>fed</code> and <code>feed</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/one-or-more-e.png" alt="one-or-more-e" width="600" height="400" loading="lazy"></p>
<p>A practical example in JavaScript is extracting vowels in a test string while limiting occurrences by making sure multiple vowels that follow one another are also returned:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr = <span class="hljs-string">'You should plant trees to save mother earth'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/[aeiou]+/gi</span>;

<span class="hljs-built_in">console</span>.log(myStr.match(re));

<span class="hljs-comment">/*
Output:
[
  'ou', 'ou', 'a',
  'ee', 'o',  'a',
  'e',  'o',  'e',
  'ea'
]
*/</span>
</code></pre>
<p>You can also append the addition sign metacharacter to other metacharacters. For example, /\d+/ would match one or more digits:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/d--matches.png" alt="d--matches" width="600" height="400" loading="lazy"></p>
<p>You can also add the <code>+</code> metacharacter to a character set to repeat it one or more times. In the screenshot below, the pattern <code>/f[a-z]+/</code> would match one or more letter <code>f</code> followed by any set of small letters:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/f-set-zero-or-more.png" alt="f-set-zero-or-more" width="600" height="400" loading="lazy"></p>
<h4 id="heading-zero-or-more-matches-with-the-asterisk-metacharacter">Zero or More Matches with the Asterisk Metacharacter</h4>
<p>The asterisk metacharacter (<code>*</code>) matches zero or many occurrences of the character it comes after. You can also call it a "zero or more quantifier". </p>
<p>So, if you want a character to be repeated zero or more than one time, you can use the asterisk metacharacter. A basic example is using the pattern <code>/go*d/</code> would match any word that starts with the letter <code>g</code> followed by any number of the letter <code>o</code>, and ending with the letter <code>d</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/gd-zero-or-more.png" alt="gd-zero-or-more" width="600" height="400" loading="lazy"></p>
<p>Just like you can do with the plus metacharacter, you can also append the asterisk metacharacter to any other metacharacter. For example, you can match empty strings with the pattern <code>/\s*/</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/match-empty-string.png" alt="match-empty-string" width="600" height="400" loading="lazy"></p>
<p>Doubting that? Here it is in JavaScript code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/\s*/</span>;
<span class="hljs-keyword">const</span> emptyString = <span class="hljs-string">''</span>;

<span class="hljs-built_in">console</span>.log(re.test(emptyString)); <span class="hljs-comment">// true</span>
</code></pre>
<p>I didn’t know matching empty strings was as straightforward as this until I got to this point in the book!</p>
<p>Again, like the plus metacharacter, you can also add the <code>*</code> metacharacter to a character set to repeat it zero or more times:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/f-set-one-or-more.png" alt="f-set-one-or-more" width="600" height="400" loading="lazy"></p>
<p>Here's the same thing in JavaScript code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr = <span class="hljs-string">'You can make yourself free from diseases'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/f[a-z]*/g</span>;

<span class="hljs-built_in">console</span>.log(myStr.match(re)); <span class="hljs-comment">// [ 'f', 'free', 'from' ]</span>
</code></pre>
<p>You can see the <code>f</code> in the word <code>yourself</code> is even a match too. That's one way to deduce that the asterisk (<code>*</code>) returns more matches than the addition sign (<code>+</code>) metacharacter because it is greedier. You will learn about greediness of a regular expression in the closing part of this chapter.</p>
<h4 id="heading-zero-or-one-matches-with-the-question-mark-metacharacter">Zero or One Matches with the Question Mark Metacharacter</h4>
<p>The question mark metacharacter (<code>?</code>) is also known as the zero or one quantifier. It lets you make the character that precedes it optional, so it plays an important role in preventing greediness.</p>
<p>For example, the pattern <code>/ab?c/</code> will match <code>abc</code> and <code>ac</code>, but never <code>abbbc</code> or any other numbers of <code>b</code> between the <code>a</code> and <code>c</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/abc-optional.png" alt="abc-optional" width="600" height="400" loading="lazy"></p>
<p>This is not the case with the other two metacharacters for matching repeated characters (<code>+</code> and <code>*</code>). The pattern <code>/ab*c/</code> will match all of  <code>abc</code>, <code>ac</code>, <code>abbbc</code>, and <code>abbbbbbbc</code> while <code>/ab+c/</code> will leave out <code>ac</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr = <span class="hljs-string">'abc ac abbbc abbbbbbbc'</span>;
<span class="hljs-keyword">const</span> re1 = <span class="hljs-regexp">/ab*c/g</span>;
<span class="hljs-keyword">const</span> re2 = <span class="hljs-regexp">/ab+c/g</span>;
<span class="hljs-keyword">const</span> re3 = <span class="hljs-regexp">/ab?c/g</span>;

<span class="hljs-built_in">console</span>.log(myStr.match(re1)); <span class="hljs-comment">// [ 'abc', 'ac', 'abbbc', 'abbbbbbbc' ]</span>
<span class="hljs-built_in">console</span>.log(myStr.match(re2)); <span class="hljs-comment">// [ 'abc', 'abbbc', 'abbbbbbbc' ]</span>
<span class="hljs-built_in">console</span>.log(myStr.match(re3)); <span class="hljs-comment">// [ 'abc', 'ac' ]</span>
</code></pre>
<p>A better example is tailoring a regex pattern to match words that have different spellings due to the small variations in British and American English. For example, <code>color</code> and <code>colour</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/colou-r-optional.png" alt="colou-r-optional" width="600" height="400" loading="lazy"></p>
<p>There's also <code>centre</code> and <code>center</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/cente-re--optional.png" alt="cente-re--optional" width="600" height="400" loading="lazy"></p>
<p>You can extract those words in JavaScript. You can't use the <code>match()</code> method for that because it causes some unexpected behaviors when used with the <code>?</code> metacharacter.</p>
<p>Here's how I was able to do it for <code>color</code> and <code>colour</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr = <span class="hljs-string">'The words center and centre are homophones'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/cente?re?/g</span>;

<span class="hljs-keyword">let</span> match;
<span class="hljs-keyword">const</span> matches = [];

<span class="hljs-keyword">while</span> ((match = re.exec(myStr)) !== <span class="hljs-literal">null</span>) {
  matches.push(match[<span class="hljs-number">0</span>]);
}

<span class="hljs-built_in">console</span>.log(matches); <span class="hljs-comment">// ["center", "centre"]</span>
</code></pre>
<p>I used the same approach to extract <code>center</code> and <code>centre</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr =
  <span class="hljs-string">'It is "colour" in British English and "color" in American English'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/colou?r/g</span>;

<span class="hljs-keyword">let</span> match;
<span class="hljs-keyword">const</span> matches = [];

<span class="hljs-keyword">while</span> ((match = re.exec(myStr)) !== <span class="hljs-literal">null</span>) {
  matches.push(match[<span class="hljs-number">0</span>]);
}

<span class="hljs-built_in">console</span>.log(matches); <span class="hljs-comment">// [ 'colour', 'color' ]</span>
</code></pre>
<p>Many times, it's challenging knowing which to use for character repetition between these three metacharacters – <code>*</code>, <code>+</code>, and <code>?</code>. It can even be hard to get used to what each of them does if you're just starting out with regular expressions.</p>
<p>Be aware that identifying them and knowing which to use between them is not a herculean task. Here are some things to note about the three of them:</p>
<ul>
<li>Asterisk (<code>*</code>) means "zero or many": use it if you want a character not to appear in the target string or you want the same character to be more than one</li>
<li>Plus (<code>+</code>) means "one or many": use it if you want a character to appear once or more than once in the target string</li>
<li>Question mark (<code>?</code>) means "zero or one": use it if you want a character to be optional in the target string.</li>
</ul>
<h3 id="heading-how-to-specify-match-quantity-with-the-curly-braces-metacharacter">How to Specify Match Quantity with the Curly Braces Metacharacter</h3>
<p>Quantifiers let you indicate the quantity or frequency of a preceding character in a pattern with curly braces (<code>{}</code>}. With those braces, you can specify an exact quantifier, a minimum quantifier, and a range quantifier.</p>
<h4 id="heading-the-range-quantifier">The Range Quantifier</h4>
<p>The general syntax for the range quantifier looks like this:</p>
<pre><code class="lang-console">char{n1,n2}
</code></pre>
<ul>
<li><code>cha</code> is any character you're applying the quantifier to</li>
<li><code>n1</code> is the minimum number of times you want the character to repeat</li>
<li><code>n2</code> is the maximum number of times you want the character to repeat</li>
</ul>
<p>An example is the pattern <code>/a{3,6}/</code>. This means you want to match between three and six letters <code>a</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/a-3-6--match.png" alt="a-3-6--match" width="600" height="400" loading="lazy"></p>
<p>If you have more than six letters <code>a</code> in the test string, the first six will match:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/a-range-error.png" alt="a-range-error" width="600" height="400" loading="lazy"></p>
<p>To fix this, you can surround the pattern in a word boundary:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/a-range-error-fix.png" alt="a-range-error-fix" width="600" height="400" loading="lazy"></p>
<p>You can also attach the range quantifier to metacharacters. For example, you can extract any number that is at least in hundreds this way:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr =
  <span class="hljs-string">'The marathon had 500 participants, with 251 finishing under 3 hours, and the winner crossed the line at 4800 seconds.'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/\b\d{3,6}\b/g</span>;

<span class="hljs-built_in">console</span>.log(myStr.match(re)); <span class="hljs-comment">// [ '500', '251', '4800' ]</span>
</code></pre>
<h4 id="heading-the-minimum-quantifier">The Minimum Quantifier</h4>
<p>The minimum quantifier lets you specify the minimum number of times you want the character that precedes it to match. You can do this by putting a comma right after the number in the curly brace. The general syntax looks like this: <code>{n,}</code>. </p>
<p>For example, the pattern <code>/a{3,}/</code> means you want a minimum of three letters <code>a</code>. In this case, one letter <code>a</code> and two letters <code>a</code> won't be a match, but three letters <code>a</code> and upward would be returned as matches:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/a-3---match.png" alt="a-3---match" width="600" height="400" loading="lazy"></p>
<p>Let's extract those matches with the <code>match()</code> method:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr =
  <span class="hljs-string">'"a" won\'t match here. "aa" won\'t match too, but "aaa" is a match, "aaaa" is also a match, and every other number of "a"'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/a{3,}/g</span>;

<span class="hljs-built_in">console</span>.log(myStr.match(re)); <span class="hljs-comment">// [ 'aaa', 'aaaa' ]</span>
</code></pre>
<h4 id="heading-the-exact-quantifier">The Exact Quantifier</h4>
<p>The exact specifier is represented by <code>{n}</code>. In this case, <code>n</code> stands for the exact number of times you want that character to be repeated. For instance, the pattern, <code>/a{3}/</code> means you want <code>a</code> to be repeated three times</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/exact-a-3-.png" alt="exact-a-3-" width="600" height="400" loading="lazy"></p>
<p>Unfortunately, a match is returned anywhere there are three letters <code>a</code> that follow one another. You can prevent this behavior with word boundary (<code>\b</code>):</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/exact-a-3--fixed-.png" alt="exact-a-3--fixed-" width="600" height="400" loading="lazy"></p>
<p>That way, you can extract the abbreviations, <code>AAA</code> from a string using the <code>match()</code> method. Below is an example: </p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr =
  <span class="hljs-string">"There is American automobile association (AAA)and there is Australian automobile association (AAA). What I've never seen is AAAA or AAAAAA."</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/\ba{3}\b/gi</span>;

<span class="hljs-built_in">console</span>.log(myStr.match(re)); <span class="hljs-comment">// [ 'AAA', 'AAA' ]</span>
</code></pre>
<p>Remember the pattern I wrote to match dates in the <code>dd/mm/yyyy</code> format? You can make it better and easier to read with the exact quantifier like this:</p>
<pre><code class="lang-console">\d{2}[/.-]\d{2}[/.-]\d{4}
</code></pre>
<p>Everything still works fine:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> slashSeparatedSate = <span class="hljs-string">'22/04/2023'</span>;
<span class="hljs-keyword">const</span> hyphenSeparatedDate = <span class="hljs-string">'22-04-2023'</span>;
<span class="hljs-keyword">const</span> periodSeparatedDate = <span class="hljs-string">'22.04.2023'</span>;

<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/\d{2}[/.-]\d{2}[/.-]\d{4}/</span>;

<span class="hljs-built_in">console</span>.log(re.test(slashSeparatedSate)); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(re.test(hyphenSeparatedDate)); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(re.test(periodSeparatedDate)); <span class="hljs-comment">// true</span>
</code></pre>
<p>You can also make the pattern that matches the US phone number better and shorter with the same approach:</p>
<pre><code class="lang-console">\(\d{3}\) \d{3}-\d{4}
</code></pre>
<p>Everything still works fine too:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> USPhone = <span class="hljs-string">'(123) 456-7890'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/\(\d{3}\) \d{3}-\d{4}/</span>;

<span class="hljs-built_in">console</span>.log(re.test(USPhone)); <span class="hljs-comment">// true</span>
</code></pre>
<h3 id="heading-the-wildcard-metacharacter">The Wildcard Metacharacter</h3>
<p>The wildcard metacharacter is represented by a dot (<code>.</code>), so you can also call it the dot metacharacter. </p>
<p>The wildcard lets you match any character apart from a new line (<code>\n</code>). That means you can use it to match alphanumeric characters, spaces, and symbols.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/wcard-match.png" alt="wcard-match" width="600" height="400" loading="lazy"></p>
<p>You can also attach the wildcard metacharacter to another metacharacter. For example, the pattern <code>/\d./g</code> should match at least a number and everything that follows it:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/digit-greedy.png" alt="digit-greedy" width="600" height="400" loading="lazy"></p>
<p>You can see that the pattern is transcending beyond the digits by matching the spaces after them. This is what is called <strong>greediness</strong>.</p>
<p>The pattern, <code>/\d.*/g</code> is even more greedy because it will match everything after it encounters the first number:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/super-digit-greedy.png" alt="super-digit-greedy" width="600" height="400" loading="lazy"></p>
<p>It’s the same in code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr =
  <span class="hljs-string">'An example of a two-digit number is 20. 100 is a three-digit number. 300 and 900 are also three-digit numbers.'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/\d.*/g</span>;

<span class="hljs-built_in">console</span>.log(myStr.match(re)); <span class="hljs-comment">// [ '20. 100 is a three-digit number. 300 and 900 are also three-digit numbers.']</span>
</code></pre>
<p>If you want the wildcard to match a new line too, you can use the <code>s</code> flag. Here's an example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> codeBlock = <span class="hljs-string">`
  function add(x, y) {
    /* This is a function
    that takes two numbers
    and adds them together. */
    return x + y;
  }
`</span>;

<span class="hljs-keyword">let</span> commentRegex = <span class="hljs-regexp">/\/\*(.*)\*\//</span>s; <span class="hljs-comment">// gets everything between /* and */</span>

<span class="hljs-keyword">const</span> match = codeBlock.match(commentRegex);
<span class="hljs-built_in">console</span>.log(match);
</code></pre>
<p>Here's the result:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/dotAllRes-1.png" alt="dotAllRes-1" width="600" height="400" loading="lazy"></p>
<p>You can use the <code>dotAll</code> property to check if the <code>s</code> flag is used in the pattern:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> codeBlock = <span class="hljs-string">`
  function add(x, y) {
    /* This is a function
    that takes two numbers
    and adds them together. */
    return x + y;
  }
`</span>;

<span class="hljs-keyword">let</span> commentRegex = <span class="hljs-regexp">/\/\*(.*)\*\//</span>s; <span class="hljs-comment">// gets everything between /* and */</span>
<span class="hljs-keyword">const</span> match = codeBlock.match(commentRegex);

<span class="hljs-built_in">console</span>.log(commentRegex.dotAll) <span class="hljs-comment">// true;</span>
</code></pre>
<p>You can extract the match with an if statement:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> codeBlock = <span class="hljs-string">`
  function add(x, y) {
    /* This is a function
    that takes two numbers
    and adds them together. */
    return x + y;
  }
`</span>;

<span class="hljs-keyword">let</span> commentRegex = <span class="hljs-regexp">/\/\*(.*)\*\//</span>s; <span class="hljs-comment">// gets everything between /* and */</span>

<span class="hljs-keyword">const</span> match = codeBlock.match(commentRegex);

<span class="hljs-keyword">if</span> (match) {
  <span class="hljs-built_in">console</span>.log(match[<span class="hljs-number">1</span>]);
}

<span class="hljs-comment">/*
Output:  
This is a function
    that takes two numbers
    and adds them together.
*/</span>
</code></pre>
<p>Because the wildcard always matches any character it encounters apart from a new line, it is better not to use it unless it is absolutely necessary. For every character the wildcard matches, there is always another way to match it.</p>
<h3 id="heading-greediness-and-laziness-in-regular-expressions">Greediness and Laziness in Regular Expressions</h3>
<p>By default, regular expression patterns are greedy, meaning they always try to match as many as possible characters. But the concept of greediness is primarily applicable to quantifiers (<code>*</code>, <code>+</code>, <code>?</code>, and <code>{}</code>) and the wildcard (<code>.</code>).</p>
<p>For Example, the pattern <code>/f.*h/gi</code> will match as many characters as possible after encountering an <code>f</code> in the target string:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/asterisk-greedy.png" alt="asterisk-greedy" width="600" height="400" loading="lazy"></p>
<p>Same for the pattern, <code>/f.*h/gi</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/plus-greedy.png" alt="plus-greedy" width="600" height="400" loading="lazy"></p>
<p>It’s the same in code: </p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr = <span class="hljs-string">'The fresh fish was caught in the Finnish lake'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/f.*h/gi</span>;

<span class="hljs-built_in">console</span>.log(myStr.match(re)); <span class="hljs-comment">// [ 'fresh fish was caught in the Finnish' ]</span>
</code></pre>
<p><strong>Laziness</strong> is the opposite of greediness and it’s the way you stop greediness. On many occasions, if you want to stop greediness, all you need is to apply the <strong>zero or ones quantifier</strong> (<code>?</code>) to the metacharacter causing the greediness.</p>
<p>Here's how I stopped the greediness of the asterisk metacharacter:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/make-asterisk-lazy.png" alt="make-asterisk-lazy" width="600" height="400" loading="lazy"></p>
<p>I stopped it for the plus metacharacter the same way:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/make-plus-lazy.png" alt="make-plus-lazy" width="600" height="400" loading="lazy"></p>
<p>I can now safely extract every word that starts with <code>f</code> and ends with <code>h</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr = <span class="hljs-string">'The fresh fish was caught in the Finnish lake'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/f.*?h/gi</span>;

<span class="hljs-built_in">console</span>.log(myStr.match(re)); <span class="hljs-comment">// [ 'fresh', 'fish', 'Finnish' ]</span>
</code></pre>
<h2 id="heading-chapter-6-grouping-and-capturing-in-regex">Chapter 6: Grouping and Capturing in Regex</h2>
<h3 id="heading-what-is-grouping">What is Grouping?</h3>
<p>Grouping means treating a regex pattern or a part of a regex pattern as a single unit. To achieve grouping, you surround the pattern or the part of the pattern you want to group in parenthesis (<code>(</code> and <code>)</code>).</p>
<p>After you've grouped the part of the pattern you want to, you can then refer back to it through a process we call "backreferencing" in regular expressions.</p>
<p>The groups you define in a pattern refer to the target string or text and not the pattern itself. You'll see this in action when it's time to discuss backreferencing. </p>
<p>After grouping, you can then apply a quantifier to that group since all the patterns in it are a unit.</p>
<p>Let's say you have a group of the ids <code>z8g4g4 ga1v4g f4k7f9 bb3b2b d6b4t5 d4cm3d e9f5y6 ggj64 mgtyqg m0foh9</code> and you want to find out which of them follow the pattern <code>letter number letter number letter number</code>. The pattern <code>[a-z]\d[a-z]\d[a-z]\d</code> can do that for you:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/without-grouping.png" alt="without-grouping" width="600" height="400" loading="lazy"></p>
<p>Using grouping, you can make the pattern shorter by grouping the <code>[a-z]\d</code> sequence and applying an exact quantifier of <code>3</code> to it:</p>
<pre><code class="lang-console">([a-z]\d){3}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/with-grouping.png" alt="with-grouping" width="600" height="400" loading="lazy"></p>
<p>When you use grouping in a pattern, especially if you have multiple groups in the same pattern, you can use the <code>exec()</code> method to extract each of the groups.</p>
<p>A good example to illustrate this is a date in any acceptable format, for example <code>dd/mm/yyyy</code>.</p>
<p>Here's how I group the pattern <code>\d\d[/.-]\d\d[/.-]\d\d\d\d</code> into <code>dd</code>, <code>mm</code>, and <code>yyyy</code>:</p>
<pre><code class="lang-console">(\d\d)[/.-](\d\d)[/.-](\d\d\d\d)
</code></pre>
<p>I used the <code>exec()</code> method this way:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/(\d\d)[/.-](\d\d)[/.-](\d\d\d\d)/</span>;
<span class="hljs-keyword">const</span> date = <span class="hljs-string">'22-03-2023'</span>;

<span class="hljs-keyword">const</span> execRes = re.exec(date);
<span class="hljs-built_in">console</span>.log(execRes);
</code></pre>
<p>This is what the result looks like in the console:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/exec-group-res.png" alt="exec-group-res" width="600" height="400" loading="lazy"></p>
<p>In the array, you can see that:</p>
<ul>
<li>there is the whole date in the index <code>0</code></li>
<li>the index <code>1</code> has the <code>day</code></li>
<li>the index <code>2</code> has the month`</li>
<li>and the index <code>3</code> has the <code>year</code></li>
</ul>
<p>You can then use array referencing to get all of those figures:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/(\d\d)[/.-](\d\d)[/.-](\d\d\d\d)/</span>;
<span class="hljs-keyword">const</span> date = <span class="hljs-string">'22-03-2023'</span>;

<span class="hljs-keyword">const</span> execRes = re.exec(date);

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The full date is <span class="hljs-subst">${execRes[<span class="hljs-number">0</span>]}</span>`</span>); <span class="hljs-comment">// The full date is 22-03-2023</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The day is <span class="hljs-subst">${execRes[<span class="hljs-number">1</span>]}</span>`</span>); <span class="hljs-comment">// The day is 22</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The month is <span class="hljs-subst">${execRes[<span class="hljs-number">2</span>]}</span>`</span>); <span class="hljs-comment">// The month is 03</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The year is <span class="hljs-subst">${execRes[<span class="hljs-number">3</span>]}</span>`</span>); <span class="hljs-comment">// The year is 2023</span>
</code></pre>
<p>You can also use this approach to extract a username and domain from an email:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">extractUsernameAndDomain</span>(<span class="hljs-params">email</span>) </span>{
  <span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/([a-z]{2,})@([a-z]{3,}\.com)/</span>;
  <span class="hljs-keyword">const</span> result = re.exec(email);

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The username is <span class="hljs-subst">${result[<span class="hljs-number">1</span>]}</span>`</span>);
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The domain is <span class="hljs-subst">${result[<span class="hljs-number">2</span>]}</span>`</span>);
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The full email is <span class="hljs-subst">${result[<span class="hljs-number">0</span>]}</span>`</span>);
}

extractUsernameAndDomain(<span class="hljs-string">'janedoe@gmail.com'</span>);

<span class="hljs-comment">/*
Output:
The username is janedoe
The domain is gmail.com
The full email is janedoe@gmail.com
*/</span>
</code></pre>
<p>This behavior of grouping in which each match of the pattern is separated in an array according to the groups is the reason groups are also called "capturing" groups. This way, you don’t need the <code>split()</code> method of JavaScript or any other programming hacks to get each of the groups on those dates.</p>
<h3 id="heading-how-to-reference-captured-groups-with-backreferences">How to Reference Captured Groups with Backreferences</h3>
<p>Since groups are captured by default, you can refer back to them. To do this, you use a backslash (<code>\</code>) and then the order of the group in the pattern. For example, you can reference the first group with <code>\1</code> and the third group with <code>\3</code>. No zero indentation.</p>
<p>Let's say you want to match "tsetse" fly in the text <code>There are many tsetse flies in the tropics</code>. If you group the text "tse" first and use the <code>g</code> flag, you'll get two matches:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/tse-group-warn.png" alt="tse-group-warn" width="600" height="400" loading="lazy"></p>
<p>You can refer back to that <code>tse</code> group with <code>\1</code> and you'll have a single match: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/tse-group-right.png" alt="tse-group-right" width="600" height="400" loading="lazy"></p>
<p>It's very important to note that when you use a capturing group, the grouping refers to the target string (or text) and not the pattern itself. The reason why the pattern <code>/(tse)\1/</code> returns a match in the last example is because of the "tse" in the text and not the "tse" in the pattern.</p>
<p>To illustrate this, let's use a date again, since the month or date and the separators can repeat and can be different. I will use the pattern <code>(\d\d)([/.-])\1\2(\d\d\d\d)</code> for matching dates that I grouped in one of the previous examples. Remember the pattern successfully matches a date:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/date-match-group.png" alt="date-match-group" width="600" height="400" loading="lazy"></p>
<p>I can group the separator too and refer back to it for the second separator. I can also refer back to the day part of the date to match the month, since they both look for two digits. </p>
<p>Here's the new pattern now:</p>
<pre><code class="lang-console">(\d\d)([/.-])\1\2(\d\d\d\d)
</code></pre>
<p>I can make the pattern shorter with an exact quantifier:</p>
<pre><code class="lang-console">(\d{2})([/.-])\1\2(\d{4})
</code></pre>
<p>The new pattern successfully matches the same date:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/date-match-group-same.png" alt="date-match-group-same" width="600" height="400" loading="lazy"></p>
<p>But the reason there's a match in the example above is that the separators are the same and the day and month are the same.</p>
<p>If the day is different from the month, there won't be a match:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/no-match-because-of-day-month-difference.png" alt="no-match-because-of-day-month-difference" width="600" height="400" loading="lazy"></p>
<p>If the separators are different too, there also won't be a match:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/no-match-because-of-separator-difference.png" alt="no-match-because-of-separator-difference" width="600" height="400" loading="lazy"></p>
<p>But remember that if both are the same, there will be a match:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/date-match-group-same-1.png" alt="date-match-group-same-1" width="600" height="400" loading="lazy"></p>
<p>That is the reason why the groups in a pattern refer to the target string (or text) and not the pattern itself. </p>
<p>It is also possible to make a group non-capturing. That way, you won't be able to refer to it in the pattern. To create a <strong>non-capturing</strong> group, you use a question mark and a colon right after the opening parenthesis.</p>
<p>The syntax for that looks like this:</p>
<pre><code class="lang-console">(?: chars)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/no-match-non-capture.png" alt="no-match-non-capture" width="600" height="400" loading="lazy"></p>
<p>Because of this, the text does not match the pattern anymore. To make it match again I have to:</p>
<ul>
<li>remove the first backreference (<code>\1</code>)</li>
<li>define <code>\d{2}</code> for the date</li>
<li>change the reference to the separator from <code>\2</code> to <code>\1</code></li>
</ul>
<p>Here’s the new pattern:</p>
<pre><code class="lang-console">(?:\d{2})([/.-])\d{2}\1(\d{4})
</code></pre>
<p>And now the date matches the pattern:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/match-non-capture.png" alt="match-non-capture" width="600" height="400" loading="lazy"></p>
<h3 id="heading-how-to-use-the-d-flag-and-hasindices-property-with-groups">How to Use the <code>d</code> Flag and <code>hasIndices</code> Property with Groups</h3>
<p>The <code>d</code> flag adds index information to match objects for capture groups. This way, you won't just know what was matched by each capture group, but also where that match was found in the input string.</p>
<p>Let's look at how this works with the grouping for matching dates:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/(\d\d)[/.-](\d\d)[/.-](\d\d\d\d)/</span>d;
<span class="hljs-keyword">const</span> date = <span class="hljs-string">'22-03-2023'</span>;

<span class="hljs-keyword">const</span> match = re.exec(date);
<span class="hljs-built_in">console</span>.log(match);
</code></pre>
<p>The result contains an array of objects detailing the total position of all matches, and the position of each match:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/dFlagRes.png" alt="dFlagRes" width="600" height="400" loading="lazy"></p>
<p>If you want to see those indices, you can use <code>.indices</code> to see them:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/(\d\d)[/.-](\d\d)[/.-](\d\d\d\d)/</span>d;
<span class="hljs-keyword">const</span> date = <span class="hljs-string">'22-03-2023'</span>;

<span class="hljs-keyword">const</span> match = re.exec(date);

<span class="hljs-built_in">console</span>.log(match.indices);
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/dFlagHasIndicesRes.png" alt="dFlagHasIndicesRes" width="600" height="400" loading="lazy"></p>
<p>You can also extract those indices separately:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/(\d\d)[/.-](\d\d)[/.-](\d\d\d\d)/</span>d;
<span class="hljs-keyword">const</span> date = <span class="hljs-string">'22-03-2023'</span>;

<span class="hljs-keyword">const</span> match = re.exec(date);

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The full index range is <span class="hljs-subst">${match.indices[<span class="hljs-number">0</span>]}</span>`</span>); <span class="hljs-comment">//The full index range is 0,10</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The day index range is <span class="hljs-subst">${match.indices[<span class="hljs-number">1</span>]}</span>`</span>); <span class="hljs-comment">// The day index range is 0,2</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The month index range is <span class="hljs-subst">${match.indices[<span class="hljs-number">2</span>]}</span>`</span>); <span class="hljs-comment">// The month index range is 3,5</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The year index range is <span class="hljs-subst">${match.indices[<span class="hljs-number">3</span>]}</span>`</span>); <span class="hljs-comment">// The year index range is 6,10</span>
</code></pre>
<p>And finally, you can check if the <code>d</code> flag is really used with the <code>hasIndices</code> property:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/(\d\d)[/.-](\d\d)[/.-](\d\d\d\d)/</span>d;
<span class="hljs-keyword">const</span> date = <span class="hljs-string">'22-03-2023'</span>;

<span class="hljs-built_in">console</span>.log(re.hasIndices); <span class="hljs-comment">// true</span>
</code></pre>
<h2 id="heading-chapter-7-lookaround-groups-lookaheads-and-lookbehinds">Chapter 7: Lookaround Groups: Lookaheads and Lookbehinds</h2>
<h3 id="heading-what-are-lookaround-groups">What are Lookaround Groups?</h3>
<p>Lookaround assertions are non-capturing groups that return matches only if the target string is followed or preceded by a particular character. </p>
<p>Lookaround assertions do not consume the characters in the input string or text. This makes them a "zero-width assertion", and that's why lookaround groups are also called "lookahead assertions".</p>
<p>There are two types of lookaround groups: <strong>lookahead</strong> and <strong>lookbehind</strong>. The two also have their positive and negative forms, so there are <strong>positive lookahead</strong>, <strong>negative lookahead</strong>, <strong>positive lookbehind</strong>, and <strong>negative lookbehind</strong> groups.</p>
<h3 id="heading-what-is-a-lookahead-group">What is a Lookahead Group?</h3>
<p>A lookahead group is a non-capturing group that lets you match a part of a string only if it is followed by another character in the string, without including that string or text to match in the pattern.</p>
<p>A lookahead group is useful when you want to match a string based on a condition. So, look at it like an <code>if</code> statement in a programming language.</p>
<p>There are two types of lookaheads, namely <strong>positive lookahead</strong> and <strong>negative lookahead</strong>.</p>
<p>Because you're still dealing with groupings, a positive lookahead is specified by an opening parenthesis followed by a question mark, an equal sign, the characters, and a closing parenthesis:</p>
<pre><code class="lang-console">(?=chars)
</code></pre>
<p>For example, the pattern <code>x(?=y)</code> means match <code>x</code> only if it is followed by <code>y</code>.</p>
<p>In the syntax of negative lookahead, you replace the equal sign with an exclamation mark:</p>
<pre><code class="lang-console">(?!chars)
</code></pre>
<p>For example, the pattern <code>x(?!y)</code> means do not match <code>x</code> if it is followed by <code>y</code>.</p>
<p>Let's look at an example of a positive lookahead assertion.</p>
<p>Say you want to match the domain name of domains that have only the <code>.org</code> extension within a string of domains with other extensions. This pattern would do it:</p>
<pre><code class="lang-console">[a-zA-Z]+(?=\.org)
</code></pre>
<p>In the pattern, <code>[a-zA-Z]+</code> represents one or more word characters, and <code>(?=\.org)</code> checks whether the domain contains a <code>.org</code> extension.</p>
<p>In the screenshot below, you can see that domain names that have a <code>.org</code> extension were matched:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/org-matches.png" alt="org-matches" width="600" height="400" loading="lazy"></p>
<p>You also can see that the words "freeCodeCamp" and "catholic" were not included in the pattern, but they still matched the pattern because they have the <code>.org</code> extension.</p>
<p>If there are no domains with the <code>.org</code> extension in the target string, there won't be any match. That's true for the domains without the <code>.org</code> extension.</p>
<p>That way, you can extract text like that in JavaScript and do whatever you want with it:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> domains = <span class="hljs-string">'koladechris.com freeCodeCamp.org mdn.com catholic.org'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/[a-zA-Z]+(?=\.org)/g</span>;

<span class="hljs-keyword">const</span> charityWebsitesArr = domains.match(re);
<span class="hljs-keyword">const</span> charityWebsites = charityWebsitesArr.join(<span class="hljs-string">','</span>).replace(<span class="hljs-regexp">/,/</span>, <span class="hljs-string">' and '</span>);

<span class="hljs-built_in">console</span>.log(charityWebsites, <span class="hljs-string">'are examples of charity organizations.'</span>); <span class="hljs-comment">//freeCodeCamp and catholic are examples of charity organizations.</span>
</code></pre>
<p>If you want to match the <code>.org</code> as well so the whole domain gets matched, you have to include the <code>.org</code> in the pattern:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/org-all-match.png" alt="org-all-match" width="600" height="400" loading="lazy"></p>
<p>Since lookahead groups don’t consume characters, you will see a lot of developers use positive lookaheads to validate passwords.</p>
<p>Let's say you want the password to be at least six characters that includes a lowercase letter, an uppercase letter, a number, and a symbol. You can use lookaheads to define all of those conditions:</p>
<ul>
<li><code>(?=.{6,})</code> ¬– at least 6 characters</li>
<li><code>(?=.*[a-z])</code> – at least one lowercase character, but check if there are zero or many characters before it</li>
<li><code>(?=.*[A-Z])</code> – at least one lowercase character, but check if there are zero or many characters before it</li>
<li><code>(?=.*[0-9])</code> – at least one number, but check if there are zero or many characters before it</li>
<li><code>(?=.*[!@#$%%^&amp;*()+=-])</code> – accepted symbols, but check if there are zero or many characters before each</li>
<li><code>.*</code> – check if there are zero or many characters after the groups</li>
</ul>
<p>Here's the full regular expression:</p>
<pre><code class="lang-js">(?=.{<span class="hljs-number">6</span>,})(?=.*[a-z])(?=.*[A-Z])(?=.*[<span class="hljs-number">0</span><span class="hljs-number">-9</span>])(?=.*[!@#$%%^&amp;*()+=-]).*
</code></pre>
<p>And here is what matches the pattern and what does not:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/pword-lookahead.png" alt="pword-lookahead" width="600" height="400" loading="lazy"></p>
<p>To use that pattern in JavaScript, you can test it against a password string and do something from there:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> password = <span class="hljs-string">'Tse23*'</span>;
<span class="hljs-keyword">const</span> passwordRe =
  <span class="hljs-regexp">/(?=.{6,})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%%^&amp;*()+=-]).*/</span>;

<span class="hljs-keyword">if</span> (passwordRe.test(password)) {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Welcome to your dashboard!'</span>);
} <span class="hljs-keyword">else</span> {
  <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Incorrect password!'</span>);
}

<span class="hljs-comment">/**
output: Welcome to your dashboard!
*/</span>
</code></pre>
<p>For the application of negative lookahead, it is useful when you don't want a certain character before the character(s) you are looking for in a string. </p>
<p>Let's say you want to extract all items of an array that do not have the article "the" before them. In that case, you can use the pattern below:</p>
<pre><code class="lang-console">/^(?!.*\bThe\b).*$/
</code></pre>
<p>In the pattern above:</p>
<ul>
<li><code>^</code> ensures the regex pattern matches from the start of the line</li>
<li><code>(?!.*\bThe\b)</code> is the negative lookbehind that ensures that the article "the" is not in the target string</li>
<li><code>\bThe\b</code> is a word boundary that matches "The" and nothing else</li>
<li><code>.*</code> the wildcard that matches any character apart from a new line</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> docTitles = [
  <span class="hljs-string">'The Incredible Dr. Poll'</span>,
  <span class="hljs-string">'Born in Africa'</span>,
  <span class="hljs-string">"America's Funniest Home Videos"</span>,
  <span class="hljs-string">'The Lion Queen'</span>,
  <span class="hljs-string">'Snake in the City'</span>,
];
<span class="hljs-keyword">let</span> re = <span class="hljs-regexp">/^(?!.*\bThe\b).*$/</span>;

<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> title <span class="hljs-keyword">of</span> docTitles) {
  <span class="hljs-keyword">if</span> (re.test(title)) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`A Title without "The": <span class="hljs-subst">${title}</span>`</span>);
  }
}

<span class="hljs-comment">/*
Output:
A Title without "The": Born in Africa
A Title without "The": America's funniest home videos
A Title without "The": Snake in the City
*/</span>
</code></pre>
<h3 id="heading-what-is-a-lookbehind-group">What is a Lookbehind Group?</h3>
<p>A lookbehind group is similar to lookahead group. But instead of checking if a certain character(s) follows what you're trying to match, it checks whether the character(s) precedes what you're trying to match.</p>
<p>So, a lookbehind group is a non-capturing group that lets you match a part of a string only if it is preceded by another character in the string, without including that string or text to match in the pattern.</p>
<p>Like lookaheads, there are also positive and negative lookbehind assertions. A positive lookbehind returns a match only if the character you want to match is preceded by another character you specify in your pattern. On the other hand, a negative lookbehind returns a match only if the character you want to match is not preceded by another character.</p>
<p>A positive lookbehind is represented by an opening parenthesis, a question mark, a less than symbol, an equals sign, the character(s), and a closing parenthesis:</p>
<pre><code class="lang-console">(?&lt;=chars)
</code></pre>
<p>For example, the pattern <code>(?&lt;=x)y</code> indicates you want to match <code>y</code> only if there's <code>x</code> before it. In this case, <code>xx</code> or <code>yx</code> won't match, but <code>xy</code> would match.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/positive-lookbehind-match.png" alt="positive-lookbehind-match" width="600" height="400" loading="lazy"></p>
<p>For a negative lookbehind, an exclamation mark replaces the equals sign:</p>
<pre><code class="lang-console">(?&lt;!chars)
</code></pre>
<p>For example, the pattern <code>(?&lt;!x)y</code> means do not match <code>y</code> if there's <code>x</code> before it. In this case <code>by</code> would match, <code>my</code>, would match, but never <code>xy</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/negative-lkb-match.png" alt="negative-lkb-match" width="600" height="400" loading="lazy"></p>
<p>Positive lookbehind groups can be useful for matching numbers preceded only by a certain currency symbol, for example numbers preceded by the dollar sign.</p>
<p>The regex pattern below has a positive lookbehind that matches a number only if it is preceded by a dollar sign:</p>
<pre><code class="lang-js">(?&lt;=\$)\d+(\.\d*)?
</code></pre>
<p>In the pattern above, the lookbehind (<code>(?&lt;=\$)</code>) checks whether there's a dollar sign before one or more digits (represented by <code>\d+</code>). The other group, <code>(\.\d*)</code>, and the zero or one quantifier (<code>?</code>) check whether the number contains floating points.</p>
<p>Here's what matches and what does not:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/positive-lkb-match.png" alt="positive-lkb-match" width="600" height="400" loading="lazy"></p>
<p>In JavaScript, what you can do with the numbers that match is to calculate the total with the <code>reduce()</code> method:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myStr =
  <span class="hljs-string">'10 pieces of the items cost $102.99, but you can get 15 for a discount of $2, and 20 for a discount of $3.99'</span>;

<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/(?&lt;=\$)\d+(\.\d*)?/g</span>;

<span class="hljs-comment">// put all the prices in an array</span>
<span class="hljs-keyword">const</span> allPrices = myStr.match(re); <span class="hljs-comment">// [ '102.99', '2', '3.99' ]</span>

<span class="hljs-comment">// convert each of the prices to a number with map() and unary plus</span>
<span class="hljs-keyword">const</span> allPricesToNum = allPrices.map(<span class="hljs-function">(<span class="hljs-params">price</span>) =&gt;</span> +price); <span class="hljs-comment">// [ 102.99, 2, 3.99 ]</span>

<span class="hljs-comment">// add all the numbers with reduce()</span>
<span class="hljs-keyword">const</span> sumOfAllPrices = allPricesToNum.reduce(<span class="hljs-function">(<span class="hljs-params">acc, curr</span>) =&gt;</span> acc + curr, <span class="hljs-number">0</span>); <span class="hljs-comment">// 108.97999999999999</span>

<span class="hljs-comment">// add a dolar sign to the number and use toFixed() to round it down</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`$<span class="hljs-subst">${sumOfAllPrices.toFixed(<span class="hljs-number">2</span>)}</span>`</span>); <span class="hljs-comment">// $108.98</span>
</code></pre>
<p>For the example of negative lookbehind, let's say you want to match a digit as long as it is not preceded by the dollar sign. This pattern does it:</p>
<pre><code class="lang-js">(?&lt;!\$)\d+
</code></pre>
<p>But unfortunately, it still looks out for a number inside another number and matches it even if there's a dollar sign before the whole number:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/dollar-negative-lkb-err.png" alt="dollar-negative-lkb-err" width="600" height="400" loading="lazy"></p>
<p>To correct that behavior, you can surround the whole pattern with a word boundary (<code>\b</code>):</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/dollar-negative-lkb-fix.png" alt="dollar-negative-lkb-fix" width="600" height="400" loading="lazy"></p>
<p>Negative lookbehind groups are supported in JavaScript as well:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> monies = <span class="hljs-string">'$123 456 $789 £12 ₦568 $8903 £345'</span>;
<span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/\b(?&lt;!\$)\d+\b/g</span>;

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Monies without dollar sign:'</span>, monies.match(re)); <span class="hljs-comment">// Monies without dollar sign: [ '456', '12', '568', '345' ]</span>
</code></pre>
<h2 id="heading-chapter-8-regex-best-practices-and-troubleshooting">Chapter 8: Regex Best Practices and Troubleshooting</h2>
<h3 id="heading-best-practices-to-consider-while-writing-regular-expressions">Best Practices to Consider While Writing Regular Expressions</h3>
<p>Over time, regular expressions can become complex and hard to understand, depending on the use case and purpose. Things may become more complicated if it takes you a long time to come back to them or you work in a team.</p>
<p>Luckily, there are a few best practices to consider while writing regular expressions so you can make things easier for yourself and your team members.</p>
<p>Here are those best practices:</p>
<ul>
<li><p><strong>Keep it simple and readable</strong>: a simple, easy-to-read, and effective regex is better than a complex and effective regex. If you can make the regex efficient without using the complex concept of non-capturing groups like lookarounds (lookaheads and lookbehinds), then don’t use them.</p>
</li>
<li><p><strong>Avoid greedy matches</strong>: metacharacters like <code>*</code> and <code>+</code> and the wildcard (<code>.</code>) are greedy by default. It's hard to do without them, but when you use them and they cause greediness, make sure you use the zero or one quantifier (<code>?</code>) on them. In addition, avoid using the wildcard where necessary.</p>
</li>
<li><p><strong>Use comments to describe what a regex does</strong>: if you're working in a team, try to explain what the regexes you write do so others can understand them without wasting time.</p>
</li>
<li><p><strong>Use online regex testers</strong>: instead of writing your regular expressions in your code editor, write them in regex testers where you can test what they match without writing some more code. Free online regex testers like regex101 and regexpal.com also play a role in debugging because they can highlight errors and tell you what's wrong. </p>
</li>
<li><p><strong>Escape special characters</strong>: if you want to perform a literal match on metacharacters like <code>.</code>, <code>*</code>, <code>+</code>, <code>{</code>, <code>}</code>, and others, don’t forget to escape them unless you're using them inside a character set. Sometimes, you even have to escape hyphens in a character set. </p>
</li>
</ul>
<h3 id="heading-how-to-write-accurate-regular-expressions">How to Write Accurate Regular Expressions</h3>
<p>Writing accurate regular expressions with precision requires understanding what you want to match, the pattern to use, attention to detail, and an understanding of the underlying syntax and behavior of regular expressions in general.</p>
<p>This is crucial in order to ensure there are no avoidable errors and make sure the regexes you write effectively match the desired string.</p>
<p>Here are some tips to help you write accurate regular expressions:</p>
<ul>
<li><p><strong>Understand the string you want to match</strong>: before you write the regex pattern to match a string, examine the string closely. Determine if you're targeting the whole string or a particular part of the string. If you're targeting a part of the string or you want to strip out some, look out for the pattern that you want follow. If you get familiar with the string, you can write a more accurate regex.</p>
</li>
<li><p><strong>Be specific</strong>: avoid using the wildcard where necessary. For instance, do not use the wildcard to match a number since you can use <code>\d</code> or <code>[0-9]</code>, or uppercase letters since you can use <code>[A-Z]</code>.</p>
</li>
<li><p><strong>Use quantifiers to shorten patterns</strong>: if you want a particular part of your regex to match repeated occurrences, try to use quantifiers like <code>+</code>, <code>*</code>, <code>{n,m}</code>, <code>{n,}</code>, and <code>{n}</code>. For instance, if you want to match a date with <code>/</code> as the separator, you can use the pattern <code>\d{1,2}\/\d{1,2}\/\d{4}</code> instead of <code>\d\d\/\d\d\/\d\d\d\d</code>.</p>
</li>
<li><p><strong>Use online regex testers</strong>: online regex testers like regexpal.com and regex101.com help you write more accurate regexes by giving you a live match preview, highlighting matches, and showing you errors their engines encounter while processing the regexes.</p>
</li>
<li><p><strong>Use word boundary to prevent unwanted matches</strong>: surrounding your pattern with the word boundary (<code>\b</code>) can help you prevent unnecessary and unwanted matches. For example, if you want to match a 6-digit zip code, <code>\d{6}</code> can do it for you but will also match any part of the string that has 6 digits that follow one another. What would do it better is <code>\b\d{6}\b</code>.</p>
</li>
</ul>
<p>Anchors (<code>^</code> and <code>$</code>) can also help prevent unwanted matches since they "anchor" a pattern to the start or end of the line. You can use them to make sure the match is found at the end or start of the line, or both. </p>
<p>For example:</p>
<ul>
<li><code>/^Hello/i</code> would only match <code>Hello</code> or <code>hello</code> at the start of a line</li>
<li><code>/Hello$/i</code> would only match <code>Hello</code> or <code>hello</code> at the end of a line</li>
<li><code>/^Hello$/i</code> would only match <code>Hello</code> or <code>hello</code> if it’s the only target string unless you have the multiline flag turned on and there's <code>Hello</code> or <code>hello</code> on another line.</li>
</ul>
<p>If you have issues getting things right with a regex pattern, online testing tools like regex101.com and regexpal.com can also help you step through the pattern bit by bit. There are also regex visualizers you can use to check what's wrong with your regex patterns. </p>
<p>One of those tools that I find amazing is Regulex (jex.im/regulex). It helps you put your regular expressions in a visual perspective you can export</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/regulex-right.png" alt="regulex-right" width="600" height="400" loading="lazy"></p>
<p>And it can show you what goes wrong with your pattern:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/regulex-wrong.png" alt="regulex-wrong" width="600" height="400" loading="lazy"></p>
<h2 id="heading-chapter-9-applications-of-regular-expressions">Chapter 9: Applications of Regular Expressions</h2>
<h3 id="heading-a-better-way-to-match-dates">A Better Way to Match Dates</h3>
<p>You've seen several patterns you can use to match dates in the <code>dd/mm/yyyy</code> format such as <code>\d\d\/\d\d\/\d\d\d\d</code>, <code>\d\d[/.-]\d\d[/.-]\d\d\d\d/;</code>, and <code>\d{1,2}\/\d{1,2}\/\d{4}</code>.</p>
<p>The problem is that those three patterns just check for the occurrence of a number, and not a valid date. For example, invalid dates <code>99/89/2022</code> or <code>42/32/1909</code> would still match those patterns:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/invalid-date-matches.png" alt="invalid-date-matches" width="600" height="400" loading="lazy"></p>
<p>The solution is that you must account for the acceptable day, month, and year:</p>
<ul>
<li>the day can be 1 or 2 digits</li>
<li>the day cannot exceed 31</li>
<li>the month cannot exceed 12</li>
<li>the year could be 2 or 4 digits, but never 1, 3, or greater than 4 digits</li>
</ul>
<p>You should also account for:</p>
<ul>
<li>a day that could start with 0, 1, 2, or 3, but never 4 or greater</li>
<li>a month that could start with 0, or 1, but never 2 or greater</li>
</ul>
<p>Here's the regex pattern that satisfies those conditions:</p>
<pre><code class="lang-console">/^(3[01]|[12][0-9]|0?[1-9])[-./](1[0-2]|0?[1-9])[-./](20[0-9]{2}|[0-9]{4}|[0-9]{2})$/gm
</code></pre>
<p>The image below is an illustration that labels each part of the pattern and explains what they do:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/regexdate--1-.png" alt="regexdate--1-" width="600" height="400" loading="lazy"></p>
<p>Here are the dates that match the pattern and those that do not:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/date-re-matches.png" alt="date-re-matches" width="600" height="400" loading="lazy"></p>
<p>You can take the pattern and test it against some dates in JavaScript:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re =
  <span class="hljs-regexp">/^(3[01]|[12][0-9]|0?[1-9])[-./](1[0-2]|0?[1-9])[-./](20[0-9]{2}|[0-9]{4}|[0-9]{2})$/</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">testDate</span>(<span class="hljs-params">date</span>) </span>{
  <span class="hljs-keyword">const</span> dateTester = re.test(date);
  <span class="hljs-built_in">console</span>.log(dateTester);
}

testDate(<span class="hljs-string">'12-01-2022'</span>); <span class="hljs-comment">// true</span>
testDate(<span class="hljs-string">'31.11.1999'</span>); <span class="hljs-comment">// true</span>
testDate(<span class="hljs-string">'02-01-21'</span>); <span class="hljs-comment">// true</span>
testDate(<span class="hljs-string">'42-01-2021'</span>); <span class="hljs-comment">// false</span>
testDate(<span class="hljs-string">'22-91-23'</span>); <span class="hljs-comment">// false</span>
</code></pre>
<p>You can see the date, month, year, and separator parts of the pattern are in their respective groups. If you want to match other formats like <code>mm/dd/yyyy</code> or <code>yyyy/mm/dd</code>, you can twist the pattern around.</p>
<p>You can even make the pattern a little shorter by putting the first separator in a group and referencing it for the second separator:</p>
<pre><code class="lang-console">^(3[01]|[12][0-9]|0?[1-9])([-./])(1[0-2]|0?[1-9])\2(20[0-9]{2}|[0-9]{4}|[0-9]{2})$
</code></pre>
<h3 id="heading-how-to-match-us-zip-codes">How to Match US Zip Codes</h3>
<p>The zip codes in the US are a 5-digit number, but they may also have a 4-digit extension, for example, <code>56893</code> or <code>56893-9232</code>.</p>
<p>The pattern <code>\b\d{5}\b</code> would match a 5-digit zip-code:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/zip-code-first-part-match.png" alt="zip-code-first-part-match" width="600" height="400" loading="lazy"></p>
<p>You also need to account for the other 4 digits and the hyphen between the two sets of numbers. The pattern, <code>\b\d{5}(\-\d{4})?\b</code> would do that for you.</p>
<p>Here's an image that labels each part of the pattern and explais what they do:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/zip-regex--1-.png" alt="zip-regex--1-" width="600" height="400" loading="lazy"></p>
<p>You can also take the regex and extract all the zip codes that are matches:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/\b\d{5}(\-\d{4})?\b/g</span>;
<span class="hljs-keyword">const</span> zipCodes = [
  <span class="hljs-string">'56893'</span>,
  <span class="hljs-string">'ca58392bn'</span>,
  <span class="hljs-string">'29043'</span>,
  <span class="hljs-string">'90342-9014'</span>,
  <span class="hljs-string">'89435'</span>,
  <span class="hljs-string">'75034'</span>,
  <span class="hljs-string">'90453-3056'</span>,
  <span class="hljs-string">'12345-6789'</span>,
  <span class="hljs-string">'b458923'</span>,
  <span class="hljs-string">'589323'</span>,
];

<span class="hljs-keyword">const</span> matchedZipCodes = [];

<span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> zipCode <span class="hljs-keyword">of</span> zipCodes) {
  <span class="hljs-keyword">const</span> matches = zipCode.match(re);
  <span class="hljs-keyword">if</span> (matches) {
    matchedZipCodes.push(matches[<span class="hljs-number">0</span>]);
  }
}

<span class="hljs-built_in">console</span>.log(matchedZipCodes);

<span class="hljs-comment">/*
Output:
[
  '56893',
  '29043',
  '90342-9014',
  '89435',
  '75034',
  '90453-3056',
  '12345-6789'
]
*/</span>
</code></pre>
<p>And if you want the zip codes that are invalid, you can use the <code>filter()</code> array method to remove those that do not match the pattern:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> re = <span class="hljs-regexp">/\b\d{5}(\-\d{4})?\b/g</span>;
<span class="hljs-keyword">const</span> zipCodes = [
  <span class="hljs-string">'56893'</span>,
  <span class="hljs-string">'ca58392bn'</span>,
  <span class="hljs-string">'29043'</span>,
  <span class="hljs-string">'90342-9014'</span>,
  <span class="hljs-string">'89435'</span>,
  <span class="hljs-string">'75034'</span>,
  <span class="hljs-string">'90453-3056'</span>,
  <span class="hljs-string">'12345-6789'</span>,
  <span class="hljs-string">'b458923'</span>,
  <span class="hljs-string">'589323'</span>,
];

<span class="hljs-keyword">const</span> invalidZipCodes = zipCodes.filter(<span class="hljs-function">(<span class="hljs-params">zipCode</span>) =&gt;</span> !zipCode.match(re));

<span class="hljs-built_in">console</span>.log(invalidZipCodes); <span class="hljs-comment">// [ 'ca58392bn', 'b458923', '589323' ]</span>
</code></pre>
<h3 id="heading-how-to-match-email-addresses">How to Match Email Addresses</h3>
<p>Email addresses could be as simple as <code>john@email.com</code>, and as complex as you can ever imagine. So, there's no "one pattern" for validating email addresses. This also makes email validation a complex thing to do.</p>
<p>Validating emails with regex can also be a bit questionable because you can't stop anyone from making an email up. But still, there's a format you generally want the email address to be in whether it is made up or not. This is why you may want to use regular expressions to validate an email.</p>
<p>A pattern like <code>^/\w{4,}@\w{3,}\.\w{3,}$/</code> could be enough for validating simple and straightforward email addresses like <code>john@example.com</code>.</p>
<p>Here's an image that labels each part of the pattern and explains what they do:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/simpleEmailRegEx.png" alt="simpleEmailRegEx" width="600" height="400" loading="lazy"></p>
<p>And here are the emails that match:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/email-unreliable.png" alt="email-unreliable" width="600" height="400" loading="lazy"></p>
<p>As you can see, the pattern did not even match all the emails provided. That's because the pattern does not account for:</p>
<ul>
<li>emails with a period within usernames like <code>jane.doe@email.com</code> </li>
<li>second-level domain (SLD) extensions like <code>john@example.abc.com</code> </li>
<li>and country code second-level domains (ccSLDs) like <code>jane@email.co.uk</code></li>
</ul>
<p>In fact, a single email can even combine all the criteria listed above.</p>
<p>A better pattern for matching emails is <code>/^[\w.-]+@[a-zA-Z\d.-]+\.[a-zA-Z]{2,}$/</code>. </p>
<p>I also prepare an illustration that labels each part of the pattern and shows what they do:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/betterEmailRegEx.png" alt="betterEmailRegEx" width="600" height="400" loading="lazy"></p>
<p>This pattern matches an email address better than the first one:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/email-a-bit-reliable.png" alt="email-a-bit-reliable" width="600" height="400" loading="lazy"></p>
<p>According to the RFC 5322 specification, the pattern that works 99% of the time for validating email is this:</p>
<pre><code class="lang-console">(?:[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])
</code></pre>
<p><strong>N.B.</strong>: You should surround the pattern with anchors so it doesn’t leave out a part of a possible email and match the others. </p>
<p>This is what I'm trying to point out:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/matchingIvalidEmail.png" alt="matchingIvalidEmail" width="600" height="400" loading="lazy"></p>
<p>You can take that pattern into JavaScript and test it against some email addresses:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> emailRe =
  <span class="hljs-regexp">/^(?:[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">matchEmail</span>(<span class="hljs-params">email</span>) </span>{
  <span class="hljs-keyword">if</span> (emailRe.test(email)) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Valid email!'</span>);
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Invalid email'</span>);
  }
}

matchEmail(<span class="hljs-string">'janedoe@email.com'</span>);
matchEmail(<span class="hljs-string">'john.doe@email.com'</span>);
matchEmail(<span class="hljs-string">'7@koala@email.com!'</span>);
matchEmail(<span class="hljs-string">'kayla.simpson@email.co.uk'</span>);
matchEmail(<span class="hljs-string">'kayla.simpson@email.co..uk'</span>);
</code></pre>
<p>As I pointed out earlier, matching email addresses with regex is a complex task. If you know the kind of email you'll be working with, it is better to tailor your regex for them. </p>
<p>Sometimes, to match an email, all you all you might need is a simple regex. Some other times, the pattern you need might be as complex as the one above.</p>
<h3 id="heading-how-to-match-passwords">How to Match Passwords</h3>
<p>To match passwords, you can use a lookahead – since lookaround groups generally don’t consume characters. But there are always multiple ways of doing the same thing in regular expressions, and programming in general of course.</p>
<p>You've seen a lookahead for matching 6-digit passwords already. This time around, let's say the password should not be less than 8 characters with at least one uppercase, one lowercase, one digit, and one symbol.</p>
<p>Here's the regex pattern that does just that:</p>
<pre><code class="lang-console">^(?=.{8,})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$?%"';^}{&amp;:*()∞+=-]).*$
</code></pre>
<p>Here are the passwords it matches:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/pword-matches.png" alt="pword-matches" width="600" height="400" loading="lazy"></p>
<p>You can take that into JavaScript and test it against possible passwords:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> passwordRe =
  <span class="hljs-regexp">/^(?=.{8,})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$?%"';^}{&amp;:*()∞+=-]).*$/gm</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">matchPassWord</span>(<span class="hljs-params">password</span>) </span>{
  <span class="hljs-keyword">if</span> (passwordRe.test(password)) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-literal">true</span>);
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-literal">false</span>);
  }
}

matchPassWord(<span class="hljs-string">'johnDoe21^'</span>);
matchPassWord(<span class="hljs-string">'Strong@123'</span>);
matchPassWord(<span class="hljs-string">'weakpassword'</span>);
matchPassWord(<span class="hljs-string">'ABcd12$'</span>);
matchPassWord(<span class="hljs-string">'Longpassword1234!'</span>);
matchPassWord(<span class="hljs-string">'Short@1'</span>);
matchPassWord(<span class="hljs-string">'janEdoe34$'</span>);
</code></pre>
<p>You can also extract each of those group into its variable and test a password against it. This would let you show an error for that particular condition the password is trying to match:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> passwordLength = <span class="hljs-regexp">/(?=.{8,})/</span>,
  lowercaseChar = <span class="hljs-regexp">/(?=.*[a-z])/</span>,
  uppercaseChar = <span class="hljs-regexp">/(?=.*[A-Z])/</span>,
  numberChar = <span class="hljs-regexp">/(?=.*[0-9])/</span>,
  specialChar = <span class="hljs-regexp">/(?=.*[!@#$?%"';^}{&amp;:*()∞+=-])/</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">validatePassword</span>(<span class="hljs-params">password</span>) </span>{
  <span class="hljs-keyword">if</span> (
    passwordLength.test(password) &amp;&amp;
    lowercaseChar.test(password) &amp;&amp;
    uppercaseChar.test(password) &amp;&amp;
    numberChar.test(password) &amp;&amp;
    specialChar.test(password)
  ) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Valid password!'</span>);
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Invalid Password'</span>);
  }
}

validatePassword(<span class="hljs-string">'johnDoe21^'</span>);
validatePassword(<span class="hljs-string">'Strong@123'</span>);
validatePassword(<span class="hljs-string">'weakpassword'</span>);
validatePassword(<span class="hljs-string">'ABcd12$'</span>);
validatePassword(<span class="hljs-string">'Longpassword1234!'</span>);
validatePassword(<span class="hljs-string">'Short@1'</span>);
validatePassword(<span class="hljs-string">'janEdoe34$'</span>);
</code></pre>
<h3 id="heading-form-validation-with-regex">Form Validation with Regex</h3>
<p>One of the most popular ways developers use regular expressions is form validation. Since a form usually has input fields like name, email, password, and others, you can write a regular expression for what you expect the user to put in those input fields.</p>
<p>I prepared a little website where I show you how to validate the name, username, email, and password fields of a form with regex. </p>
<p>Here's the HTML:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"styles.css"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"form-validate.js"</span> <span class="hljs-attr">defer</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Form Validation with RegEx<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"error-message"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">""</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Sign Up<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Fill in the form fields<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"name"</span>&gt;</span>Name<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"name"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"name"</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"username"</span>&gt;</span>Username<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"username"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"username"</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"email"</span>&gt;</span>Email<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"email"</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"email"</span>&gt;</span>Password<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"password"</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Submit"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"submit"</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>The CSS:</p>
<pre><code class="lang-css"><span class="hljs-keyword">@import</span> url(<span class="hljs-string">'https://fonts.googleapis.com/css2?family=Roboto&amp;display=swap'</span>);

* {
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">box-sizing</span>: border-box;
}

<span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#d0d0d5</span>;
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
  <span class="hljs-attribute">font-family</span>: <span class="hljs-string">'Roboto'</span>, sans-serif;
}

<span class="hljs-selector-tag">form</span> {
  <span class="hljs-attribute">position</span>: absolute;
  <span class="hljs-attribute">top</span>: <span class="hljs-number">50%</span>;
  <span class="hljs-attribute">left</span>: <span class="hljs-number">50%</span>;
  <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translate</span>(-<span class="hljs-number">50%</span>, -<span class="hljs-number">50%</span>);
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#3b3b4f</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.4rem</span> <span class="hljs-number">3rem</span> <span class="hljs-number">1rem</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">2px</span>;
}

<span class="hljs-selector-tag">p</span> {
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0.5rem</span> <span class="hljs-number">0</span>;
}

<span class="hljs-selector-id">#error-message</span> {
  <span class="hljs-attribute">background-color</span>: crimson;
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
  <span class="hljs-attribute">max-width</span>: <span class="hljs-number">80%</span>;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0.5rem</span> auto <span class="hljs-number">0</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.2rem</span> <span class="hljs-number">0.5rem</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">4px</span>;
}

<span class="hljs-selector-id">#error-message</span> <span class="hljs-selector-tag">p</span> {
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">14px</span>;
  <span class="hljs-attribute">text-align</span>: center;
}

<span class="hljs-selector-class">.form-control</span> {
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">flex-direction</span>: column;
}

<span class="hljs-selector-class">.form-control</span> <span class="hljs-selector-tag">label</span> {
  <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">0.2rem</span>;
}

<span class="hljs-selector-class">.form-control</span> <span class="hljs-selector-tag">input</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">14rem</span>;
  <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">1.2rem</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.2rem</span>;
  <span class="hljs-attribute">border</span>: <span class="hljs-number">2px</span> solid <span class="hljs-number">#d0d0d5</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">2px</span>;
}

<span class="hljs-selector-class">.form-control</span> <span class="hljs-selector-tag">input</span><span class="hljs-selector-pseudo">:focus</span> {
  <span class="hljs-attribute">outline</span>: none;
}

<span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=<span class="hljs-string">'submit'</span>]</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#fecc4c</span>;
  <span class="hljs-attribute">border-color</span>: <span class="hljs-number">#f1a02a</span>;
  <span class="hljs-attribute">font-family</span>: <span class="hljs-string">'Roboto'</span>, sans-serif;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.3rem</span>;
  <span class="hljs-attribute">border-width</span>: <span class="hljs-number">1px</span>;
  <span class="hljs-attribute">cursor</span>: pointer;
}

<span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=<span class="hljs-string">'submit'</span>]</span><span class="hljs-selector-pseudo">:hover</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#e3bd53</span>;
}

<span class="hljs-selector-class">.hide</span> {
  <span class="hljs-attribute">display</span>: none;
}

<span class="hljs-selector-class">.show</span> {
  <span class="hljs-attribute">display</span>: block;
}

<span class="hljs-keyword">@media</span> screen <span class="hljs-keyword">and</span> (<span class="hljs-attribute">max-width:</span> <span class="hljs-number">768px</span>) {
  <span class="hljs-selector-id">#error-message</span> {
    <span class="hljs-attribute">margin</span>: <span class="hljs-number">0.5rem</span> auto <span class="hljs-number">0</span>;
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.1rem</span> <span class="hljs-number">0.2rem</span>;
  }
}

<span class="hljs-keyword">@media</span> screen <span class="hljs-keyword">and</span> (<span class="hljs-attribute">max-width:</span> <span class="hljs-number">667px</span>) {
  <span class="hljs-selector-tag">form</span> {
    <span class="hljs-attribute">top</span>: <span class="hljs-number">61%</span>;
  }

  <span class="hljs-selector-id">#error-message</span> {
    <span class="hljs-attribute">margin</span>: <span class="hljs-number">0.2rem</span> auto <span class="hljs-number">0</span>;
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.1rem</span> <span class="hljs-number">0.4rem</span>;
  }
}
</code></pre>
<p>Most importantly, some well-commented JavaScript that contains the patterns I used, and how I tested each of the patterns against the respective fields they correlate with:</p>
<pre><code class="lang-js"><span class="hljs-comment">// Get the form element</span>
<span class="hljs-keyword">const</span> form = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'form'</span>);
<span class="hljs-comment">// Get the div element that shows the error(s)</span>
<span class="hljs-keyword">const</span> errorMessageDiv = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#error-message'</span>);

<span class="hljs-comment">// The RegEx patterns in a "patterns" object</span>
<span class="hljs-keyword">const</span> patterns = {
  <span class="hljs-attr">nameRe</span>: <span class="hljs-regexp">/^[a-zA-Z]{2,35}\s[a-zA-Z]{2,35}$/</span>, <span class="hljs-comment">// validates the name field</span>
  usernameRe: <span class="hljs-regexp">/^[a-zA-Z]{3,30}(\d{1,4})?$/</span>, <span class="hljs-comment">// validates the username field</span>
  emailRe: <span class="hljs-regexp">/^[\w.-]+@[a-zA-Z\d.-]+\.[a-zA-Z]{2,}$/</span>, <span class="hljs-comment">// validates the email field</span>
  passwordRe:
    <span class="hljs-regexp">/^(?=.{8,})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$?%"';^}{&amp;:*()∞+=-]).*$/</span>, <span class="hljs-comment">// validates the password field</span>
};

<span class="hljs-comment">// Hide error message div when the page loads</span>
errorMessageDiv.style.display = <span class="hljs-string">'none'</span>;

<span class="hljs-comment">// Add a submit event to the form</span>
form.addEventListener(<span class="hljs-string">'submit'</span>, validateAndSubmitForm);

<span class="hljs-comment">// Form validation and submit function</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">validateAndSubmitForm</span>(<span class="hljs-params">e</span>) </span>{
  e.preventDefault();

  <span class="hljs-comment">// Clear previous error messages</span>
  errorMessageDiv.innerHTML = <span class="hljs-string">''</span>;

  <span class="hljs-keyword">let</span> nameInputValue = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#name'</span>).value;
  <span class="hljs-keyword">let</span> usernameInputValue = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#username'</span>).value;
  <span class="hljs-keyword">let</span> emailInputValue = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#email'</span>).value;
  <span class="hljs-keyword">let</span> passwordInputValue = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#password'</span>).value;

  <span class="hljs-comment">// Validate Name</span>
  <span class="hljs-keyword">if</span> (!patterns.nameRe.test(nameInputValue)) {
    showError(<span class="hljs-string">'Name must have first name and last name separated by a space'</span>);
  }

  <span class="hljs-comment">// Validate Username</span>
  <span class="hljs-keyword">if</span> (!patterns.usernameRe.test(usernameInputValue)) {
    showError(
      <span class="hljs-string">'Username must have between 3 and 30 characters and can include up to 4 digits at the end'</span>
    );
  }

  <span class="hljs-comment">// Validate Email</span>
  <span class="hljs-keyword">if</span> (!patterns.emailRe.test(emailInputValue)) {
    showError(<span class="hljs-string">'Enter a valid email address'</span>);
  }

  <span class="hljs-comment">// Validate Password</span>
  <span class="hljs-keyword">if</span> (!patterns.passwordRe.test(passwordInputValue)) {
    showError(
      <span class="hljs-string">'Password must contain at least 8 characters, one lowercase letter, one uppercase letter, one digit, and one special character.'</span>
    );
  }

  <span class="hljs-comment">// If there are no error messages, the form is valid, so you can submit it</span>
  <span class="hljs-keyword">if</span> (errorMessageDiv.innerHTML === <span class="hljs-string">''</span>) {
    <span class="hljs-built_in">console</span>.log(nameInputValue);
    <span class="hljs-built_in">console</span>.log(usernameInputValue);
    <span class="hljs-built_in">console</span>.log(emailInputValue);
    <span class="hljs-built_in">console</span>.log(passwordInputValue);

    <span class="hljs-comment">// Hide the errorMessageDiv element since there are no errors</span>
    errorMessageDiv.style.display = <span class="hljs-string">'none'</span>;

    <span class="hljs-comment">// Greet user</span>
    alert(<span class="hljs-string">`Hi <span class="hljs-subst">${usernameInputValue}</span> 👋🏽 \nThanks for filling this form`</span>);

    <span class="hljs-comment">// Clear input fields with the reset() method</span>
    <span class="hljs-built_in">document</span>.forms[<span class="hljs-number">0</span>].reset();
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-comment">// Show the errorMessageDiv element if there are errors</span>
    errorMessageDiv.style.display = <span class="hljs-string">'block'</span>;
  }
}

<span class="hljs-comment">// The function responsible for showing error(s)</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">showError</span>(<span class="hljs-params">message</span>) </span>{
  <span class="hljs-keyword">const</span> errorMessageElement = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'p'</span>);

  errorMessageElement.innerText = message;
  errorMessageDiv.appendChild(errorMessageElement);
}
</code></pre>
<p>This is what the form does:
<img src="https://www.freecodecamp.org/news/content/images/2023/07/form-validation.gif" alt="form-validation" width="600" height="400" loading="lazy"></p>
<p>You can grab all the code in this <a target="_blank" href="https://github.com/Ksound22/regex-bk-form-validator">GitHub repo</a>.</p>
<h3 id="heading-article-table-of-contents-generator">Article Table of Contents Generator</h3>
<p>You can leverage the power of regular expressions to create a markdown table of contents generator.</p>
<p>Markdown tables of contents are made up of <code>h2</code> headings at the top level. Those <code>h2</code> headings have an <code>id</code> attribute you can use as the link. If you take a look at those <code>id</code> attributes, they are in the format below:</p>
<pre><code class="lang-console">[How to Do ABC on XYZ!!!](##howtodoabconxyz)
</code></pre>
<p>This means you need to:</p>
<ul>
<li>use the text as it is as the link text and surround them with curly braces</li>
<li>replace all spaces with an empty string</li>
<li>replace all symbols with an empty string</li>
<li>convert all the letters to lowercase</li>
<li>surround the new link with parenthesis</li>
</ul>
<p>The <code>replace()</code> and <code>lowerCase()</code> string methods will help you achieve those things.</p>
<p>Here's the HTML for the app:</p>
<pre><code class="lang-js">&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;

&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;link rel="stylesheet" href="styles.css"&gt;
    &lt;script src="toc.js" defer&gt;&lt;/script&gt;
    &lt;title&gt;TOC Generator&lt;/title&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;div class="alert" id="alert"&gt;
        Please enter some heading texts!
    &lt;/div&gt;

    &lt;h1&gt;Markdown Table of Content Generator for your Next Article&lt;/h1&gt;
    &lt;h2&gt;Paste in your headings to generate table of content&lt;/h2&gt;
    &lt;form action=""&gt;

        &lt;div class="form"&gt;
            &lt;div class="form-control"&gt;
                &lt;textarea name="toc" id="toc" cols="40" rows="15"&gt;&lt;/textarea&gt;
            &lt;/div&gt;

            &lt;div class="form-control"&gt;
                &lt;input type="submit" value="Generate" id="submit"&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/form&gt;

    &lt;div id="generated-toc"&gt;
        &lt;!-- &lt;p&gt;Lorem ipsum dolor sit amet consectetur.&lt;/p&gt;
        &lt;p&gt;Lorem ipsum dolor sit amet consectetur.&lt;/p&gt;
        &lt;p&gt;Lorem ipsum dolor sit amet consectetur.&lt;/p&gt;
        &lt;p&gt;Lorem ipsum dolor sit amet consectetur.&lt;/p&gt;
        &lt;p&gt;Lorem ipsum dolor sit amet consectetur.&lt;/p&gt;
        &lt;p&gt;Lorem ipsum dolor sit amet consectetur.&lt;/p&gt;
        &lt;p&gt;Lorem ipsum dolor sit amet consectetur.&lt;/p&gt; --&gt;
    &lt;/div&gt;

&lt;/body&gt;

&lt;/html&gt;
</code></pre>
<p>The CSS:</p>
<pre><code class="lang-js">@<span class="hljs-keyword">import</span> url(<span class="hljs-string">'https://fonts.googleapis.com/css2?family=Poppins&amp;family=Roboto&amp;display=swap'</span>);

* {
  <span class="hljs-attr">margin</span>: <span class="hljs-number">0</span>;
  padding: <span class="hljs-number">0</span>;
  box-sizing: border-box;
}

body {
  font-family: <span class="hljs-string">'Poppins'</span> sans-serif;
  background-color: #<span class="hljs-number">3</span>b3b4f;
  color: #fff;
}

h1 {
  margin-top: <span class="hljs-number">2</span>rem;
}

h1,
h2 {
  text-align: center;
  color: black;
  margin-bottom: <span class="hljs-number">1</span>rem;
  color: white;
}

form {
  max-width: <span class="hljs-number">90</span>%;
  margin: <span class="hljs-number">0</span> auto;
  background-color: #d0d0d5;
  padding: <span class="hljs-number">2</span>rem;
  border-radius: <span class="hljs-number">2</span>px;
}

.form-control {
  text-align: center;
}

textarea {
  <span class="hljs-attr">padding</span>: <span class="hljs-number">0.2</span>rem <span class="hljs-number">2</span>rem <span class="hljs-number">1</span>rem <span class="hljs-number">0.2</span>rem;
}

<span class="hljs-attr">textarea</span>:focus {
  <span class="hljs-attr">outline</span>: <span class="hljs-number">1</span>px solid #<span class="hljs-number">3</span>b3b4f;
}

input[type=<span class="hljs-string">'submit'</span>] {
  font-family: <span class="hljs-string">'Poppins'</span>, sans-serif;
  font-size: <span class="hljs-number">1.1</span>rem;
  border: none;
  background-color: #<span class="hljs-number">03732</span>e;
  color: #fff;
  padding: <span class="hljs-number">0.5</span>rem <span class="hljs-number">1</span>rem;
  border-radius: <span class="hljs-number">4</span>px;
  margin-top: <span class="hljs-number">1</span>rem;
  transition: <span class="hljs-number">0.3</span>s;
}

input[type=<span class="hljs-string">'submit'</span>]:hover {
  <span class="hljs-attr">cursor</span>: pointer;
  background-color: #<span class="hljs-number">00471</span>b;
}

#generated-toc {
  max-width: <span class="hljs-number">60</span>%;
  margin: <span class="hljs-number">1</span>rem auto;
  background-color: #d0d0d5;
  color: black;
  padding: <span class="hljs-number">2</span>rem;
  border-radius: <span class="hljs-number">2</span>px;
  text-align: left;
  font-size: <span class="hljs-number">1.1</span>rem;
  display: none;
}

.alert {
  <span class="hljs-attr">display</span>: none;
  margin: <span class="hljs-number">1</span>rem auto;
  max-width: <span class="hljs-number">20</span>%;
  text-align: center;
  padding: <span class="hljs-number">1</span>rem <span class="hljs-number">0</span>;
  border-radius: <span class="hljs-number">2</span>px;
  background-color: #eb7189;
  color: black;
}

@media screen and (max-width: <span class="hljs-number">768</span>px) {
  textarea {
    <span class="hljs-attr">width</span>: <span class="hljs-number">16</span>rem;
  }

  .alert {
    max-width: <span class="hljs-number">50</span>%;
  }
}
</code></pre>
<p>And the well-commented JavaScript:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> form = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'form'</span>);
<span class="hljs-keyword">const</span> generatedToc = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#generated-toc'</span>);
<span class="hljs-keyword">const</span> alert = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.alert'</span>);

<span class="hljs-comment">// Regular expressions to remove spaces and special characters</span>
<span class="hljs-keyword">const</span> spaceRe = <span class="hljs-regexp">/\s+/g</span>;
<span class="hljs-keyword">const</span> symRe = <span class="hljs-regexp">/[°?+*$∞^%$#@!.,©:&amp;;"=%'_\[\]–\/\\&lt;&gt;|÷™®)£(}{€¥¢—“”‘•~]/g</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generateToc</span>(<span class="hljs-params">e</span>) </span>{
  e.preventDefault();

  <span class="hljs-comment">// Get the heading texts from the textarea</span>
  <span class="hljs-keyword">const</span> headingTexts = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#toc'</span>).value;

  <span class="hljs-keyword">if</span> (headingTexts === <span class="hljs-string">''</span>) {
    <span class="hljs-comment">// Alert the user to enter heading texts</span>
    alert.style.display = <span class="hljs-string">'block'</span>;

    <span class="hljs-comment">// hide the alert after 3 seconds</span>
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      alert.style.display = <span class="hljs-string">'none'</span>;
    }, <span class="hljs-number">3000</span>);

    <span class="hljs-comment">// hide generated table of content (if any) since the user is trying to paste in another one</span>
    generatedToc.style.display = <span class="hljs-string">'none'</span>;
    <span class="hljs-keyword">return</span>;
  }

  <span class="hljs-comment">// Split the heading texts into an array of lines</span>
  <span class="hljs-keyword">const</span> headingLines = headingTexts.split(<span class="hljs-string">'\n'</span>);

  <span class="hljs-comment">// Create an initial empty variable to save the table of content inside later</span>
  <span class="hljs-keyword">let</span> tocContent = <span class="hljs-string">''</span>;

  <span class="hljs-comment">// Loop through each line and generate the table of content items</span>
  headingLines.forEach(<span class="hljs-function">(<span class="hljs-params">headingLine</span>) =&gt;</span> {
    <span class="hljs-comment">// Remove any leading and/or trailing spaces from the line</span>
    headingLine = headingLine.trim();

    <span class="hljs-comment">// skip empty lines</span>
    <span class="hljs-keyword">if</span> (headingLine === <span class="hljs-string">''</span>) {
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-comment">// Generate the TOC link based on the heading text(s)</span>
    <span class="hljs-keyword">const</span> markdownLink = headingLine
      .replace(spaceRe, <span class="hljs-string">''</span>) <span class="hljs-comment">// replace spaces with an empty string</span>
      .replace(symRe, <span class="hljs-string">''</span>) <span class="hljs-comment">// replace special characters (symbols)</span>
      .toLowerCase(); <span class="hljs-comment">// convert the link texts to lowercase characters</span>

    <span class="hljs-comment">// Create the table of contents item and append it to the tocContent variable</span>
    tocContent += <span class="hljs-string">`&lt;p&gt;• [<span class="hljs-subst">${headingLine}</span>](#<span class="hljs-subst">${markdownLink}</span>)&lt;/p&gt;`</span>;
  });

  <span class="hljs-comment">// Insert the generated table of contents into the "generated-toc" div element</span>
  generatedToc.innerHTML = tocContent;

  <span class="hljs-comment">// hide alert since there's currently no error at this point</span>
  alert.style.display = <span class="hljs-string">'none'</span>;

  <span class="hljs-comment">// show the "generated-toc" div</span>
  generatedToc.style.display = <span class="hljs-string">'block'</span>;

  <span class="hljs-comment">// clear the heading texts in the text area</span>
  <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#toc'</span>).value = <span class="hljs-string">''</span>;
}

<span class="hljs-comment">// Add a submit event to the form</span>
form.addEventListener(<span class="hljs-string">'submit'</span>, generateToc);

<span class="hljs-comment">/*
What is HTML?
How to Contribute$ To Open Source Like a Boss!!
Why you should Learn to C$ode in Java?

Why you should get into Web3!
Don't Attach Question Mark(?) to Hows!
Stop Scaring Newbies!
Why are you too cold&amp;
*/</span>
</code></pre>
<p>Here's what's happening in the app:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/tocgen.gif" alt="tocgen" width="600" height="400" loading="lazy"></p>
<p>You can look through the code to have more understanding of how I was able to do that. The code is available on this <a target="_blank" href="https://github.com/Ksound22/regex-bk-form-validator">GitHub repo</a> and the app is <a target="_blank" href="https://astonishing-dolphin-948101.netlify.app/">live here</a>.</p>
<h2 id="heading-glossary-and-references">Glossary and References</h2>
<h3 id="heading-glossary-of-terms">Glossary of Terms</h3>
<ul>
<li><code>Regular Expression</code> or <code>RegEx</code>: A you can use for matching, searching, and manipulating text.</li>
<li><code>Pattern</code> or <code>regex pattern</code>: A sequence of characters that defines a search criterion in a regular expression.</li>
<li><code>Literal Character</code>: A character that matches itself in a regular expression (for example, "a" matches the character "a").</li>
<li><code>Flag</code>: Modifiers added after the closing delimiter of a regex to change matching behavior, such as <code>i</code> (case-insensitive) or <code>g</code> (global).</li>
<li><code>Metacharacter</code>: A character with a special meaning in a regular expression. Examples include <code>.</code> (any character), <code>*</code> (zero or more), and <code>|</code> (alternation).</li>
<li><code>Quantifier</code>: A metacharacter that specifies the number of repetitions of the preceding element. For example, <code>*</code> matches zero or more occurrences, and <code>{n}</code> matches <code>n</code> character(s).</li>
<li><code>Anchors</code>: Metacharacters that represent positions in the input string, such as <code>^</code> (start of line) and <code>$</code> (end of line).</li>
<li><code>Grouping</code>: Using parentheses <code>()</code> to create a subexpression you can repeat or reference as a single unit.</li>
<li><code>Capture Group</code>: A group in a regular expression that captures and stores the matched text for later use.</li>
<li><code>Non-Capturing Group</code>: A group in a regular expression that matches the pattern but does not capture the matched text.</li>
<li><code>Greedy</code>: A matching behavior where quantifiers try to match as much as possible.</li>
<li><code>Lazy</code>: Another matching behavior where quantifiers match as little as possible. It is the opposite of <code>greedy</code>.</li>
<li><code>Lookahead</code>: A zero-width assertion that looks ahead to see if a pattern exists without including it in the match.</li>
<li><code>Lookbehind</code>: A zero-width assertion that looks behind to see if a pattern exists without including it in the match.</li>
<li><code>Escape Sequence and Character</code>: Using a backslash <code>\</code>to escape a metacharacter to treat it as a literal character. Or using it before a character to match its special meaning instead of the literal character. For example, <code>\d</code>.</li>
<li><code>Word Boundary</code>: A zero-width assertion that matches the position between a word character and a non-word character.</li>
<li><code>Negated Character Class</code>: A character class with <code>^</code> as the first character, matching any character not in the class.</li>
<li><code>Regex Engine</code>: The underlying software component that processes regular expressions and performs matching.</li>
<li><code>Case Sensitive</code>: A matching behavior where letters' cases must exactly match in the regex pattern and the input string.</li>
<li><code>Case Insensitive</code>: A flag (<code>i</code>) that enables case-insensitive matching in the regular expression.</li>
<li><code>Shorthand Character Class</code>: Shortcuts for common character classes, such as <code>\d</code> (digit), <code>\w</code> (word character), and <code>\s</code> (whitespace).</li>
<li>Backreference: Referring to a captured group's content in the regex pattern. For example, <code>\1</code>.</li>
<li>Alternation: Using the <code>|</code> metacharacter to match either of two patterns.</li>
<li>JavaScript RegExp Object: The built-in JavaScript object that represents a regular expression. It has methods like <code>test()</code> and <code>exec()</code> for working with regular expressions.</li>
<li><code>Regular Expression Literals</code>: Regular expressions defined using slashes <code>/.../</code>, e.g., <code>/regex-pattern/</code>.</li>
<li>RegExp Constructor: The RegExp constructor for creating regular expressions dynamically.</li>
</ul>
<h3 id="heading-quick-reference-of-metacharacters-and-quantifiers">Quick Reference of Metacharacters and Quantifiers</h3>
<ul>
<li><code>\d</code>: matches any digit (0-9).</li>
<li><code>\D</code>: matches any non-digit character.</li>
<li><code>\w</code>: matches any word character (alphanumeric characters and underscore).</li>
<li><code>\W</code>: matches any non-word character.</li>
<li><code>\s</code>: matches any whitespace character (space, tab, newline, carriage return).</li>
<li><code>\S</code>: matches any non-whitespace character.</li>
<li><code>\b</code>: matches a word boundary position.</li>
<li><code>\B</code>: matches a non-word boundary position.</li>
<li><code>^</code>: matches the start of the line.</li>
<li><code>$</code>: matches the end of the line.</li>
<li><code>.</code>: matches any character except newline.</li>
<li><code>*</code>: matches zero or more occurrences.</li>
<li><code>+</code>: matches one or more occurrences.</li>
<li><code>?</code>: matches zero or one occurrence.</li>
<li><code>{n}</code>: matches exactly <code>n</code> (number) occurrences.</li>
<li><code>{n,}</code>: matches <code>n</code> or more occurrences.</li>
<li><code>{n,m}</code> matches at least <code>n</code> and at most <code>m</code> (another number) occurrences.</li>
<li><code>|</code>: matches either the left or right expression.</li>
<li><code>(...)</code>: capturing group.</li>
<li><code>(?:...)</code>: non-capturing group.</li>
<li><code>\</code>: escapes a metacharacter in order to match it literally, or escapes a metacharacter that is also a literal character. For example, <code>\d</code>.</li>
<li><code>[...]</code>: character class.</li>
<li><code>[^...]</code>: negated character class.</li>
<li><code>(?=...)</code>:  positive lookahead.</li>
<li><code>(?!...)</code>: negative lookahead.</li>
<li><code>(?&lt;=...)</code> positive lookbehind.</li>
<li><code>(?&lt;!...)</code>: negative lookbehind.</li>
</ul>
<p>Thank you for reading!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Delete YouTube History – How to Delete YouTube Search and Watch Histories ]]>
                </title>
                <description>
                    <![CDATA[ YouTube is the most popular platform for watching and discovering educational and entertainment-focused videos.  But if you have a privacy concern and want to clear your YouTube history for a fresh start, deleting your YouTube search and watch histor... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/delete-youtube-history-how-to-delete-youtube-search-and-watch-histories/</link>
                <guid isPermaLink="false">66adf0aa2d0eb5bfdd6b0c18</guid>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Mon, 22 May 2023 14:55:02 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/deleteYtHistories.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>YouTube is the most popular platform for watching and discovering educational and entertainment-focused videos. </p>
<p>But if you have a privacy concern and want to clear your YouTube history for a fresh start, deleting your YouTube search and watch histories can be an effective solution. </p>
<p>In this article, I will guide you through the step-by-step process of deleting your YouTube search and watch histories on a computer and the YouTube mobile apps. I will also show you how you can auto-delete the histories, and how you can pause them.</p>
<h2 id="heading-what-well-cover">What We'll Cover</h2>
<ul>
<li><a class="post-section-overview" href="#heading-how-to-delete-your-youtube-search-and-watch-histories-on-a-computer">How to Delete your YouTube Search and Watch Histories on a Computer</a></li>
<li><a class="post-section-overview" href="#heading-how-to-delete-your-youtube-search-and-watch-histories-on-youtube-mobile-apps">How to Delete your YouTube Search and Watch Histories on YouTube Mobile Apps</a></li>
<li><a class="post-section-overview" href="#heading-how-to-auto-delete-your-youtube-search-and-watch-histories">How to Auto-delete your YouTube Search and Watch Histories</a></li>
<li><a class="post-section-overview" href="#heading-how-to-pause-your-youtube-search-and-watch-histories">How to Pause your YouTube Search and Watch Histories</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<h2 id="heading-how-to-delete-your-youtube-search-and-watch-histories-on-a-computer">How to Delete your YouTube Search and Watch Histories on a Computer</h2>
<p><strong>Step 1</strong>: Go to youtube.com and click on the hamburger menu on the left:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss1-6.png" alt="ss1-6" width="600" height="400" loading="lazy"></p>
<p><strong>Step 2</strong>: Select "History".</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss2-3.png" alt="ss2-3" width="600" height="400" loading="lazy"></p>
<p><strong>Step 3</strong>: From here, you can select "Clear all watch history". But instead, select "Manage all history":</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss3-2.png" alt="ss3-2" width="600" height="400" loading="lazy"></p>
<p>Doing that will open up your YouTube history in your Google account activity page. Here, you get to choose a better way to clear your YouTube search and watch histories.</p>
<p><strong>Step 4</strong>: Click on the arrow icon in front of "Delete":</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss4-2.png" alt="ss4-2" width="600" height="400" loading="lazy"></p>
<p><strong>Step 5</strong>: Select which way suits you better, between "Delete today", "Delete custom range", and "Delete all time":</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss5-3.png" alt="ss5-3" width="600" height="400" loading="lazy"></p>
<p><strong>Step 6</strong>: If you select "Delete custom range", click on the calendar icon in front of both "After" and "Before" to select the dates you want to start the deletion from and where to end it:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss6-2.png" alt="ss6-2" width="600" height="400" loading="lazy"></p>
<p><strong>Step 7</strong>: When you are done, click "Next":</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss7-2.png" alt="ss7-2" width="600" height="400" loading="lazy"></p>
<p><strong>Step 8</strong>: Click "Delete":</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss8.png" alt="ss8" width="600" height="400" loading="lazy"></p>
<p>That's it!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss9.png" alt="ss9" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-delete-your-youtube-search-and-watch-histories-on-youtube-mobile-apps">How to Delete your YouTube Search and Watch Histories on YouTube Mobile Apps</h2>
<p>The process of deleting YouTube search and watch histories on both Android and iOS apps is the same.</p>
<p><strong>Step 1</strong>: Open your YouTube app and tap on your account icon on the right.</p>
<p><strong>Step 2</strong>: Select "Settings" and then "Manage all history". If you have multiple Google accounts on your phone, you have to select the one where you want to delete the YouTube search and watch histories.</p>
<p><strong>Step 3</strong>: Tap the arrow icon in front of "Delete":</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Screenshot_20230519-092007.png" alt="Screenshot_20230519-092007" width="600" height="400" loading="lazy"></p>
<p><strong>Step 4</strong>: Select how you want to delete your search and watch histories:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Screenshot_20230519-092116.png" alt="Screenshot_20230519-092116" width="600" height="400" loading="lazy"></p>
<p><strong>Step 4</strong>: If you tapped "Delete custom range", enter the date to start from and the date to end the deletion, then select "Next" and "Delete":</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Screenshot_20230519-092402.png" alt="Screenshot_20230519-092402" width="600" height="400" loading="lazy"></p>
<p>There you go!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Screenshot_20230519-092417.png" alt="Screenshot_20230519-092417" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-auto-delete-your-youtube-search-and-watch-histories">How to Auto-delete your YouTube Search and Watch Histories</h2>
<p><strong>Step 1</strong>: On the YouTube website, select the hamburger icon and then click "History":</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss2-3.png" alt="ss2-3" width="600" height="400" loading="lazy"></p>
<p><strong>Step 2</strong>: Click "Manage all history":</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss3-2.png" alt="ss3-2" width="600" height="400" loading="lazy"></p>
<p><strong>Step 3</strong>: On the next page, select "Auto delete (36 months)":</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss10.png" alt="ss10" width="600" height="400" loading="lazy"></p>
<p><strong>Step 4</strong>: Choose whether you want to auto-delete after every 3 months, 18 months, or 36 months, then click "Next":</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss11.png" alt="ss11" width="600" height="400" loading="lazy"></p>
<p>That's it!</p>
<h2 id="heading-how-to-pause-your-youtube-search-and-watch-histories">How to Pause your YouTube Search and Watch Histories</h2>
<p>You can stop YouTube from saving your search and watch histories. Follow the steps below to do that:</p>
<p><strong>Step 1</strong>: On the YouTube history page, select "Saving your YouTube history":</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss12.png" alt="ss12" width="600" height="400" loading="lazy"></p>
<p><strong>Step 2</strong>: On the next page, select "TURN OFF":</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss13.png" alt="ss13" width="600" height="400" loading="lazy"></p>
<p><strong>Step 3</strong>: Select "Pause":</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss14.png" alt="ss14" width="600" height="400" loading="lazy"></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>YouTube automatically saves your search and watch histories in order to keep showing you what they feel you like to watch. But sometimes you wonder why they know so much about you, and you might start worrying about your privacy.</p>
<p>In the same vein, there are times you get recommendations you don't like all because you once stumbled on a video that doesn’t align with your current needs.</p>
<p>That's why I put this article together to help you clear your search and watch histories, auto-delete them, and pause them.</p>
<p>Thank you for reading!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ RegEx for Date Formats – Regular Expressions for Matching Dates ]]>
                </title>
                <description>
                    <![CDATA[ Regular expressions let you match any string, be it in the form of various user inputs such as username, password, URL, and even different date formats. In this article, I’ll show you several ways you can match a date with regular expressions. In the... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/regex-for-date-formats-what-is-the-regular-expression-for-matching-dates/</link>
                <guid isPermaLink="false">66adf1f36f5e63db3fc43643</guid>
                
                    <category>
                        <![CDATA[ Regex ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Thu, 18 May 2023 12:41:17 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/dateRegEx.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Regular expressions let you match any string, be it in the form of various user inputs such as username, password, URL, and even different date formats.</p>
<p>In this article, I’ll show you several ways you can match a date with regular expressions.</p>
<p>In the programming world, there are always multiple ways of doing the same thing. So, how I’ll show you how to match date formats with regex might be different from how you’ll see it elsewhere.</p>
<h2 id="heading-what-well-cover">What We'll Cover</h2>
<ul>
<li><a class="post-section-overview" href="#heading-how-to-match-dates-with-regular-expressions">How to Match Dates with Regular Expressions</a><ul>
<li><a class="post-section-overview" href="#heading-how-to-match-dates-with-regular-expressions-example-1">How to Match Dates with Regular Expressions – Example 1</a></li>
<li><a class="post-section-overview" href="#heading-how-to-match-dates-with-regular-expressions-example-2">How to Match Dates with Regular Expressions – Example 2</a></li>
<li><a class="post-section-overview" href="#heading-how-to-match-dates-with-regular-expressions-example-3">How to Match Dates with Regular Expressions – Example 3</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<h2 id="heading-how-to-match-dates-with-regular-expressions">How to Match Dates with Regular Expressions</h2>
<p>Dates are usually numbers unless you format them with some programming tools. So, the characters I will use to match dates will be digit characters.</p>
<h3 id="heading-how-to-match-dates-with-regular-expressions-example-1">How to Match Dates with Regular Expressions – Example 1</h3>
<p>Let’s start with something less complex first. Assuming the date format is in <code>DD/MM/YYYY</code> or <code>MM/DD/YYYY</code>, this would work:</p>
<pre><code class="lang-bash">\d{1,2}\/\d{1,2}\/\d{2,4}
</code></pre>
<p>In the regex above:</p>
<ul>
<li><code>\d{1,2}</code> matches 1 or 2 digits</li>
<li><code>\/</code> matches a slash (the separator). You can also make a hyphen (-) the separator</li>
<li>\d{2,4} matches 2 or 4 digits</li>
</ul>
<p>Indeed, the pattern matches a date:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Screenshot-2023-05-18-at-11.08.02.png" alt="Screenshot-2023-05-18-at-11.08.02" width="600" height="400" loading="lazy"> </p>
<p>But that pattern is too generic because we don’t know which is which between the date and the month. The year can also be 2 or 4 digits. </p>
<p>In short, anything that is not a valid date would go:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Screenshot-2023-05-18-at-11.11.10.png" alt="Screenshot-2023-05-18-at-11.11.10" width="600" height="400" loading="lazy"> </p>
<p>That’s not how you want to match a date. I’ll show you a better pattern next.</p>
<h3 id="heading-how-to-match-dates-with-regular-expressions-example-2">How to Match Dates with Regular Expressions – Example 2</h3>
<p>Here’s another pattern that can match a date:</p>
<pre><code class="lang-bash">(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0,1,2])\/(19|20)\d{2}
</code></pre>
<p>In the pattern above: </p>
<ul>
<li><code>(0[1-9]|[12][0-9]|3[01])</code> is the first group of the pattern and it lets you specify the date only between <code>01</code> and <code>31</code></li>
<li><code>\/</code> is the separator</li>
<li><code>(0[1-9]|1[0,1,2])</code> represents the month and it lets you specify it between <code>01</code> and <code>12</code></li>
<li><code>\/</code> is another separator</li>
<li><code>(19|20)\d{2}</code> represents the year which can be between 1900 and any 2000 year</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Screenshot-2023-05-18-at-11.37.38.png" alt="Screenshot-2023-05-18-at-11.37.38" width="600" height="400" loading="lazy"> </p>
<p>You can replace the separator with any hyphen this way:</p>
<pre><code class="lang-bash">(0[1-9]|[12][0-9]|3[01])-(0[1-9]|1[1,2])-(19|20)\d{2}
</code></pre>
<p>And you can accept both forward slash and hyphen as a separator:</p>
<pre><code class="lang-bash">(0[1-9]|[12][0-9]|3[01])(\/|-)(0[1-9]|1[1,2])(\/|-)(19|20)\d{2}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Screenshot-2023-05-18-at-11.41.32.png" alt="Screenshot-2023-05-18-at-11.41.32" width="600" height="400" loading="lazy"></p>
<p>You can also rearrange the pattern to be in the <code>MM/DD/YYYY</code> format this way:</p>
<pre><code class="lang-bash">(0[1-9]|1[1,2])(\/|-)(0[1-9]|[12][0-9]|3[01])(\/|-)(19|20)\d{2}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Screenshot-2023-05-18-at-11.46.46.png" alt="Screenshot-2023-05-18-at-11.46.46" width="600" height="400" loading="lazy"></p>
<h3 id="heading-how-to-match-dates-with-regular-expressions-example-3">How to Match Dates with Regular Expressions – Example 3</h3>
<p>Many times, you’ll be accepting just one date in your input. In that case, you have to specify the start and end of a string with caret (<code>^</code>) and dollar sign (<code>$</code>).</p>
<p>This is how I came with that pattern:</p>
<pre><code class="lang-bash">^(3[01]|[12][0-9]|0?[1-9])(\/|-)(1[0-2]|0?[1-9])\2([0-9]{2})?[0-9]{2}$
</code></pre>
<p>And here’s what the pattern does:</p>
<ul>
<li><code>^</code> denotes the start of the string</li>
<li><code>(3[01]|[12][0-9]|0?[1-9])</code> represents the day<ul>
<li><code>3[01]</code> matches numbers from <code>30</code> to <code>31</code></li>
<li><code>[12][0-9]</code> matches numbers from <code>10</code> to <code>29</code></li>
<li><code>0?[1-9]</code> matches numbers from <code>1</code> to <code>9</code>, with an optional leading zero</li>
</ul>
</li>
<li><code>(\/|-)</code> matches either a forward slash (<code>/</code>) or a hyphen (<code>-</code>)</li>
<li><code>(1[0-2]|0?[1-9])</code> represents the month part<ul>
<li><code>1[0-2]</code> matches numbers from <code>10</code> to <code>12</code></li>
<li><code>0?[1-9]</code> matches numbers from <code>1</code> to <code>9</code>, with an optional leading zero</li>
</ul>
</li>
<li><code>\2</code> is a backreference that matches the same delimiter captured in the second capturing group <code>(\/|-)</code>. This ensures that the delimiter between day and month is consistent</li>
<li><code>([0-9]{2})?</code> matches the two-digit year part optionally</li>
<li><code>([0-9]{2})</code> matches any two digits representing a year</li>
<li><code>[0-9]{2}</code> matches the last two digits of the year</li>
<li><code>$</code> denotes the end of the string</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This article took you through how to match a date with regular expressions with three examples.</p>
<p>The first example is a bit generic and won’t do well in matching a date, but the second can match valid dates in an input. The third does it better as it is tailored for a valid and single date – which would likely be what you want to do.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Regular Expressions in YAML File – RegEx in YAML Tutorial ]]>
                </title>
                <description>
                    <![CDATA[ YAML does not have built-in support for regular expressions. But you can still include regex patterns as part of a YAML file's contents, access those patterns, and create a regex out of them. You can do this, for example, with the JavaScript RegExp c... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-regular-expressions-in-yaml-file/</link>
                <guid isPermaLink="false">66adf1506f5e63db3fc43620</guid>
                
                    <category>
                        <![CDATA[ Regex ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Regular Expressions ]]>
                    </category>
                
                    <category>
                        <![CDATA[ YAML ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Wed, 17 May 2023 14:48:51 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/yamlRe.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>YAML does not have built-in support for regular expressions. But you can still include regex patterns as part of a YAML file's contents, access those patterns, and create a regex out of them.</p>
<p>You can do this, for example, with the JavaScript <code>RegExp</code> constructor.</p>
<p>So, in YAML, regular expressions are typically represented as strings, using a specific syntax to define the pattern. For example, a YAML key-value pair that includes a regular expression pattern might look like this:</p>
<pre><code class="lang-bash">example:
pattern: ^[A-Za-z]+$
</code></pre>
<p>In this article, I'll show you how to write regular expressions inside a YAML file and access its entries in a JavaScript file. Let's take a look at what the YAML file is first.</p>
<h2 id="heading-what-well-cover">What We'll Cover</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-is-a-yaml-file">What is a YAML File?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-write-regular-expressions-in-a-yaml-file">How to Write Regular Expressions in a YAML File</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-import-a-yaml-file-in-javascript-and-use-it">How to Import a YAML File in JavaScript and Use it</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-what-is-a-yaml-file">What is a YAML File?</h2>
<p>YAML stands for YAML ain't markup language. It is a human and machine-readable data serialization file format. It is often used as configuration files, for data exchange, and for representing structured data in DevOps engineering.</p>
<p>YAML files use indentation and a concise syntax to define data structures such as lists, dictionaries (key-value pairs), and scalars (strings, numbers, booleans).</p>
<p>Each entry in a YAML file can be string, number, or Boolean, and other YAML-specific data types like scalars and lists. Here's a YAML file containing those data types:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># YAML Data Types Example</span>
<span class="hljs-comment"># -----------------------</span>

<span class="hljs-comment"># Scalars</span>
null_example: null           <span class="hljs-comment"># Null Scalar</span>
bool_example: <span class="hljs-literal">true</span>           <span class="hljs-comment"># Boolean Scalar</span>
int_example: 42              <span class="hljs-comment"># Integer Scalar</span>
float_example: 3.14          <span class="hljs-comment"># Float Scalar</span>
str_example: <span class="hljs-string">"Hello, YAML!"</span>  <span class="hljs-comment"># String Scalar</span>

<span class="hljs-comment"># Sequences (Arrays)</span>
seq_example:                 <span class="hljs-comment"># Sequence (Array)</span>
  - Apple
  - Orange
  - Banana

<span class="hljs-comment"># Mappings (Dictionaries)</span>
map_example:                 <span class="hljs-comment"># Mapping (Dictionary)</span>
  key1: value1
  key2: value2
  key3: value3

<span class="hljs-comment"># List (Sequence of Mappings)</span>
list_example:                <span class="hljs-comment"># List of Mappings (Sequence of Dictionaries)</span>
  - name: John
    age: 30
  - name: Jane
    age: 28
  - name: Bob
    age: 35
</code></pre>
<p>You can also put regular expressions right inside a YAML file. And that's what we'll look at next.</p>
<h2 id="heading-how-to-write-regular-expressions-in-a-yaml-file">How to Write Regular Expressions in a YAML File</h2>
<p>You can represent specific values in a YAML file as regular expressions. Below are some validation regex patterns:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># validator.yaml file</span>
password:
  pattern: ^(?!.*[\s])(?=.*[A-Z])(?=.*[a-z])(?=.*\d)[A-Za-z\d@$!%*<span class="hljs-comment">#?&amp;]{8,}$</span>
  description: |
    - At least 8 characters
    - At least one uppercase letter
    - At least one lowercase letter
    - At least one digit
    - Allowed special characters: @$!%*<span class="hljs-comment">#?&amp;</span>

nigerianPhoneNumber:
  pattern: ^(\+?234|0)[789]\d{9}$
  description: |
    - Nigerian phone number format
    - Starts with +234 or 0
    - Followed by 7, 8, or 9
    - Total of 11 digits

email:
  pattern: ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$
  description: |
    - Valid email address format
    - Example: example@example.com

username:
  pattern: ^[a-zA-Z0-9_-]{3,16}$
  description: |
    - Allowed characters: letters (upper and lower <span class="hljs-keyword">case</span>), numbers, underscore (_), and hyphen (-)
    - Minimum length: 3 characters
    - Maximum length: 16 characters
</code></pre>
<p>You can then import the YAML file into your JavaScript file and do what you want with it – for instance, create regular expressions out of those patterns and use them.</p>
<p>But that process is not straightforward. So that's the next thing you'll learn in this article.</p>
<h2 id="heading-how-to-import-a-yaml-file-in-javascript-and-use-it">How to Import a YAML File in JavaScript and Use it</h2>
<p>If you attempt to import any YAML file into a JavaScript file with the <code>import</code> syntax, like <code>import abc from file.yaml</code>, this is the kind of error you'll get:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/reYamlErr.png" alt="reYamlErr" width="600" height="400" loading="lazy"></p>
<p>Instead of doing it that way, you should create a <code>package.json</code> in your project directory by running <code>npm init -y</code> and install the <code>js-yaml</code> package by running <code>npm install js-yaml</code>.</p>
<p>After that, import the <code>fs</code> module of Node.js and the <code>js-yaml</code> package this way:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
<span class="hljs-keyword">const</span> yaml = <span class="hljs-built_in">require</span>(<span class="hljs-string">'js-yaml'</span>);
</code></pre>
<p>The next thing you should do is read the <code>validator.yaml</code> file with the <code>readFileSync</code> method of the <code>fs</code> module and parse the YAML file with the <code>load()</code> method:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> yamlData = fs.readFileSync(<span class="hljs-string">'validator.yaml'</span>, <span class="hljs-string">'utf8'</span>);
<span class="hljs-keyword">const</span> parsedData = yaml.load(yamlData);
</code></pre>
<p>All that's left to do is to access any of the patterns, create a RegEx out of it, and use it. This is how I used the password pattern:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> passwordPattern = parsedData.password.pattern;
<span class="hljs-keyword">const</span> pwordValidator = <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(passwordPattern);

<span class="hljs-keyword">const</span> myPassword = <span class="hljs-string">'reallyStrongPassword21!'</span>;
<span class="hljs-built_in">console</span>.log(pwordValidator.test(myPassword)); <span class="hljs-comment">//true</span>
</code></pre>
<p>Here's how I used the Nigerian phone number validator pattern:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> phonePattern = parsedData.nigerianPhoneNumber.pattern;

phoneValidator = <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(phonePattern);

<span class="hljs-keyword">const</span> myPhoneNum = <span class="hljs-string">'08133333333'</span>;
<span class="hljs-built_in">console</span>.log(phoneValidator.test(myPhoneNum)); <span class="hljs-comment">//true;</span>
</code></pre>
<p>Here's the full code:</p>
<pre><code class="lang-js"><span class="hljs-comment">// import the fs module to be able to access the YAML file</span>
<span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);

<span class="hljs-comment">// import the YAML package</span>
<span class="hljs-keyword">const</span> yaml = <span class="hljs-built_in">require</span>(<span class="hljs-string">'js-yaml'</span>);

<span class="hljs-comment">// Read the validator.yaml file with the FS module</span>
<span class="hljs-keyword">const</span> yamlData = fs.readFileSync(<span class="hljs-string">'test.yaml'</span>, <span class="hljs-string">'utf8'</span>);

<span class="hljs-comment">// parse the YAML file</span>
<span class="hljs-keyword">const</span> parsedData = yaml.load(yamlData);

<span class="hljs-comment">// Access the password validator pattern from the YAML file</span>
<span class="hljs-keyword">const</span> passwordPattern = parsedData.password.pattern;

<span class="hljs-comment">// Create a regex out of the password pattern</span>
<span class="hljs-keyword">const</span> pwordValidator = <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(passwordPattern);

<span class="hljs-keyword">const</span> myPassword = <span class="hljs-string">'reallyStrongPassword21!'</span>;
<span class="hljs-built_in">console</span>.log(pwordValidator.test(myPassword)); <span class="hljs-comment">//true</span>

<span class="hljs-comment">// Access the nigeriaPhoneNumber validator pattern from the YAML file</span>
<span class="hljs-keyword">const</span> phonePattern = parsedData.nigerianPhoneNumber.pattern;

<span class="hljs-comment">// Create a regex out of the phonePAttern</span>
phoneValidator = <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(phonePattern);

<span class="hljs-keyword">const</span> myPhoneNum = <span class="hljs-string">'08133333333'</span>;
<span class="hljs-built_in">console</span>.log(phoneValidator.test(myPhoneNum)); <span class="hljs-comment">//true;</span>

<span class="hljs-comment">// Access the email validator pattern from the YAML file</span>
<span class="hljs-keyword">const</span> emailPattern = parsedData.email.pattern;

<span class="hljs-comment">// Create a regex out of the phonePAttern</span>
emailValidator = <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(emailPattern);

<span class="hljs-keyword">const</span> emailAddress = <span class="hljs-string">'chris@gmail.com'</span>;
<span class="hljs-built_in">console</span>.log(emailValidator.test(emailAddress)); <span class="hljs-comment">//false;</span>

<span class="hljs-comment">// Access the username validator pattern from the YAML file</span>
<span class="hljs-keyword">const</span> usernamePattern = parsedData.username.pattern;

<span class="hljs-comment">// Create a regex out of the phonePAttern</span>
usernameValidator = <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(usernamePattern);

<span class="hljs-keyword">const</span> username = <span class="hljs-string">'ksound22'</span>;
<span class="hljs-built_in">console</span>.log(usernameValidator.test(username)); <span class="hljs-comment">//false;</span>
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This article showed you how to put regular expressions in a YAML file, import it into a JavaScript file with the <code>js-yaml</code> package, and access any of the values in it.</p>
<p>We also looked at how you can create regular expressions out of the patterns in the YAML file and test them with some strings.</p>
<p>Thanks for reading. If you find the article helpful, kindly share it with your friends and family.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ URL RegEx Pattern – How to Write a Regular Expression for a URL ]]>
                </title>
                <description>
                    <![CDATA[ Regular expressions provide a powerful and flexible way to define patterns and match specific strings, be it usernames, passwords, phone numbers, or even URLs. In this article, I'll show you the fundamentals of crafting a regular expression for URLs.... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-write-a-regular-expression-for-a-url/</link>
                <guid isPermaLink="false">66adf152db5636c0b30cba7d</guid>
                
                    <category>
                        <![CDATA[ Regex ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Mon, 15 May 2023 12:22:48 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/urlRegEx.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Regular expressions provide a powerful and flexible way to define patterns and match specific strings, be it usernames, passwords, phone numbers, or even URLs.</p>
<p>In this article, I'll show you the fundamentals of crafting a regular expression for URLs. Whether you need to validate user input, extract components from URLs, or perform any other URL-related tasks, understanding how to construct a regex for URLs can greatly enhance URL validation in your applications.</p>
<p>First, let me show you what a URL is.</p>
<h2 id="heading-what-well-cover">What We'll Cover</h2>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-a-url">What is a URL?</a></li>
<li><a class="post-section-overview" href="#heading-how-to-write-a-regular-expression-for-a-url">How to Write a Regular Expression for a URL</a></li>
<li><a class="post-section-overview" href="#heading-testing-the-regex-with-javascript">Testing the RegEx with JavaScript</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<h2 id="heading-what-is-a-url">What is a URL?</h2>
<p>A URL, short for Uniform Resource Locator, is a string that identifies the location of a resource on the web. It typically consists of various components, including:</p>
<ul>
<li>the protocol – for instance, HTTP or HTTPS</li>
<li>domain name – for example, freecodecamp.org</li>
<li>subdomain – for example, Chinese.freecodecamp.org</li>
<li>port number – 3000, 5000, 4000, and more</li>
<li>path – for example, <code>freecodecamp.org/news</code></li>
<li>query parameters – for example, <code>https://example.com/search?q=apple&amp;category=fruits</code></li>
</ul>
<h2 id="heading-how-to-write-a-regular-expression-for-a-url">How to Write a Regular Expression for a URL</h2>
<p>A URL can be a base URL (without a subdomain, path, or query param). It can also contain a subdomain, path, or other components. Due to this, you have to tailor your regular expression to the way you're expecting the URL.</p>
<p>If the users are typing in a base URL, you have to tailor your regex fir that, and if you're expecting a URL that has a subdomain or path, you have to tailor your regex that way. If you like, you can also write a complex regex that can accept a URL in any form it can come. It is not impossible.</p>
<p>Here's a regex pattern that matches a base URL of any domain extension:</p>
<pre><code class="lang-bash">(https:\/\/www\.|http:\/\/www\.|https:\/\/|http:\/\/)?[a-zA-Z0-9]{2,}(\.[a-zA-Z0-9]{2,})(\.[a-zA-Z0-9]{2,})?
</code></pre>
<p>This would match domains like <code>https://www.freecodecamp.org</code>, <code>http://www.freecodecamp.org/</code>, <code>freeCodeCamp.org</code>, <code>google.co.uk</code>, <code>facebook.net</code>, <code>google.com.ng</code>, <code>google.com.in</code>, and many other base URLs.</p>
<p>The pattern below matches any URL with a path:</p>
<pre><code class="lang-bash">(https:\/\/www\.|http:\/\/www\.|https:\/\/|http:\/\/)?[a-zA-Z0-9]{2,}(\.[a-zA-Z0-9]{2,})(\.[a-zA-Z0-9]{2,})?\/[a-zA-Z0-9]{2,}
</code></pre>
<p>This include URLs like <code>https://www.freecodecamp.org/news</code>,
<code>http://www.freecodecamp.org/ukrainian</code>, and others</p>
<p>If you want to match a URL with a subdomain, the pattern below can do it for you:</p>
<pre><code class="lang-js">(https:\/\/www\.|http:\/\/www\.|https:\/\/|http:\/\/)?[a-zA-Z0<span class="hljs-number">-9</span>]{<span class="hljs-number">2</span>,}\.[a-zA-Z0<span class="hljs-number">-9</span>]{<span class="hljs-number">2</span>,}\.[a-zA-Z0<span class="hljs-number">-9</span>]{<span class="hljs-number">2</span>,}(\.[a-zA-Z0<span class="hljs-number">-9</span>]{<span class="hljs-number">2</span>,})?
</code></pre>
<p>This would match subdomains like <code>https://www.chinese.freecodecamp.org</code>,
<code>chinese.freecodecamp.org</code>, <code>https://chinese.freecodecamp.org</code>, and others.</p>
<p>If you want a regex that matches any URL that is base, has a subdomain, or a path, you can combine all the patterns I've shown you like this:</p>
<pre><code class="lang-bash">(https:\/\/www\.|http:\/\/www\.|https:\/\/|http:\/\/)?[a-zA-Z]{2,}(\.[a-zA-Z]{2,})(\.[a-zA-Z]{2,})?\/[a-zA-Z0-9]{2,}|((https:\/\/www\.|http:\/\/www\.|https:\/\/|http:\/\/)?[a-zA-Z]{2,}(\.[a-zA-Z]{2,})(\.[a-zA-Z]{2,})?)|(https:\/\/www\.|http:\/\/www\.|https:\/\/|http:\/\/)?[a-zA-Z0-9]{2,}\.[a-zA-Z0-9]{2,}\.[a-zA-Z0-9]{2,}(\.[a-zA-Z0-9]{2,})?
</code></pre>
<p>Not the prettiest way to do things, but it works:
<img src="https://www.freecodecamp.org/news/content/images/2023/05/ss1-5.png" alt="ss1-5" width="600" height="400" loading="lazy"></p>
<h2 id="heading-testing-the-regex-with-javascript">Testing the RegEx with JavaScript</h2>
<p>On testing the regex using the <code>test()</code> method of JavaScript RegEx, I got <code>true</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> pattern =
  <span class="hljs-regexp">/(https:\/\/www\.|http:\/\/www\.|https:\/\/|http:\/\/)?[a-zA-Z]{2,}(\.[a-zA-Z]{2,})(\.[a-zA-Z]{2,})?\/[a-zA-Z0-9]{2,}|((https:\/\/www\.|http:\/\/www\.|https:\/\/|http:\/\/)?[a-zA-Z]{2,}(\.[a-zA-Z]{2,})(\.[a-zA-Z]{2,})?)|(https:\/\/www\.|http:\/\/www\.|https:\/\/|http:\/\/)?[a-zA-Z0-9]{2,}\.[a-zA-Z0-9]{2,}\.[a-zA-Z0-9]{2,}(\.[a-zA-Z0-9]{2,})?/g</span>;

<span class="hljs-keyword">const</span> urls = <span class="hljs-string">`https://www.freecodecamp.org
http://www.freecodecamp.org
google.co.uk
facebook.net
google.com.ng
google.com.in
freecodecamp.org
yoruba.freecodecamp.org
freecodecamp.org/yoruba

http://www.freecodecamp.org/news
freecodecamp.org/news

chinese.freecodecamp.org
https://chinese.freecodecamp.org`</span>;

<span class="hljs-built_in">console</span>.log(pattern.test(urls)); <span class="hljs-comment">//true;</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss2-2.png" alt="ss2-2" width="600" height="400" loading="lazy"></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The regular expression patterns for matching a URL depend on your specific need – since URLs can be in various forms. So, while writing the patterns for the URL, you have to write them to suit the way you expect the URL.</p>
<p>Writing a regex that matches all kinds of URLs works, but it's not the best way to because it's very hard to read and debug.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Smart Quotes – Single Quote and Double Quotation Mark for Copy + Paste ]]>
                </title>
                <description>
                    <![CDATA[ Smart quotes are commonly used punctuation marks in HTML and in writing. Knowing how to use them correctly can make a significant difference in the clarity and professionalism of your writing.  So in this article, you will get access to the commonly ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/smart-quotes-single-quote-and-double-quotation-mark-for-copy-paste/</link>
                <guid isPermaLink="false">66adf2146992d2a84c5d7942</guid>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technical writing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ writing ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Wed, 10 May 2023 14:31:24 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/smartQuotes-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Smart quotes are commonly used punctuation marks in HTML and in writing. Knowing how to use them correctly can make a significant difference in the clarity and professionalism of your writing. </p>
<p>So in this article, you will get access to the commonly used quotation marks out there that you can copy and paste them into your articles, papers, and HTML.</p>
<p>It doesn’t end there. You will get access to the Unicode characters, HTML entities, and CSS entities of all the smart quotes. Make sure you check the end of this article so you can learn how to use the HTML and CSS entities and Unicode characters of the smart quotes.</p>
<p>Before showing you a table containing all the smart quotes, let's see how to use them in HTML and CSS first.</p>
<h2 id="heading-what-well-cover">What We'll Cover</h2>
<ul>
<li><a class="post-section-overview" href="#heading-how-to-use-smart-quotes-quotation-marks-in-html-and-css">How to Use Smart Quotes (Quotation Marks) in HTML and CSS</a></li>
<li><a class="post-section-overview" href="#heading-table-of-smart-quotes-their-unicode-characters-html-and-css-codes">Table of Smart Quotes, their Unicode Characters, HTML, and CSS Codes</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<h2 id="heading-how-to-use-smart-quotes-quotation-marks-in-html-and-css">How to Use Smart Quotes (Quotation Marks) in HTML and CSS</h2>
<p>To use smart quotes in HTML and CSS, you need their Unicode characters. For instance, the Unicode for quotation marks is <code>U+0022</code>. So, to use it in HTML, strip out the <code>U+</code> part, prepend the other letters or numbers with <code>&amp;#x</code>, and end them with semicolon (<code>;</code>) like this:</p>
<pre><code class="lang-bash">&amp;<span class="hljs-comment">#x0022;</span>
</code></pre>
<p>That translates to this: "</p>
<p>In CSS, you need to strip out the <code>U+</code> part again and replace them with a backslash (<code>\</code>). So this is how you'd use a quotation mark in CSS:</p>
<pre><code class="lang-bash">\0022
</code></pre>
<p>But there's a caveat to using Unicode characters in CSS. To make them visible on a web page, you need to create a pseudo-element and make the Unicode character the content:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">element</span><span class="hljs-selector-pseudo">::after</span> {
  <span class="hljs-attribute">content</span>: <span class="hljs-string">'\0022'</span>;
}
</code></pre>
<h2 id="heading-table-of-smart-quotes-their-unicode-characters-html-and-css-codes">Table of Smart Quotes, their Unicode Characters, HTML, and CSS Codes</h2>
<p>The table below contains the quotation marks available for use in HTML and other writings:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Quotation Mark Name</td><td>Symbol</td><td>Unicode</td><td>HTML Code</td><td>CSS Code</td></tr>
</thead>
<tbody>
<tr>
<td>Quotation Mark</td><td><code>"</code></td><td><code>U+0022</code></td><td><code>&amp;#x0022</code></td><td><code>\0022</code></td></tr>
<tr>
<td>Single High Reversed Quotation Mark</td><td><code>‛</code></td><td><code>U+201B</code></td><td><code>&amp;#x201B</code></td><td><code>\201B</code></td></tr>
<tr>
<td>Double High Reversed Quotation Mark</td><td><code>‟</code></td><td><code>U+201F</code></td><td><code>&amp;#x201F</code></td><td><code>\201F</code></td></tr>
<tr>
<td>Full Width Quotation Mark</td><td><code>＂</code></td><td><code>U+FF02</code></td><td><code>&amp;#xFF02</code></td><td><code>\FF02</code></td></tr>
<tr>
<td>Right Single Quotation Mark</td><td><code>’</code></td><td><code>U+2019</code></td><td><code>&amp;#x2019</code></td><td><code>\2019</code></td></tr>
<tr>
<td>Left Single Quotation Mark</td><td><code>‘</code></td><td><code>U+2018</code></td><td><code>&amp;#x2018</code></td><td><code>\2018</code></td></tr>
<tr>
<td>Single Low Quotation Mark</td><td><code>‚</code></td><td><code>U+201A</code></td><td><code>&amp;#x201A</code></td><td><code>\201A</code></td></tr>
<tr>
<td>Double Prime Quotation Mark</td><td><code>〞</code></td><td><code>U+301E</code></td><td><code>&amp;#x301E</code></td><td><code>\301E</code></td></tr>
<tr>
<td>Reversed Double Prime Quotation Mark</td><td><code>〝</code></td><td><code>U+301D</code></td><td><code>&amp;#x301D</code></td><td>\301D</td></tr>
<tr>
<td>Low Double Prime Quotation Mark</td><td><code>〟</code></td><td><code>U+301F</code></td><td><code>&amp;#x301F</code></td><td><code>\301F</code></td></tr>
<tr>
<td>Right Double Quotation Mark</td><td><code>”</code></td><td><code>U+201D</code></td><td><code>&amp;#x201D</code></td><td><code>\201D</code></td></tr>
<tr>
<td>Left Double Quotation Mark</td><td><code>“</code></td><td><code>U+201C</code></td><td><code>&amp;#x201C</code></td><td><code>\201C</code></td></tr>
<tr>
<td>Double Low Quotation Mark</td><td><code>„</code></td><td><code>U+201E</code></td><td><code>&amp;#x201E</code></td><td><code>\201E</code></td></tr>
<tr>
<td>Double Low Reversed Quotation Mark</td><td><code>⹂</code></td><td><code>U+2E42</code></td><td><code>&amp;#x2E42</code></td><td><code>\2E42</code></td></tr>
<tr>
<td>Heavy Right Pointing Angle Quotation Mark Ornament</td><td><code>❯</code></td><td><code>U+276F</code></td><td><code>&amp;#x276F</code></td><td><code>\276F</code></td></tr>
<tr>
<td>Heavy Left Pointing Angle Quotation Mark Ornament</td><td><code>❮</code></td><td><code>U+276E</code></td><td><code>&amp;#x27CE</code></td><td><code>\27CE</code></td></tr>
<tr>
<td>Single Right Pointing Angle Quotation Mark</td><td><code>›</code></td><td><code>U+203A</code></td><td><code>&amp;#x203A</code></td><td><code>\203A</code></td></tr>
<tr>
<td>Single Left Pointing Angle Quotation Mark</td><td><code>‹</code></td><td><code>U+2039</code></td><td><code>&amp;#x2039</code></td><td><code>\2039</code></td></tr>
<tr>
<td>Heavy Low Single Comma Quotation Mark Ornament</td><td><code>❟</code></td><td><code>U+275F</code></td><td><code>&amp;#x275F</code></td><td><code>\275F</code></td></tr>
<tr>
<td>Heavy Single Comma Quotation Mark Ornament</td><td><code>❜</code></td><td><code>U+275C</code></td><td><code>&amp;#x275C</code></td><td><code>\275C</code></td></tr>
<tr>
<td>Heavy Single Turned Comma Quotation Mark Ornament</td><td><code>❛</code></td><td><code>U+275B</code></td><td><code>&amp;#x275B</code></td><td><code>\275B</code></td></tr>
<tr>
<td>Heavy Double Turned Comma Quotation Mark Ornament</td><td><code>❝</code></td><td><code>U+275D</code></td><td><code>&amp;#x275D</code></td><td><code>\275D</code></td></tr>
<tr>
<td>Heavy Double Comma Quotation Mark Ornament</td><td><code>❞</code></td><td><code>U+275E</code></td><td><code>&amp;#x275E</code></td><td><code>\275E</code></td></tr>
<tr>
<td>Right Pointing Double Angle Quotation Mark</td><td><code>»</code></td><td><code>U+00BB</code></td><td><code>&amp;#x00BB</code></td><td><code>\00BB</code></td></tr>
<tr>
<td>Left Pointing Double Angle Quotation Mark</td><td><code>«</code></td><td><code>U+00AB</code></td><td><code>&amp;#x00AB</code></td><td><code>\00AB</code></td></tr>
<tr>
<td>Full Width Apostrophe</td><td><code>＇</code></td><td><code>U+FF07</code></td><td><code>&amp;#xFF07</code></td><td><code>\FF07</code></td></tr>
</tbody>
</table>
</div><p>Note: if you have a Mac, you may not be able to see the "Double low revesed quotation mark" and the "Heavy low single comma quotation mark". Here's what they're supposed to look like:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Screenshot-2023-05-10-at-7.20.26-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Screenshot-2023-05-10-at-7.20.35-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I hope this article helps you learn about the smart quotes out there, and how to use them in your HTML and CSS files, and other writings.</p>
<p>Try to share the article with your friends and family so they can have access to the smart quotes.</p>
<p>Thank you.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Find and Replace in Notepad++ – How to Find String with Regular Expression in Notepad++ ]]>
                </title>
                <description>
                    <![CDATA[ Notepad++ has a Find feature with which you can search for any text in a file. But it doesn’t end there.  You can also use Notepad++'s Find and Replace feature to search for a text and replace it with a specified replacement. The Find and Find and Re... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-find-string-with-regular-expression-in-notepad-find-and-replace-in-notepad/</link>
                <guid isPermaLink="false">66adf1196778e7bd69427bfe</guid>
                
                    <category>
                        <![CDATA[ Regex ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Fri, 05 May 2023 13:21:02 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/findAndReplacewithRe.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Notepad++ has a <strong>Find</strong> feature with which you can search for any text in a file. But it doesn’t end there. </p>
<p>You can also use Notepad++'s <strong>Find and Replace</strong> feature to search for a text and replace it with a specified replacement.</p>
<p>The <strong>Find</strong> and <strong>Find and Replace</strong> features accept regular text, but they both also accept regular expressions.</p>
<p>Let's see how the <strong>Find</strong> and <strong>Find and Replace</strong> feature of Notepad++ works by using regular expressions instead of regular text.</p>
<h2 id="heading-how-to-find-a-string-with-regular-expressions-in-notepad">How to Find a String with Regular Expressions in Notepad++</h2>
<p>This is the code I'll use for this demo:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Find String with RegEx in Notepad++<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Find String with RegEx in Notepad++<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Lorem ipsum dolor sit.<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
      Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eius beatae
      dignissimos alias quo odit aperiam laborum accusamus ea maxime dolores?
    <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>Lorem ipsum dolor sit amet.<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Lorem ipsum dolor sit.<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Quae voluptatem
      perferendis iure laborum inventore ducimus harum saepe voluptatibus neque
      earum?
    <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>Lorem ipsum dolor sit amet.<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Lorem ipsum dolor sit.<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
      Lorem ipsum dolor, sit amet consectetur adipisicing elit. Magnam
      accusantium placeat dolore illo, quidem suscipit. Recusandae corrupti
      assumenda soluta libero!
    <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>Lorem ipsum dolor sit amet.<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Lorem ipsum dolor sit.<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
      Lorem ipsum dolor sit amet consectetur, adipisicing elit. Cupiditate
      officia rerum id inventore sunt deleniti quaerat quibusdam libero vero
      non?
    <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>Lorem ipsum dolor sit amet.<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Once you've opened your file in Notepad++, press <code>CTRL + H</code> to open the <strong>Find</strong> popup. Make sure you're in the <strong>Find</strong> tab because the <strong>Replace</strong> tab is what opens by default. </p>
<p>After that, select <strong>Regular expression</strong>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss1-3.png" alt="ss1-3" width="600" height="400" loading="lazy"> </p>
<p>Next, enter your regular expression in the search input. I want to search for all Heading elements, so I'll enter the regex <code>&lt;h(1|2|3|4|5|6)&gt;</code></p>
<p>After entering the regex, click the Find Next button. It may also appear as "Find":</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss2-1.png" alt="ss2-1" width="600" height="400" loading="lazy"> </p>
<p>To keep seeing the matches, you have to keep clicking the "Find Next" button. However, you can click the "Count" button to see all your matches:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss3-1.png" alt="ss3-1" width="600" height="400" loading="lazy"> </p>
<h2 id="heading-how-to-find-and-replace-a-string-with-regular-expressions-in-notepad">How to Find and Replace a String with Regular Expressions in Notepad++</h2>
<p>You can perform find and replace almost the same way. The only difference is that you select the "Replace" tab instead of "Find":</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss4-1.png" alt="ss4-1" width="600" height="400" loading="lazy"></p>
<p>The search regex gets automatically populated, so what you need to do here is specify what to replace the matches with and the click <strong>Replace</strong>. </p>
<p>Let's say I want to replace all headings with a <code>p</code> tag:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss5-2.png" alt="ss5-2" width="600" height="400" loading="lazy"> </p>
<p>Instead of clicking "Replace" repeatedly to replace the matches, you can click the "Replace All" button:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss6-1.png" alt="ss6-1" width="600" height="400" loading="lazy"> </p>
<p>I'm also going to find all the closing heading tags with this regex <code>&lt;\/h(1|2|3|4|5|6)&gt;</code> and replace them with closing <code>p</code> tags.</p>
<p>Now, this is what the code looks like:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Find String with RegEx in Notepad++<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Find String with RegEx in Notepad++<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Lorem ipsum dolor sit.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
      Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eius beatae
      dignissimos alias quo odit aperiam laborum accusamus ea maxime dolores?
    <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Lorem ipsum dolor sit amet.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Lorem ipsum dolor sit.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Quae voluptatem
      perferendis iure laborum inventore ducimus harum saepe voluptatibus neque
      earum?
    <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Lorem ipsum dolor sit amet.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Lorem ipsum dolor sit.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
      Lorem ipsum dolor, sit amet consectetur adipisicing elit. Magnam
      accusantium placeat dolore illo, quidem suscipit. Recusandae corrupti
      assumenda soluta libero!
    <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Lorem ipsum dolor sit amet.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Lorem ipsum dolor sit.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
      Lorem ipsum dolor sit amet consectetur, adipisicing elit. Cupiditate
      officia rerum id inventore sunt deleniti quaerat quibusdam libero vero
      non?
    <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Lorem ipsum dolor sit amet.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Find and Replace is a great feature that saves you a ton of time in Notepad++, especially if you have to replace text in a large file.</p>
<p>Since VS Code is the most popular code editor these days, it also has its own find and replaces feature you can access by pressing <code>CTRL + H</code>. And if you want to search with regex, you can press the <code>.*</code> button:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss7-1.png" alt="ss7-1" width="600" height="400" loading="lazy"></p>
<p>Thank you for reading. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ You're offline. Check your Connection. [How to Fix YouTube Error] ]]>
                </title>
                <description>
                    <![CDATA[ Have you ever logged on to YouTube to watch videos only to see the error, "You're offline. Check your Connection"?  This error can occur on both the YouTube website and the mobile apps for Android and iPhone. In the case of the mobile apps, you migh... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/youre-offline-check-your-connection-how-to-fix-youtube-error/</link>
                <guid isPermaLink="false">66adf2997550d4f37c2019df</guid>
                
                    <category>
                        <![CDATA[ error ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Thu, 04 May 2023 17:44:45 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/yt-error--1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Have you ever logged on to YouTube to watch videos only to see the error, "You're offline. Check your Connection"? </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ss1-2.png" alt="ss1-2" width="600" height="400" loading="lazy"></p>
<p>This error can occur on both the YouTube website and the mobile apps for Android and iPhone. In the case of the mobile apps, you might get the error "You're offline. Watch downloads without a connection." </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Screenshot_20230504-105247-1.png" alt="Screenshot_20230504-105247-1" width="600" height="400" loading="lazy"></p>
<p>That's because you have videos downloaded on that mobile app. If you don’t have downloaded videos, the error message is the same as you'd see on the web version of YouTube.</p>
<p>In this article, I'll show you how to fix the error on both PC and mobile phones so you can start watching your favorite videos on YouTube once again. But before that, let's look at what causes the error.</p>
<h2 id="heading-what-well-cover">What We'll Cover</h2>
<ul>
<li><a class="post-section-overview" href="#heading-what-causes-the-youre-offline-check-your-connection-youtube-error">What Causes the "You're offline. Check your Connection." YouTube Error?</a></li>
<li><a class="post-section-overview" href="#heading-how-to-fix-the-youre-offline-check-your-connection-youtube-error">How to Fix the "You're offline. Check your Connection." YouTube Error</a></li>
<li><a class="post-section-overview" href="#heading-how-to-fix-the-youre-offline-check-your-connection-youtube-error-on-a-computer">How to Fix the "You're offline. Check your Connection." YouTube Error on a Computer</a><ul>
<li><a class="post-section-overview" href="#heading-disable-your-ad-blocker">Disable your Ad Blocker</a></li>
<li><a class="post-section-overview" href="#heading-disable-your-virtual-private-network-vpn">Disable your Virtual Private Network (VPN)</a></li>
<li><a class="post-section-overview" href="#heading-flush-your-computers-dns-in-the-command-line">Flush your Computer's DNS in the Command Line</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-how-to-fix-the-youre-offline-check-your-connection-youtube-error-on-a-mobile-phone">How to Fix the "You're offline. Check your Connection." YouTube Error on a Mobile Phone</a><ul>
<li><a class="post-section-overview" href="#heading-update-the-youtube-mobile-app">Update the YouTube Mobile App </a></li>
<li><a class="post-section-overview" href="#heading-force-stop-and-clear-your-mobile-apps-cache-data">Force Stop and Clear your Mobile App's Cache Data</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion </a></li>
</ul>
<h2 id="heading-what-causes-the-youre-offline-check-your-connection-youtube-error">What Causes the "You're offline. Check your Connection." YouTube Error?</h2>
<p>Most errors you encounter online will contain error messages that tell you what went wrong and how to fix them. </p>
<p>In the case of this error, it is related to your internet connection. That's why a part of the error message says "You're offline". Therefore, the causes include:</p>
<ul>
<li>A poor or unstable network.</li>
<li>A faulty Wi-Fi adapter connection.</li>
<li>An outdated YouTube app or browser.</li>
<li>Corrupted cache data.</li>
</ul>
<p>The other part of the error message says "Check your connection". So make sure your internet connection is stable. </p>
<p>But your internet connection may not be the only reason for this error. Read on to see other solutions you can use to fix the error.</p>
<h2 id="heading-how-to-fix-the-youre-offline-check-your-connection-youtube-error">How to Fix the "You're offline. Check your Connection." YouTube Error</h2>
<p>Since the error is network-related, some <strong>quick fixes</strong> you can try include:</p>
<ul>
<li>Make sure your internet connection is good.</li>
<li>Refresh the YouTube website or tap retry in the YouTube mobile app.</li>
<li>Refresh the YouTube mobile app.</li>
<li>Restart the YouTube mobile app.</li>
<li>Clear your browser cache.</li>
<li>Make sure your PC or mobile phone is not in airplane mode.</li>
</ul>
<p>If all of the quick fixes above fail to work, then keep reading to see other solutions you can use to fix the error on both PC and mobile. </p>
<h2 id="heading-how-to-fix-the-youre-offline-check-your-connection-youtube-error-on-a-computer">How to Fix the "You're offline. Check your Connection." YouTube Error on a Computer</h2>
<h3 id="heading-disable-your-ad-blocker">Disable your Ad Blocker</h3>
<p>Ad blockers are software programs that prevent adverts from appearing on websites. They work by blocking the code that displays ads, such as images or videos, before they can be loaded in the browser. </p>
<p>While ad blockers can improve the user experience by removing annoying and intrusive ads, they can also interfere with some website functionalities, including YouTube.</p>
<p>So, disabling the ad blocker(s) on your computer might be enough to get YouTube working again.</p>
<h3 id="heading-disable-your-virtual-private-network-vpn">Disable your Virtual Private Network (VPN)</h3>
<p>A Virtual Private Network (VPN) can interfere with websites like YouTube and cause them not to work properly due to restrictions in the virtual server's location, configuration issues, network congestion, and so on.</p>
<p>So, just like disabling ad blockers, disabling your VPN can be a solution to the error.</p>
<h3 id="heading-flush-your-computers-dns-in-the-command-line">Flush your Computer's DNS in the Command Line</h3>
<p>Sometimes, clearing your browser's cache might not be enough to get rid of corrupted cache data because the cache might be on your computer itself. </p>
<p>In that case, you need to clear your computer's cache too. And flushing your DNS gets rid of it for you.</p>
<p>To flush your PC's DNS, open CMD and run the following commands one by one:</p>
<ul>
<li><code>ipconfig /flushdns</code></li>
<li><code>ipconfig /release</code></li>
<li><code>ipconfig /renew</code></li>
</ul>
<h2 id="heading-how-to-fix-the-youre-offline-check-your-connection-youtube-error-on-a-mobile-phone">How to Fix the "You're offline. Check your Connection." YouTube Error on a Mobile Phone</h2>
<h3 id="heading-update-the-youtube-mobile-app">Update the YouTube Mobile App</h3>
<p>If you use an Android device, head over to the Play Store and update the YouTube app if updates are available. And if you use an iPhone, you can download the latest version of the YouTube app on the iOS App Store.</p>
<p>But sometimes, the error occurs even if your mobile app is up to date. In that case, the next solution might fix it for you.</p>
<h3 id="heading-force-stop-and-clear-your-mobile-apps-cache-data">Force Stop and Clear your Mobile App's Cache Data</h3>
<p>On an Android phone, long-tap the YouTube app and select "App info":
<img src="https://www.freecodecamp.org/news/content/images/2023/05/Screenshot_20230504-115912-1.png" alt="Screenshot_20230504-115912-1" width="600" height="400" loading="lazy"></p>
<p>Tap on "Force stop":
<img src="https://www.freecodecamp.org/news/content/images/2023/05/Screenshot_20230504-1159361.png" alt="Screenshot_20230504-1159361" width="600" height="400" loading="lazy"></p>
<p>After that, select "Storage &amp; Cache":
<img src="https://www.freecodecamp.org/news/content/images/2023/05/Screenshot_20230504-115936-1.png" alt="Screenshot_20230504-115936-1" width="600" height="400" loading="lazy"></p>
<p>Tap on "Clear cache":
<img src="https://www.freecodecamp.org/news/content/images/2023/05/Screenshot_20230504-1159361-1.png" alt="Screenshot_20230504-1159361-1" width="600" height="400" loading="lazy"></p>
<p>If that fails to work, select "Clear storage" or reinstall the YouTube app.</p>
<p>On an iPhone, you can delete and reinstall the YouTube app and the cache data will go away.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This article showed you how to fix the YouTube error, "You're offline. Check your Connection." error on both the web version of YouTube and the mobile apps.</p>
<p>Some of the quick fixes might be enough to fix the error. But sometimes, fixing the error goes beyond those quick fixes. That's why I discussed other advanced fixes for the error.</p>
<p>Thank you for reading. If you found the article helpful, don’t hesitate to share it with your family and friends.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ XML Formatting in Notepad++ – How to Format XML Files ]]>
                </title>
                <description>
                    <![CDATA[ If you're working with XML files in Notepad++, formatting them manually could be a cumbersome task especially if the XML files are large. In this article, I will show you how to format your XML files in a few clicks. I will also show you how to check... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/xml-formatting-in-notepad-how-to-format-xml-files/</link>
                <guid isPermaLink="false">66adf295007ea266ef6d924e</guid>
                
                    <category>
                        <![CDATA[ xml ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Wed, 03 May 2023 12:41:46 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/Copy-of-matchPunctuationRegEx.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you're working with XML files in Notepad++, formatting them manually could be a cumbersome task especially if the XML files are large.</p>
<p>In this article, I will show you how to format your XML files in a few clicks. I will also show you how to check that the syntax of the XML files is in the right order and all tags are closed.</p>
<h2 id="heading-how-to-format-xml-files-in-notepad">How to Format XML Files in Notepad++</h2>
<p>You can see that the XML file below is not well formatted at all. With the file, I'll demonstrate how to format any XML file in Notepad++:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/unformattedxmlfile-1.gif" alt="unformattedxmlfile-1" width="600" height="400" loading="lazy"></p>
<p><strong>Step 1</strong>: Open your XML file with Notepad++ if you don't have it opened already:
<img src="https://www.freecodecamp.org/news/content/images/2023/05/ss1.png" alt="ss1" width="600" height="400" loading="lazy"> </p>
<p><strong>Step 2</strong>: In the menu bar, click on "Plugins" and select "Plugins Admin":
<img src="https://www.freecodecamp.org/news/content/images/2023/05/ss2.png" alt="ss2" width="600" height="400" loading="lazy"> </p>
<p><strong>Step 3</strong>: Search for "xml tools", checkmark it in the search results, click install, and select "Yes":
<img src="https://www.freecodecamp.org/news/content/images/2023/05/ss3.png" alt="ss3" width="600" height="400" loading="lazy"> </p>
<p>The plugin will be downloaded and Notepad++ will restart:
<img src="https://www.freecodecamp.org/news/content/images/2023/05/ss4.png" alt="ss4" width="600" height="400" loading="lazy"> </p>
<p><strong>Step 4</strong>: Click "Plugins" again in the menu bar, hover on "XML Tools", and click "Pretty print" to format the XML file:
<img src="https://www.freecodecamp.org/news/content/images/2023/05/ss5.png" alt="ss5" width="600" height="400" loading="lazy"> </p>
<p>Now, the XML file is well formatted:
<img src="https://www.freecodecamp.org/news/content/images/2023/05/formattedxmlfile.gif" alt="formattedxmlfile" width="600" height="400" loading="lazy"> </p>
<p>Alternatively, you can press <code>CTRL + ALT + SHIFT + B</code> to do the same thing.</p>
<h2 id="heading-how-to-check-xml-syntax-with-notepad">How to Check XML Syntax with Notepad++</h2>
<p>If your XML file is really large, the syntax might be bad, and some tags might be missing closing tags. </p>
<p>You can check the syntax with the same XML Tools plugin and it will suggest what you have to do if it finds that anything is wrong.</p>
<p>Again, click "Plugins", hover on "XML Tools" and select "Check XML syntax now":
<img src="https://www.freecodecamp.org/news/content/images/2023/05/ss6.png" alt="ss6" width="600" height="400" loading="lazy"> </p>
<p>Now, it's showing me I didn’t close one of the tags:
<img src="https://www.freecodecamp.org/news/content/images/2023/05/ss7.png" alt="ss7" width="600" height="400" loading="lazy"> </p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This article showed you how to format your XML files inside Notepad++ with the XML Tools plugin. As already stated, this can be useful if you have to work with large XML files inside Notepad++.</p>
<p>The XML Tools plugin is a great tool for working with XML files in Notepad++ as it gives you a good user experience with XML files. For more information, you can hover on it and see a couple of other useful things you can do with it.</p>
<p>Keep coding.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is Punct in RegEx? How to Match All Punctuation Marks in Regular Expressions ]]>
                </title>
                <description>
                    <![CDATA[ In regular expressions, "punct" means punctuation marks. It is all non-word and non-space characters. "Punct" is a predefined character class in regular expressions, and you can use it in any regex flavor that supports it.  The Punct character class ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-punct-in-regex-how-to-match-all-punctuation-marks-in-regular-expressions/</link>
                <guid isPermaLink="false">66adf280febac312b73075de</guid>
                
                    <category>
                        <![CDATA[ Regex ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Fri, 28 Apr 2023 11:28:37 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/04/matchPunctuationRegEx.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In regular expressions, "punct" means punctuation marks. It is all non-word and non-space characters. "Punct" is a predefined character class in regular expressions, and you can use it in any regex flavor that supports it. </p>
<p>The <code>Punct</code> character class is denoted by <code>\p{Punct}</code> or simply <code>\p{P}</code>. It matches any punctuation mark in a string. This includes characters such as periods, commas, exclamation marks, and quotation marks. </p>
<p>Since there’s a way you can match all punctuation marks, that’s what we are going to look at in this article.</p>
<h2 id="heading-how-to-match-all-punctuation-marks-in-regex-engines">How to Match all Punctuation Marks in RegEx Engines</h2>
<p>Few regex engines out there have regex flavors that support <code>\p{P}</code>. So, for those that support it, <code>\p{P}</code> would match all punctuation marks in them.
<img src="https://www.freecodecamp.org/news/content/images/2023/04/Screenshot-2023-04-28-at-08.07.14.png" alt="Screenshot-2023-04-28-at-08.07.14" width="600" height="400" loading="lazy"></p>
<p>For regex engines that don’t support <code>\p{P}</code>, you can match all punctuation marks by negating word characters and space characters with the pattern <code>[^\w\s]+</code>:
<img src="https://www.freecodecamp.org/news/content/images/2023/04/Screenshot-2023-04-28-at-08.10.24.png" alt="Screenshot-2023-04-28-at-08.10.24" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-match-all-punctuation-marks-in-javascript-regex">How to Match all Punctuation Marks in JavaScript RegEx</h2>
<p>If you want to use the pattern <code>\p{P}</code> to match all punctuation marks in JavaScript, you have to assign it the Unicode flag like this <code>/\p{P}/u</code>. Otherwise, it won’t work. Let’s see that in action:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> text = <span class="hljs-string">`That said, Kolade, you don't have to forget to take home things you buy at the store again. Do you understand?

I just said that to show you that the pattern really matches punctuation marks. I don't forget things at the store. Here are other punctuation marks:! " # $ % &amp; ' ( ) * + , - . / : ; | &lt; = &gt; { } ? @ [ \ ] ^ _ `</span>;

<span class="hljs-keyword">const</span> regex1 = <span class="hljs-regexp">/\p{P}/gu</span>;
<span class="hljs-keyword">const</span> regex2 = <span class="hljs-regexp">/[^\w\s]+/g</span>;

<span class="hljs-built_in">console</span>.log(regex1.test(text)); <span class="hljs-comment">//true</span>
<span class="hljs-built_in">console</span>.log(regex2.test(text)); <span class="hljs-comment">//true</span>

<span class="hljs-built_in">console</span>.log(regex1.exec(text));
<span class="hljs-built_in">console</span>.log(regex2.exec(text));
</code></pre>
<p>Since <code>exec()</code> would only return one match and <code>test()</code> would only return a Boolean, you can loop through the matches with <code>exec()</code> and <code>while</code> loop to see all of them:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> text = <span class="hljs-string">`That said, Kolade, you don't have to forget to take home things you buy at the store again. Do you understand?

I just said that to show you that the pattern really matches punctuation marks. I don't forget things at the store. Here are other punctuation marks:! " # $ % &amp; ' ( ) * + , - . / : ; | &lt; = &gt; { } ? @ [ \ ] ^ _ `</span>;

<span class="hljs-keyword">const</span> regex1 = <span class="hljs-regexp">/\p{P}/gu</span>;
<span class="hljs-keyword">const</span> regex2 = <span class="hljs-regexp">/[^\w\s]+/g</span>;

<span class="hljs-keyword">let</span> match;

<span class="hljs-keyword">while</span> ((match = regex1.exec(text)) !== <span class="hljs-literal">null</span>) {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'A match: '</span>, match[<span class="hljs-number">0</span>], <span class="hljs-string">'at index: '</span>, match.index);
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/Screenshot-2023-04-28-at-08.28.30.png" alt="Screenshot-2023-04-28-at-08.28.30" width="600" height="400" loading="lazy"></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>That’s how you can match all punctuation marks in regex engines and JavaScript. Don’t forget that if you’re using <code>\p{P}</code> to match punctuation marks, you have to use it with the Unicode flag like this <code>/\p{P}/u</code>. You can also apply the same to other programming languages.</p>
<p>If you want to learn more about regular expressions, you can use <a target="_blank" href="https://www.youtube.com/watch?v=ZfQFUJhPqMM">this video</a> made by Beau Carnes of freeCodeCamp.</p>
<p>Keep coding!</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
