<?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>DEV Community: Ilya Ermoshin</title>
    <description>The latest articles on DEV Community by Ilya Ermoshin (@sineni).</description>
    <link>https://dev.to/sineni</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%2F992258%2F42cdc09c-e912-4347-965a-dfc951cd4418.jpg</url>
      <title>DEV Community: Ilya Ermoshin</title>
      <link>https://dev.to/sineni</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sineni"/>
    <language>en</language>
    <item>
      <title>Performance in .NET</title>
      <dc:creator>Ilya Ermoshin</dc:creator>
      <pubDate>Mon, 27 Mar 2023 19:42:17 +0000</pubDate>
      <link>https://dev.to/sineni/performance-in-net-4i0e</link>
      <guid>https://dev.to/sineni/performance-in-net-4i0e</guid>
      <description>&lt;p&gt;Hello everyone Today we are going to talk about the performance in .NET. In this article, I would like to break down how you can improve performance and readability of the code in just two lines of code.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Information about the machine on which the calculations were performed:&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Low Power Mode = true&lt;br&gt;
BenchmarkDotNet=v0.13.5, OS=macOS Ventura 13.2.1 (22D68) [Darwin 22.3.0]&lt;br&gt;
Apple M2 Pro, 1 CPU, 12 logical and 12 physical cores&lt;br&gt;
.NET SDK=7.0.102&lt;br&gt;
  [Host]   : .NET 7.0.2 (7.0.222.60605), Arm64 RyuJIT AdvSIMD&lt;br&gt;
  .NET 7.0 : .NET 7.0.2 (7.0.222.60605), Arm64 RyuJIT AdvSIMD&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Source Code: &lt;a href="https://github.com/Sin333/PerformanceNETCore" rel="noopener noreferrer"&gt;https://github.com/Sin333/PerformanceNETCore&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Collections&lt;/strong&gt;&lt;br&gt;
The choice of collections is always up to developers, but often due to low skill level or low code quality requirements, they choose the most versatile collection (List) regardless of all its features and disadvantages. From time to time in different companies I meet a misunderstanding when use an array for the data that is needed only to take data from the database and give it back to the client. And every time you need to explain why do you need to use &lt;code&gt;IReadOnlyCollection&lt;/code&gt;, &lt;code&gt;ImmutableCollection&lt;/code&gt; collections.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fav2a3oc8iamqnqydoym9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fav2a3oc8iamqnqydoym9.png" alt="Collection 1"&gt;&lt;/a&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Farizyqbixgz5wlwb5ik0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Farizyqbixgz5wlwb5ik0.png" alt="Collection 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wow, the &lt;code&gt;ToArray&lt;/code&gt; function works many times faster. Surprisingly, it turns out that using the right collections can not only improve the readability of the code, but also give a good performance boost :)&lt;/p&gt;

