<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Genesis Ivan Ilagan</title>
    <description>The latest articles on Forem by Genesis Ivan Ilagan (@ivanilagan11).</description>
    <link>https://forem.com/ivanilagan11</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F747033%2Fbdf42770-c1df-4677-92a3-e896bccf6568.jpeg</url>
      <title>Forem: Genesis Ivan Ilagan</title>
      <link>https://forem.com/ivanilagan11</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ivanilagan11"/>
    <language>en</language>
    <item>
      <title>Read and Write Regex as Simple English Sentences in Ruby with Regexer</title>
      <dc:creator>Genesis Ivan Ilagan</dc:creator>
      <pubDate>Thu, 25 Aug 2022 18:55:01 +0000</pubDate>
      <link>https://forem.com/ivanilagan11/read-and-write-regex-as-simple-english-sentences-in-ruby-with-regexer-50e</link>
      <guid>https://forem.com/ivanilagan11/read-and-write-regex-as-simple-english-sentences-in-ruby-with-regexer-50e</guid>
      <description>&lt;p&gt;We all encounter regex from time to time throughout our software development. Few of the common things we do with regex is wanting to find a certain set of strings or substrings with a common pattern and making our own custom validation of user inputs.&lt;/p&gt;

&lt;p&gt;But us we stumble upon regex, you'll be most likely be eyes wide open and scratching your head on it while trying to read and understand it. Well, at least that's what I always do and most likely for people who haven't have much experience with regex.&lt;/p&gt;

&lt;p&gt;Because reading regex, it feels like a language from another planet. It's full of a mix of characters and numbers then jumbled up all over the place. Like look at this for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/-?\d+(\.\d*)?/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The regex above is for matching any positive or negative decimal numbers. For beginners in regex, this really looks like something not from planet Earth. It will take a while for beginners to decipher this otherworldly language and even create their own.&lt;/p&gt;

&lt;p&gt;So to make it a bit easier to understand and easier to create one, I created a ruby DSL called regexer in which they can easily read and write regex with just simple english words and sentences. Syntax-wise, it is inspired by Factorybot &amp;amp; RSpec.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;To start, install regexer gem&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;regexer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We build our regex patterns by giving a block that contains DSL method calls to the instance of PatternBuilder class.&lt;/p&gt;

&lt;p&gt;For starters, we can create a regex pattern that matches any small letter in the alphabet like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Regexer&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PatternBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;has_letter&lt;/span&gt; &lt;span class="ss"&gt;from: &lt;/span&gt;&lt;span class="s2"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s2"&gt;"z"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# generates /[a-z]/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or we can create a regex pattern that matches consecutive instances of the word 'hello':&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Regexer&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PatternBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;has_consecutive_instances_of&lt;/span&gt; &lt;span class="s1"&gt;'hello'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# generates /(hello)+/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above examples are just simple usages of one of the available DSL methods. To make a slightly bit more complex regex patterns, we can actually chain DSL methods and express it into simple sentences. Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Regexer&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PatternBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;starts_with&lt;/span&gt; &lt;span class="n"&gt;consecutive_instances_of&lt;/span&gt; &lt;span class="n"&gt;letter&lt;/span&gt; &lt;span class="ss"&gt;from: &lt;/span&gt;&lt;span class="s2"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s2"&gt;"Z"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# generates /^([A-Z]+)/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see, it actually reads as a simple sentence.&lt;/p&gt;

&lt;p&gt;In order for us to check the regex pattern that it generated, we just call the #result method so that it will return a Regexer::Model::Pattern instance and we can just call the #regex method to get the regex value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Regexer&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PatternBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;starts_with&lt;/span&gt; &lt;span class="n"&gt;consecutive_instances_of&lt;/span&gt; &lt;span class="n"&gt;letter&lt;/span&gt; &lt;span class="ss"&gt;from: &lt;/span&gt;&lt;span class="s2"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s2"&gt;"Z"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;result&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;regex&lt;/span&gt;
&lt;span class="c1"&gt;# Outputs /^([A-Z]+)/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see, to generate the regex '/^([A-Z]+)/' in regexer, we just made a sentence that is easier to understand and functions almost similar to what we want in regex.&lt;/p&gt;

&lt;p&gt;Now going back to the more alien like regex pattern mentioned in the introduction, we can actually express that pattern in regexer like so&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Regexer&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PatternBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;has_none_or_one_instance_of&lt;/span&gt; &lt;span class="s2"&gt;"-"&lt;/span&gt;
  &lt;span class="n"&gt;has_consecutive_instances_of&lt;/span&gt; &lt;span class="n"&gt;digit_character&lt;/span&gt;
  &lt;span class="n"&gt;has_none_or_one_instance_of&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;contains&lt;/span&gt; &lt;span class="s2"&gt;"."&lt;/span&gt;
    &lt;span class="n"&gt;has_none_or_consecutive_instances_of&lt;/span&gt; &lt;span class="n"&gt;digit_character&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;result&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;regex&lt;/span&gt;
&lt;span class="c1"&gt;# Outputs /\-?\d+(\.\d*)?/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So comparing this regex '/-?\d+(.\d*)?/' and the regexer interpreted one above, regexer just made it feel more human friendly. Though it didn't exactly match the raw regex pattern but technically, the regex pattern generated by regexer functions the same as with the raw regex.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;This is my very first ruby gem and first time in making my own DSL hehe. Though there are some others who have a similar gem and works to build more complex patterns and still be human readable. But despite that, I am happy to release this and had fun on making a DSL with ruby hehe. &lt;/p&gt;

&lt;p&gt;So far, the current state of regexer allows simple to a slightly bit more complex regex patterns be generated in a more readable format. But soon enough, I'll be adding more functionality so that it can build more complex regex patterns and still retain its simple english sentence structure.&lt;/p&gt;

&lt;p&gt;Hopefully this ruby DSL can at least make it easier to read and understand regex especially for beginners.&lt;/p&gt;

&lt;p&gt;You can checkout the gem repo here: &lt;a href="https://github.com/IvanIlagan/regexer-ruby"&gt;https://github.com/IvanIlagan/regexer-ruby&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have more examples of possible regex patterns that you can build using the gem in the repo. Also you can explore more of &lt;br&gt;
the available DSL methods for you guys to mix and match and build regex more sentence like for your needs. Happy coding!&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>ruby</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