&lt;p&gt;I had one story at work where it was necessary to solve the problem with exporting excel files. The problem was that the file was generated longer than the waiting time on the client, a quick solution was needed within one day that would solve the problem as quickly as possible. The longest block of code was in a LINQ request. Everything was quite simple there, data is taken from the database, grouped, sorted and materialized into a &lt;code&gt;List&lt;/code&gt; collection and comeback to client-side. As soon as I just changed the functions &lt;code&gt;ToList&lt;/code&gt; to &lt;code&gt;ToArray&lt;/code&gt;, we were immediately able to reduce the execution time of the function by ~30%. Well, there is no magic here, I just used the right collection for a specific task (&lt;code&gt;ToListAsync()&lt;/code&gt; -&amp;gt; &lt;code&gt;ToArrayAsync()&lt;/code&gt;).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you only need to get data and send the collection without any changes, use the collections that are most suitable for immutable data such as: &lt;code&gt;Array&lt;/code&gt;, &lt;code&gt;IReadOnlyCollection&lt;/code&gt;, &lt;code&gt;ImmutableCollection&lt;/code&gt; etc.&lt;/li&gt;
&lt;li&gt;Please do not recreate a collection if you don't need it. Just look at this weird &lt;code&gt;.ToList().ToArray()&lt;/code&gt; construct.&lt;/li&gt;
&lt;li&gt;Imagine you have a dataset from which you need to take elements often and compare them with other data, &lt;code&gt;Dictionary&lt;/code&gt; will help you with this better than any other collection. Some of you will ask why? Everything is quite simple here, you understand the search by key in &lt;code&gt;Dictionary&lt;/code&gt; - O (1) thus obtaining any elements by key for you will be as fast as possible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cycles&lt;/strong&gt;&lt;br&gt;
We can talk a lot about optimizations, but let's look at how it works that all developers use, namely the automation of algorithms. The main automation that a developer resorts to is to reduce the number of lines of code and minimize code duplication. And the very first construct in the code suitable for this is Loops. They allow you to repeat many of the same operations with just a couple of lines of code. The cycles are different, and it would be good to understand how they differ. Let's take performance measurements and see if there are any differences and how they work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo58nj77ftniher136u50.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo58nj77ftniher136u50.png" alt="Collection 1"&gt;&lt;/a&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmd5nk64tu0aoeukn8oav.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmd5nk64tu0aoeukn8oav.png" alt="1000000 collection"&gt;&lt;/a&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjs6umi1uqazuuwxtzj2y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjs6umi1uqazuuwxtzj2y.png" alt="10000000 collection"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we look at the results, the first thing we see is that iterating over a &lt;code&gt;List&lt;/code&gt; is slower than iterating over an &lt;code&gt;Array&lt;/code&gt;. Why? Logically, iterating over an &lt;code&gt;Array&lt;/code&gt; is always more efficient than iterating over a &lt;code&gt;List&lt;/code&gt;, since a &lt;code&gt;List&lt;/code&gt; is a wrapper around an array. Also following the logic, &lt;code&gt;for&lt;/code&gt; is always faster than &lt;code&gt;foreach&lt;/code&gt;, since &lt;code&gt;foreach&lt;/code&gt; does extra checks. The point is that for iterating over an array, &lt;code&gt;foreach&lt;/code&gt; does not use the &lt;code&gt;IEnumerable&lt;/code&gt; implementation. In this particular case, the most optimized iteration over the index is performed, without checking for array out-of-bounds, since the &lt;code&gt;foreach&lt;/code&gt; construct does not operate on indexes, so the developer does not have the opportunity to create an &lt;code&gt;ArgumentOutOfRangeException&lt;/code&gt; error in the code.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;for&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Array&lt;/code&gt; – base iteration over index&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;List&lt;/code&gt; – base iteration over index&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;foreach&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Array&lt;/code&gt; – base iteration over index 😺&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;List&lt;/code&gt; – &lt;code&gt;IEnumerable.GetEnumerator()&lt;/code&gt; &amp;amp; &lt;code&gt;IEnumerable.MoveNext()&lt;/code&gt; 😾💔&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Keep in mind that the &lt;code&gt;List&lt;/code&gt; collection has its advantages and you should use the correct collection depending on the calculation you need. Even if you are writing logic to work with loops, you must not forget that this is a regular loop and is also subject to possible loop optimization. One possible optimization that the compiler can make is to unroll the loop, if the size of the collection is known in advance, then the compiler will go through the entire loop for X lines of code without going through the collection. But you can also reduce the number of iterations in the loop by using the two &lt;code&gt;continue&lt;/code&gt; &amp;amp; &lt;code&gt;break&lt;/code&gt; operators.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Throw&lt;/strong&gt;&lt;br&gt;
A few years ago I worked in a company on a legacy project, in that project they used to process field validation through a try-catch-throw construct.&lt;br&gt;
Even then I had a feeling that this was an nonoptimal realization of validation, so I tried not to use such a construction whenever possible. But let's see why the approach to handle errors with such a construction is bad. I wrote a little code to compare the two approaches and benchmarked each one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5g16vcbt9isqkebpozh9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5g16vcbt9isqkebpozh9.png" alt="Throw 1"&gt;&lt;/a&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F87jievqzwbrrhrcfl2sj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F87jievqzwbrrhrcfl2sj.png" alt="Throw2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see difference greater than 1000x 😉&lt;/p&gt;

&lt;p&gt;Try catch makes the code harder to understand and increases the execution time of your program. But if you need this construct, you should not insert those lines of code from which error handling is not expected - this will make the code easier to understand. In fact, it’s not so much exception handling that loads the system, but throwing the errors themselves through the &lt;code&gt;throw new Exception&lt;/code&gt; construct.&lt;/p&gt;

&lt;p&gt;Throwing exceptions is slower than any class that will collect an error in the required format. If you are processing a form or some data, and you clearly know what the error should be, why not process it?&lt;/p&gt;

&lt;p&gt;You should not write a &lt;code&gt;throw new Exception()&lt;/code&gt; construct unless this situation is exceptional. &lt;u&gt;Handling and throwing an exception is very expensive!!!&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;String compare&lt;/strong&gt;&lt;br&gt;
In my 9 years of experience on the .NET platform, I have never worked in a project without using string matching. And in each micro-service team did string comparison in different ways. But what should be used and how to unify it? In the book &lt;code&gt;CLR via C# Richter&lt;/code&gt;, I read information that the &lt;code&gt;ToUpperInvariant()&lt;/code&gt; method is faster than &lt;code&gt;ToLowerInvariant()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Extract from the book:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvc2jksdfqipozbspvdxl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvc2jksdfqipozbspvdxl.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, I didn't believe it and decided to run tests on the .NET Framework, and the result shocked me - a performance increase of more than &lt;strong&gt;15%&lt;/strong&gt;. Then, when I came to work the next morning, I shared my experience with the team and we decided to try it on our project. Surprisingly, after testing on our project, we received a significant performance boost. We received the strongest increase in the microservice responsible for generating Excel files.&lt;/p&gt;

&lt;p&gt;But actually now I recommend you use function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Compare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;strB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;StringComparison&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OrdinalIgnoreCase&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's better solution for string compares.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vqtph25dqnxrxlk4x60.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vqtph25dqnxrxlk4x60.png" alt="Image description"&gt;&lt;/a&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3t01hkce0pylm6lc719o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3t01hkce0pylm6lc719o.png" alt="String compare"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good Practices and Optimization Tips&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Remember: if you are still using the &lt;code&gt;.NET Framework&lt;/code&gt; it is never too late to upgrade your software to &lt;code&gt;.NET Core&lt;/code&gt; or &lt;code&gt;.NET&lt;/code&gt; 5 and up. This is the best way to optimize your software not only in terms of system speed, but also greatly improve the project compilation speed, reduce memory consumption and give the opportunity to work on your project not only as a developer with Windows OS. Optimization, with each new version, the optimization of the core libraries Collection/Struct/Stream/String/Regex and much more is improved. If you're moving from .NET Framework to .NET Core, you'll get a big performance boost out of the box. I am attaching a link to moving bing from NET Framework to .NET 5: &lt;a href="https://devblogs.microsoft.com/dotnet/migration-of-bings-workflow-engine-to-net-5/" rel="noopener noreferrer"&gt;https://devblogs.microsoft.com/dotnet/migration-of-bings-workflow-engine-to-net-5/&lt;/a&gt; and attaching a link to moving bin from .NET 5 to .NET 7: &lt;a href="https://devblogs.microsoft.com/dotnet/dotnet-performance-delivers-again-for-bing-from-dotnet-5-to-dotnet-7/" rel="noopener noreferrer"&gt;https://devblogs.microsoft.com/dotnet/dotnet-performance-delivers-again-for-bing-from-dotnet-5-to-dotnet-7/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Use C# keywords like: static, const, readonly, sealed, abstract, etc, where they make sense. You may think - how is this connected to optimization? The fact is that the more detailed you describe your system to the compiler, the more optimal code it will be able to generate. Give the compiler and virtual machine a chance! As a bonus, you'll find many misuse errors in your code at compile time. General rule: the more clearly the system is described, the better the result you get.&lt;/li&gt;
&lt;li&gt;If your project has regular expressions, then there is a high probability that they may not be written optimally, I strongly advise you to read my previous article on regular expressions to better understand how they work and how you can speed up your patterns: &lt;a href="https://dev.to/sineni/regex-for-lazy-developers-cg1"&gt;https://dev.to/sineni/regex-for-lazy-developers-cg1&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;End..?&lt;/strong&gt;&lt;br&gt;
When writing code, you should pay attention to different aspects of your project and use the capabilities of your programming language and platform to achieve the best result. It is important to remember that improving the performance of your system not only helps you understand the code better, but also helps you save money on resources in cloud systems such as Azure, AWS, etc. These are far from all the optimizations that I would like to share with you, but let it be good short article. If you have additional tips or history for improving code quality and code performance after reading the article, I will be glad to hear your comments! Thank you very much for reading this article to the end, I sincerely hope that it was useful to you&lt;/p&gt;

&lt;p&gt;Source Code: &lt;a href="https://github.com/Sin333/PerformanceNETCore" rel="noopener noreferrer"&gt;https://github.com/Sin333/PerformanceNETCore&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>performance</category>
      <category>csharp</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>Regex for lazy developers</title>
      <dc:creator>Ilya Ermoshin</dc:creator>
      <pubDate>Wed, 04 Jan 2023 19:15:44 +0000</pubDate>
      <link>https://dev.to/sineni/regex-for-lazy-developers-cg1</link>
      <guid>https://dev.to/sineni/regex-for-lazy-developers-cg1</guid>
      <description>&lt;p&gt;Regular expressions are a text processing system based on a special pattern notation system. Simply put, it provides programmers with the ability to easily process and validate strings. It represents the implementation of the DRY (Don't Repeat Yourself) principle, in almost all supported languages, the regular expression pattern will not change form at all. &lt;/p&gt;

&lt;p&gt;The code written on the backend and frontend applications will be identical, thereby saving time for teams to implement the same features. It is also worth emphasizing that this module is ideal for working with large or complex strings, therefore makes it possible to solve problems related to them simply and quickly. &lt;/p&gt;

&lt;p&gt;It happens over a cup of tea in the kitchen or at a team zoom-call, you can hear that regular expressions are quite difficult to learn, write and read, and in general they were invented by terrible people 😈. But is it? Let's figure it out.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note:&lt;br&gt;
This article is relevant for those who consider regular expressions complex, incomprehensible and for those who think that basic knowledge is completely enough for work.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F84ohvrdv1c6vsa0laos1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F84ohvrdv1c6vsa0laos1.png" alt="Regex mem"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does it look like&lt;/strong&gt;&lt;br&gt;
The following are examples in 6 programming languages ​​for determining a Russian phone number.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj032n7v93q9ukpil3e3k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj032n7v93q9ukpil3e3k.png" alt="Regex example based on few languages"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example, you can immediately notice the first feature of the Regex module: the condition pattern will be completely identical and you can easily share your code with a team that writes in another programming language. The ability to quickly "fumble" the code base between different teams saves time on the development and implementation of features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;History of appearance&lt;/strong&gt;&lt;br&gt;
Regular expressions first appeared in scientific papers on automata theory and the theory of formal languages ​​in the mid-1950s. Stefan Cole Kleen is credited as the person who first introduced the concept of Regular Expressions.&lt;/p&gt;

&lt;p&gt;The principles and ideas laid down in his work were practically implemented by Ken Thompson, and with his light hand were integrated into the Perl language.&lt;/p&gt;

&lt;p&gt;By definition, Regular Expressions are a module of your programming language that is used to search and manipulate text.&lt;/p&gt;

&lt;p&gt;The Regular Expression Language is not a full-fledged programming language, although, like other languages, it has its own syntax and commands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What programming languages ​​support them?&lt;/strong&gt;&lt;br&gt;
The list is quite large, here are just a few of them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;C&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;C#&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;C++&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Cobol&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Delphi&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;F#&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Go&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Groovy&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Haskell&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Java&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;JavaScript&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Julia&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Kotlin&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;MATLAB&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Objective-C&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;PHP&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Perl&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Python&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;R&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Ruby&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Rust&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Scala&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Swift&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Visual Basic&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Visual Basic .NET&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;...&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Capabilities&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pattern matching of input data.&lt;/li&gt;
&lt;li&gt;Search and change input data by template.&lt;/li&gt;
&lt;li&gt;Return the first or all results from the input string.&lt;/li&gt;
&lt;li&gt;Return along with the result of the general search, named and not substrings when searching.&lt;/li&gt;
&lt;li&gt;Replacing characters, words, phrases in the input string after the pass.&lt;/li&gt;
&lt;li&gt;And most importantly, write once and use everywhere.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Where will it be useful?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search and replace code by pattern in IDE (VS Code, Rider, CLion, VS)&lt;/li&gt;
&lt;li&gt;Validation of strings for pattern matching (file extension).&lt;/li&gt;
&lt;li&gt;Validation of fields on the front (e-mail, phone number and other).&lt;/li&gt;
&lt;li&gt;Validation of request and response data.&lt;/li&gt;
&lt;li&gt;Validating huge strings and then getting the necessary pieces of text without spending a lot of time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Basic Syntax&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;&lt;code&gt;^&lt;/code&gt;&lt;/strong&gt; - start of string (means that the input string must start with the next character after that. Not suitable if you don't know the first character of the input string).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;$&lt;/code&gt;&lt;/strong&gt; - end of string (means that all conditions before this character will be the final result of the input string and after them there is nothing further. Not suitable if you want to return several results from the input string).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;*&lt;/code&gt;&lt;/strong&gt; - means that the previous condition before the given symbol may occur one or more times or not at all (respectively, it may be repeated).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;+&lt;/code&gt;&lt;/strong&gt; - means that the previous condition before this symbol must occur one or more times (respectively, it can be repeated).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;[a-z]&lt;/code&gt;&lt;/strong&gt; - enumeration of a valid character in the input string, that is, it can be any lowercase Latin letter (a or b or c ... or x or y or z).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;[0-9]&lt;/code&gt;&lt;/strong&gt; - enumeration of a valid character in the input string, that is, it can be any lowercase Latin letter (1 or 2 or 3 ... or 7 or 8 or 9).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;.&lt;/code&gt;&lt;/strong&gt; - any single character.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;\&lt;/code&gt;&lt;/strong&gt; - selection of any special character.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;|&lt;/code&gt;&lt;/strong&gt; – OR logical operation (condition to the left or the condition to the right of this operand must be fulfilled)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Syntax Simplification&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;\d&lt;/code&gt;&lt;/strong&gt; ≡ &lt;strong&gt;&lt;code&gt;[0-9]&lt;/code&gt;&lt;/strong&gt; - any character from 0 to 9&lt;br&gt;
&lt;strong&gt;&lt;code&gt;\D&lt;/code&gt;&lt;/strong&gt; ≡ &lt;strong&gt;&lt;code&gt;[^0-9]&lt;/code&gt;&lt;/strong&gt; - any character except numbers&lt;br&gt;
&lt;strong&gt;&lt;code&gt;\w&lt;/code&gt;&lt;/strong&gt; ≡ &lt;strong&gt;&lt;code&gt;[a-zA-Z0-9_]&lt;/code&gt;&lt;/strong&gt; - any Latin character, all numbers and “_”&lt;br&gt;
&lt;strong&gt;&lt;code&gt;\W&lt;/code&gt;&lt;/strong&gt; ≡ &lt;strong&gt;&lt;code&gt;[^a-zA-Z0-9_]&lt;/code&gt;&lt;/strong&gt; – any character except Latin characters, numbers and “_”&lt;br&gt;
&lt;strong&gt;&lt;code&gt;\s&lt;/code&gt;&lt;/strong&gt; ≡ &lt;strong&gt;&lt;code&gt;[ ]&lt;/code&gt;&lt;/strong&gt; - space only&lt;br&gt;
&lt;strong&gt;&lt;code&gt;\S&lt;/code&gt;&lt;/strong&gt; ≡ &lt;strong&gt;&lt;code&gt;[^ ]&lt;/code&gt;&lt;/strong&gt; - any character except space&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Basic Syntax Explanation&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdzzxax0xil62au2x4ehk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdzzxax0xil62au2x4ehk.png" alt="Regexp Basic Syntax Explanation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Condition Length&lt;/strong&gt;&lt;br&gt;
In addition to validating values ​​in a string, we can also specify how many characters should pass the same condition. There are only three possibilities to work with length conditions:&lt;br&gt;
&lt;strong&gt;&lt;code&gt;{3}&lt;/code&gt;&lt;/strong&gt; – required number of characters for the condition&lt;br&gt;
&lt;strong&gt;&lt;code&gt;{3.5}&lt;/code&gt;&lt;/strong&gt; - min. and max. number of characters for the condition&lt;br&gt;
&lt;strong&gt;&lt;code&gt;{3,}&lt;/code&gt;&lt;/strong&gt; – mandatory min. number and unlimited max. quantity&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr608qt04mnzmi95fhbgx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr608qt04mnzmi95fhbgx.png" alt="Regex condition length"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: The condition &lt;strong&gt;&lt;code&gt;[0-9]&lt;/code&gt;&lt;/strong&gt; can be replaced with the abbreviation &lt;strong&gt;&lt;code&gt;\d&lt;/code&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Working with groups (Advanced)&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;It's going to be a little more tricky, so get ready.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;()&lt;/code&gt;&lt;/strong&gt; - creating an anonymous group (creating a substring and allocating memory for it)&lt;br&gt;
&lt;strong&gt;&lt;code&gt;(?‘nameGroup’)&lt;/code&gt;&lt;/strong&gt; - &lt;strong&gt;&lt;code&gt;(?&amp;lt;nameGroup&amp;gt;)&lt;/code&gt;&lt;/strong&gt; – create named string&lt;br&gt;
&lt;strong&gt;&lt;code&gt;(\k&amp;lt;nameGroup&amp;gt;)&lt;/code&gt;&lt;/strong&gt; - serves to get rid of the pattern from duplicate code, so, if you have a named group “nameGroup” with some condition, you can not write the second group in the pattern, but simply use this directive with a regular expression indicating only the name of the group that has been described before. Thus, the condition will be repeated and you do not need to describe it again.&lt;br&gt;
&lt;strong&gt;&lt;code&gt;(?:)&lt;/code&gt;&lt;/strong&gt; - selection in logical brackets of the condition, without naming and creating a substring&lt;br&gt;
&lt;strong&gt;&lt;code&gt;(&amp;lt;=)&lt;/code&gt;&lt;/strong&gt; - Excludes the conditions inside the brackets and does not include it in the selection.&lt;br&gt;
&lt;strong&gt;&lt;code&gt;(?!)&lt;/code&gt;&lt;/strong&gt; - Checks the conditions inside the brackets and does not include it in the selection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real life example&lt;/strong&gt;&lt;br&gt;
Once, at work, I had to parse data from a QR code that was printed on checks when buying / returning various goods, services, etc. The first version of the parser was written at the C# backend. The code base of the parser was ~150 lines of code, it did not take into account some features of various fiscal registrars (devices that print checks and send data to the Federal Tax Service). To change this function, it was necessary to carefully look, check every line of code. Later, there were so many options and there was a need to use it at the frontend for validation. Accordingly, it was decided to rewrite it using regular expressions to simplify the parser and make it easy and quick to port it to another programming language.&lt;/p&gt;

&lt;p&gt;Goals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Parse input values ​​for pattern validation&lt;/li&gt;
&lt;li&gt;Take the necessary fields for the date and amount of the purchase for further use in the system.&lt;/li&gt;
&lt;li&gt;Check that the field “n” is always equal to 1 (0 - return, 1 - purchase)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is an example for Input data:&lt;br&gt;
&lt;code&gt;t=20181125T142800&amp;amp;s=850.12&amp;amp;fn=8715000100011785&amp;amp;i=86841&amp;amp;fp=1440325305&amp;amp;n=1&lt;/code&gt;&lt;br&gt;
Regular expression for such data parsing:&lt;br&gt;
&lt;code&gt;^t=(?&amp;lt;Date&amp;gt;[0-9-:T]+)&amp;amp;s=(?&amp;lt;Sum&amp;gt;[0-9]+(?:\.[0-9]{2})?)&amp;amp;fn=[0-9]+&amp;amp;i=[0-9]+&amp;amp;fp=[0-9]+&amp;amp;n=1$&lt;/code&gt;&lt;br&gt;
Code example (C#):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;parseQRCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Regex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"^t=(?&amp;lt;Date&amp;gt;[0-9-:T]+)&amp;amp;s=(?&amp;lt;Sum&amp;gt;[0-9]+(?:\.[0-9]{2})?)&amp;amp;fn=[0-9]+&amp;amp;i=[0-9]+&amp;amp;fp=[0-9]+&amp;amp;n=1$"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RegexOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ECMAScript&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;matchResult&lt;/span&gt; &lt;span class="p"&gt;=&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;Match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;matchResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ArgumentException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid qrCode"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;dateGroup&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;matchResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Groups&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Date"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;dateGroup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ArgumentException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid qrCode, Date group not found"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;sumGroup&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;matchResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Groups&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Sum"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;sumGroup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ArgumentException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid qrCode, Sum group not found"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dateGroup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sumGroup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Code example (Typescript):&lt;br&gt;
This option is made through Exceptions, but can be done through return false or return null.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parseQRCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RegExp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;^t=(?&amp;lt;Date&amp;gt;[0-9-:T]+)&amp;amp;s=(?&amp;lt;Sum&amp;gt;[0-9]+(?:&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;.[0-9]{2})?)&amp;amp;fn=[0-9]+&amp;amp;i=[0-9]+&amp;amp;fp=[0-9]+&amp;amp;n=1$&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;matchResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;matchResult&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid qrCode&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dateGroup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;matchResult&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;dateGroup&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid qrCode, Date group not found&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sumGroup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;matchResult&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;sumGroup&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid qrCode, Sum group not found&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dateGroup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sumGroup&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the output, we get two values:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Date - a field indicating the date and time of purchase (it remains only to parse it and turn it into a date object)&lt;/li&gt;
&lt;li&gt;Sum - purchase amount&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now let's analyze the pattern in more detail:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;^&lt;/code&gt; - denoting the beginning of a line&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;t=(?&amp;lt;Date&amp;gt;[0-9-:T]+)&lt;/code&gt; – required characters t=(hereinafter any characters (from 0 to 9 or - or : or T) in one or more instances)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;amp;s=(?&amp;lt;Sum&amp;gt;[0-9]+(?:\.[0-9]{2})?)&lt;/code&gt; – required characters

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;&amp;amp;s=&lt;/code&gt; – required sequence of characters &lt;code&gt;&amp;amp;&lt;/code&gt; and &lt;code&gt;s&lt;/code&gt; and &lt;code&gt;=&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[0-9]+&lt;/code&gt; (characters 0 to 9 in one or more instances)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;(?:\.[0-9]{2})?&lt;/code&gt; - non required group start at &lt;code&gt;.&lt;/code&gt; symbol with 2 numbers&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;$&lt;/code&gt; - denoting the end of the line&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;&amp;amp;fn=[0-9]+&lt;/code&gt; – required characters &lt;code&gt;&amp;amp;fn=&lt;/code&gt; followed by &lt;code&gt;[0-9]+&lt;/code&gt; -&amp;gt; (any number from 0 to 9 in one or more instances)&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;&amp;amp;i=[0-9]+&lt;/code&gt; – required characters &lt;code&gt;&amp;amp;i=&lt;/code&gt; followed by &lt;code&gt;[0-9]+&lt;/code&gt; -&amp;gt; (any number from 0 to 9 in one or more instances)&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;&amp;amp;fp=[0-9]+&lt;/code&gt; – required characters &lt;code&gt;&amp;amp;fp=&lt;/code&gt; followed by &lt;code&gt;[0-9]+&lt;/code&gt; -&amp;gt; (any number from 0 to 9 in one or more instances)&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;&amp;amp;n=1&lt;/code&gt; – required characters &lt;code&gt;&amp;amp;n=1&lt;/code&gt;
&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The problem of working with non-Latin&lt;/strong&gt;&lt;br&gt;
When you need to work with the entire Latin alphabet, just write &lt;code&gt;[a-zA-Z]&lt;/code&gt;. Many people think that when working with Cyrillic it is enough to write &lt;code&gt;[а-яА-Я]&lt;/code&gt;. It seems that everything is logical and everything is fine, but at some point you will realize that sometimes it does not work correctly for you. The problem is that the range &lt;code&gt;[а-я]&lt;/code&gt; does not include the letter “ё”, therefore, you need to change your pattern from &lt;code&gt;[а-яА-Я]&lt;/code&gt; to &lt;code&gt;[а-яёА-ЯЁ]&lt;/code&gt; so that the code takes into account a specific letter in the alphabet. This problem exists not only in Cyrillic, this problem is also relevant for Greek, Turkish, China and a number of other languages. Be careful when writing a pattern that should use these languages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JS regex flags&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;global (g) - does not stop searching after finding the first match.&lt;/li&gt;
&lt;li&gt;multi line (m) - searches the line including line break (^ start of line, $ end of line).&lt;/li&gt;
&lt;li&gt;insensitive (i) - search insensitively (a ≡ A)&lt;/li&gt;
&lt;li&gt;sticky (y) - search returns, in addition to the match, the index from the beginning of the subselect match (not supported in IE)&lt;/li&gt;
&lt;li&gt;unicode (u) - search includes unicode characters (not supported in IE)&lt;/li&gt;
&lt;li&gt;single line (s) - in this mode, the symbol &lt;code&gt;.&lt;/code&gt; includes also newline (supported by Chrome, Opera, Safari)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Additional regex settings in C#&lt;/strong&gt;&lt;br&gt;
RegexOptions is exposed as an additional parameter in the constructor of the Regex class. It can also be specified in the Match, Matches methods.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;None - set by default.&lt;/li&gt;
&lt;li&gt;IgnoreCase (\i) - checks case insensitively.&lt;/li&gt;
&lt;li&gt;Multiline (\m) - work with a line where there are hyphens \n.&lt;/li&gt;
&lt;li&gt;ExplicitCapture (\n) - adds only named groups to the result.&lt;/li&gt;
&lt;li&gt;Compiled (will be useful only in static version, speeds up regular expression, slows down compilation).&lt;/li&gt;
&lt;li&gt;Singleline (the &lt;code&gt;.&lt;/code&gt; sign will match any character except \n and ignore it when searching)&lt;/li&gt;
&lt;li&gt;IgnorePatternWhitespace (\x) . (cuts out all spaces, exceptions in constructions[],{})&lt;/li&gt;
&lt;li&gt;RightToLeft - search from right to left.&lt;/li&gt;
&lt;li&gt;ECMAScript (JS like version but stylegroupings same as in .NET).&lt;/li&gt;
&lt;li&gt;CultureInvariant (compares ignoring the keyboard layout).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Good Practices and Optimization Tips&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The fewer groupings, the faster the execution speed. Try to avoid them if you don't need them.&lt;/li&gt;
&lt;li&gt;When using abbreviations (&lt;code&gt;\d&lt;/code&gt;, &lt;code&gt;\w&lt;/code&gt; and others), be sure that they fully match your search terms. Better check twice.&lt;/li&gt;
&lt;li&gt;If you often use regular expressions, create it once globally, thereby reducing the amount of duplicate code.&lt;/li&gt;
&lt;li&gt;Almost everywhere there is a possibility of compiling regular expressions, which often optimizes your expressions and speeds up their execution. BUT use them after validation, it will speed up your code.&lt;/li&gt;
&lt;li&gt;Try to reduce the amount of special symbol selection (&lt;code&gt;\&lt;/code&gt;), this functionality slows down the execution speed in many programming languages.&lt;/li&gt;
&lt;li&gt;Regular expressions have support for UTF character codes. At some points, this will improve performance, but reduce readability. If you decide to use them, be sure that the team will approve your decision and it's worth it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
Regular expressions just want to seem complicated, but in fact, the features that they provide give a lot of opportunities and allow you to simplify and speed up the work of everyone from Junior to Senior / Lead. &lt;br&gt;
Please, if you have any questions, please feel free to comment, there we can discuss with you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mariomka/regex-benchmark" rel="noopener noreferrer"&gt;Languages Regex Benchmark&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://regex101.com/" rel="noopener noreferrer"&gt;Online regex helper with a dictionary of all available commands and support for several programming languages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://habr.com/ru/post/577534/" rel="noopener noreferrer"&gt;My original post in RU language&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;P.S. Don't forget one important rule: "Programming is still cool." and have a nice working day&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>javascript</category>
      <category>dotnet</category>
    </item>
  </channel>
</rss>
