Regular Expressions 101

Save & Share

Flavor

  • PCRE2 (PHP >=7.3)
  • PCRE (PHP <7.3)
  • ECMAScript (JavaScript)
  • Python
  • Golang
  • Java 8
  • .NET 7.0 (C#)
  • Rust
  • Regex Flavor Guide

Function

  • Match
  • Substitution
  • List
  • Unit Tests

Tools

Sponsors
There are currently no sponsors. Become a sponsor today!
An explanation of your regex will be automatically generated as you type.
Detailed match information will be displayed here automatically.
  • All Tokens
  • Common Tokens
  • General Tokens
  • Anchors
  • Meta Sequences
  • Quantifiers
  • Group Constructs
  • Character Classes
  • Flags/Modifiers
  • Substitution
  • A single character of: a, b or c
    [abc]
  • A character except: a, b or c
    [^abc]
  • A character in the range: a-z
    [a-z]
  • A character not in the range: a-z
    [^a-z]
  • A character in the range: a-z or A-Z
    [a-zA-Z]
  • Any single character
    .
  • Alternate - match either a or b
    a|b
  • Any whitespace character
    \s
  • Any non-whitespace character
    \S
  • Any digit
    \d
  • Any non-digit
    \D
  • Any word character
    \w
  • Any non-word character
    \W
  • Non-capturing group
    (?:...)
  • Capturing group
    (...)
  • Zero or one of a
    a?
  • Zero or more of a
    a*
  • One or more of a
    a+
  • Exactly 3 of a
    a{3}
  • 3 or more of a
    a{3,}
  • Between 3 and 6 of a
    a{3,6}
  • Start of string
    ^
  • End of string
    $
  • A word boundary
    \b
  • Non-word boundary
    \B

Regular Expression
No Match

r"
"
g

Test String

Code Generator

Generated Code

#include <StringConstants.au3> ; to declare the Constants of StringRegExp #include <Array.au3> ; UDF needed for _ArrayDisplay and _ArrayConcatenate Local $sRegex = "((?:if|for|while)\s+?[^:]*?:\n)|(else\s*?:\n)|(else\s+?if[^:]*?:\n)" Local $sString = "import datetime" & @CRLF & _ "import difflib" & @CRLF & _ "import hashlib" & @CRLF & _ "import random" & @CRLF & _ "import re" & @CRLF & _ "" & @CRLF & _ "from annoying.functions import get_object_or_None" & @CRLF & _ "from django.conf import settings" & @CRLF & _ "from django.contrib.auth.models import User" & @CRLF & _ "from django.db import models" & @CRLF & _ "from markdown_deux import markdown" & @CRLF & _ "from pygments import highlight" & @CRLF & _ "from pygments.formatters import HtmlFormatter" & @CRLF & _ "from pygments.lexers import get_lexer_by_name" & @CRLF & _ "from pygments.util import ClassNotFound" & @CRLF & _ "from snipts.utils import slugify_uniquely" & @CRLF & _ "from taggit.managers import TaggableManager" & @CRLF & _ "from taggit.utils import edit_string_for_tags" & @CRLF & _ "from teams.models import Team" & @CRLF & _ "" & @CRLF & _ "" & @CRLF & _ "class Snipt(models.Model):" & @CRLF & _ " """An individual Snipt."""" & @CRLF & _ "" & @CRLF & _ " user = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE)" & @CRLF & _ " last_user_saved = models.ForeignKey(" & @CRLF & _ " User," & @CRLF & _ " blank=True," & @CRLF & _ " null=True," & @CRLF & _ " related_name="last_user_saved"," & @CRLF & _ " on_delete=models.CASCADE," & @CRLF & _ " )" & @CRLF & _ "" & @CRLF & _ " title = models.CharField(max_length=255, blank=True, null=True, default="Untitled")" & @CRLF & _ " slug = models.SlugField(max_length=255, blank=True)" & @CRLF & _ " custom_slug = models.SlugField(max_length=255, blank=True)" & @CRLF & _ " tags = TaggableManager()" & @CRLF & _ "" & @CRLF & _ " lexer = models.CharField(max_length=50)" & @CRLF & _ " code = models.TextField()" & @CRLF & _ " meta = models.TextField(blank=True, null=True)" & @CRLF & _ " description = models.TextField(blank=True, null=True)" & @CRLF & _ " stylized = models.TextField(blank=True, null=True)" & @CRLF & _ " stylized_min = models.TextField(blank=True, null=True)" & @CRLF & _ " embedded = models.TextField(blank=True, null=True)" & @CRLF & _ " line_count = models.IntegerField(blank=True, null=True, default=None)" & @CRLF & _ "" & @CRLF & _ " key = models.CharField(max_length=100, blank=True, null=True)" & @CRLF & _ " public = models.BooleanField(default=False)" & @CRLF & _ " secure = models.BooleanField(default=False)" & @CRLF & _ " blog_post = models.BooleanField(default=False)" & @CRLF & _ "" & @CRLF & _ " views = models.IntegerField(default=0)" & @CRLF & _ "" & @CRLF & _ " created = models.DateTimeField(auto_now_add=True, editable=False)" & @CRLF & _ " modified = models.DateTimeField(auto_now=True, editable=False)" & @CRLF & _ " publish_date = models.DateTimeField(blank=True, null=True)" & @CRLF & _ "" & @CRLF & _ " def _unidiff_output(self, expected, actual):" & @CRLF & _ " expected = expected.splitlines(1)" & @CRLF & _ " actual = actual.splitlines(1)" & @CRLF & _ "" & @CRLF & _ " diff = difflib.unified_diff(expected, actual)" & @CRLF & _ "" & @CRLF & _ " return "".join(diff)" & @CRLF & _ "" & @CRLF & _ " def __init__(self, *args, **kwargs):" & @CRLF & _ " super(Snipt, self).__init__(*args, **kwargs)" & @CRLF & _ " self.original_code = self.code" & @CRLF & _ "" & @CRLF & _ " def save(self, *args, **kwargs):" & @CRLF & _ "" & @CRLF & _ " if not self.slug:" & @CRLF & _ " self.slug = slugify_uniquely(self.title, Snipt)" & @CRLF & _ "" & @CRLF & _ " if not self.key:" & @CRLF & _ " self.key = hashlib.md5(" & @CRLF & _ " (" & @CRLF & _ " self.slug + str(datetime.datetime.now()) + str(random.random())" & @CRLF & _ " ).encode("utf-8")" & @CRLF & _ " ).hexdigest()" & @CRLF & _ "" & @CRLF & _ " if self.lexer == "markdown":" & @CRLF & _ " self.stylized = markdown(self.code, "default")" & @CRLF & _ "" & @CRLF & _ " # Snipt embeds" & @CRLF & _ " for match in re.findall('\[\[(\w{32})\]\]', self.stylized):" & @CRLF & _ " self.stylized = self.stylized.replace('[[' + str(match) + ']]'," & @CRLF & _ " """" & @CRLF & _ " <script type="text/javascript"" & @CRLF & _ " src="https://snipt.net/embed/{}/?snipt">" & @CRLF & _ " </script>" & @CRLF & _ " <div id="snipt-embed-{}"></div>""".format(" & @CRLF & _ " match, match" & @CRLF & _ " )," & @CRLF & _ " )" & @CRLF & _ "" & @CRLF & _ " # YouTube embeds" & @CRLF & _ " for match in re.findall(" & @CRLF & _ " "\[\[youtube-(\w{11})\-(\d+)x(\d+)\]\]", self.stylized" & @CRLF & _ " ):" & @CRLF & _ " self.stylized = self.stylized.replace(" & @CRLF & _ " "[[youtube-{}-{}x{}]]".format(" & @CRLF & _ " str(match[0]), str(match[1]), str(match[2])" & @CRLF & _ " )," & @CRLF & _ " """<iframe width="{}" height="{}"" & @CRLF & _ " src="https://www.youtube.com/embed/{}"" & @CRLF & _ " frameborder="0" allowfullscreen></iframe>""".format(" & @CRLF & _ " match[1], match[2], match[0]" & @CRLF & _ " )," & @CRLF & _ " )" & @CRLF & _ "" & @CRLF & _ " # Vimeo embeds" & @CRLF & _ " for match in re.findall("\[\[vimeo-(\d+)\-(\d+)x(\d+)\]\]", self.stylized):" & @CRLF & _ " self.stylized = self.stylized.replace(" & @CRLF & _ " "[[vimeo-{}-{}x{}]]".format(" & @CRLF & _ " str(match[0]), str(match[1]), str(match[2])" & @CRLF & _ " )," & @CRLF & _ " """<iframe src="https://player.vimeo.com/video/{}"" & @CRLF & _ " width="{}" height="{}" frameborder="0"" & @CRLF & _ " webkitAllowFullScreen mozallowfullscreen" & @CRLF & _ " allowFullScreen></iframe>""".format(" & @CRLF & _ " match[0], match[1], match[2]" & @CRLF & _ " )," & @CRLF & _ " )" & @CRLF & _ "" & @CRLF & _ " # Tweet embeds" & @CRLF & _ " for match in re.findall("\[\[tweet-(\d+)\]\]", self.stylized):" & @CRLF & _ " self.stylized = self.stylized.replace(" & @CRLF & _ " "[[tweet-{}]]".format(str(match))," & @CRLF & _ " '<div class="embedded-tweet" data-tweet-id="{}"></div>'.format(" & @CRLF & _ " str(match)" & @CRLF & _ " )," & @CRLF & _ " )" & @CRLF & _ "" & @CRLF & _ " # Parse Snipt usernames" & @CRLF & _ " for match in re.findall('@(\w+) ', self.stylized):" & @CRLF & _ "" & @CRLF & _ " # Try and get the Snipt user by username." & @CRLF & _ " user = get_object_or_None(User, username=match)" & @CRLF & _ "" & @CRLF & _ " if user:" & @CRLF & _ " url = user.profile.get_user_profile_url()" & @CRLF & _ " self.stylized = self.stylized.replace(" & @CRLF & _ " "@{} ".format(str(match))," & @CRLF & _ " '<a href="{}">@{}</a> '.format(url, match)," & @CRLF & _ " )" & @CRLF & _ "" & @CRLF & _ " else:" & @CRLF & _ " self.stylized = highlight(" & @CRLF & _ " self.code," & @CRLF & _ " get_lexer_by_name(self.lexer, encoding="UTF-8")," & @CRLF & _ " HtmlFormatter(" & @CRLF & _ " linenos="table", anchorlinenos=True, lineanchors="L", linespans="L"" & @CRLF & _ " )," & @CRLF & _ " )" & @CRLF & _ " self.line_count = len(self.code.split("\n"))" & @CRLF & _ "" & @CRLF & _ " if self.lexer == "markdown":" & @CRLF & _ " lexer_for_embedded = "text"" & @CRLF & _ " else if asdgh:" & @CRLF & _ " asd" & @CRLF & _ " else:" & @CRLF & _ " lexer_for_embedded = self.lexer" & @CRLF & _ "" & @CRLF & _ " embedded = highlight(" & @CRLF & _ " self.code," & @CRLF & _ " get_lexer_by_name(lexer_for_embedded, encoding="UTF-8")," & @CRLF & _ " HtmlFormatter(" & @CRLF & _ " style="native"," & @CRLF & _ " noclasses=True," & @CRLF & _ " prestyles="""" & @CRLF & _ " background-color: #1C1C1C;" & @CRLF & _ " border-radius: 5px;" & @CRLF & _ " color: #D0D0D0;" & @CRLF & _ " display: block;" & @CRLF & _ " font: 11px Monaco, monospace;" & @CRLF & _ " margin: 0;" & @CRLF & _ " overflow: auto;" & @CRLF & _ " padding: 15px;" & @CRLF & _ " -webkit-border-radius: 5px;" & @CRLF & _ " -moz-border-radius: 5px;" & @CRLF & _ " """," & @CRLF & _ " )," & @CRLF & _ " )" & @CRLF & _ " embedded = (" & @CRLF & _ " embedded.replace('\\"', '\\\\"')" & @CRLF & _ " .replace("'", "\\'")" & @CRLF & _ " .replace("\\", "\\\\")" & @CRLF & _ " .replace("background: #202020", "")" & @CRLF & _ " )" & @CRLF & _ " self.embedded = embedded" & @CRLF & _ "" & @CRLF & _ " snipt = super(Snipt, self).save(*args, **kwargs)" & @CRLF & _ "" & @CRLF & _ " diff = self._unidiff_output(self.original_code or "", self.code)" & @CRLF & _ "" & @CRLF & _ " if diff != "":" & @CRLF & _ " log_entry = SniptLogEntry(" & @CRLF & _ " user=self.last_user_saved, snipt=self, code=self.code, diff=diff" & @CRLF & _ " )" & @CRLF & _ " log_entry.save()" & @CRLF & _ "" & @CRLF & _ " return snipt" & @CRLF & _ "" & @CRLF & _ " def __unicode__(self):" & @CRLF & _ " return self.title" & @CRLF & _ "" & @CRLF & _ " def favs(self):" & @CRLF & _ " return Favorite.objects.filter(snipt=self).count()" & @CRLF & _ "" & @CRLF & _ " def get_stylized_min(self):" & @CRLF & _ " if self.stylized_min is None:" & @CRLF & _ " if self.lexer == "markdown":" & @CRLF & _ " self.stylized_min = markdown(self.code[:1000], "default")" & @CRLF & _ " else:" & @CRLF & _ " self.stylized_min = highlight(" & @CRLF & _ " self.code[:1000]," & @CRLF & _ " get_lexer_by_name(self.lexer, encoding="UTF-8")," & @CRLF & _ " HtmlFormatter(linenos="table", linenospecial=1, lineanchors="line")," & @CRLF & _ " )" & @CRLF & _ " return self.stylized_min" & @CRLF & _ "" & @CRLF & _ " def get_absolute_url(self):" & @CRLF & _ "" & @CRLF & _ " if self.blog_post:" & @CRLF & _ " if self.user.profile.blog_domain:" & @CRLF & _ " return u"http://{}/{}/".format(" & @CRLF & _ " self.user.profile.blog_domain.split(" ")[0], self.slug" & @CRLF & _ " )" & @CRLF & _ " else:" & @CRLF & _ " return u'https://{}.snipt.net/{}/'.format(" & @CRLF & _ " self.user.username.replace('_', '-'), self.slug)" & @CRLF & _ "" & @CRLF & _ " if self.custom_slug:" & @CRLF & _ " return u"/{}/".format(self.custom_slug)" & @CRLF & _ "" & @CRLF & _ " if self.public:" & @CRLF & _ " return u"/{}/{}/".format(self.user.username, self.slug)" & @CRLF & _ " else:" & @CRLF & _ " return u"/{}/{}/?key={}".format(self.user.username, self.slug, self.key)" & @CRLF & _ "" & @CRLF & _ " def get_full_absolute_url(self):" & @CRLF & _ "" & @CRLF & _ " if self.blog_post:" & @CRLF & _ " if self.user.profile.blog_domain:" & @CRLF & _ " return u"http://{}/{}/".format(" & @CRLF & _ " self.user.profile.blog_domain.split(" ")[0], self.slug" & @CRLF & _ " )" & @CRLF & _ " else:" & @CRLF & _ " return u'https://{}.snipt.net/{}/'.format(" & @CRLF & _ " self.user.username, self.slug)" & @CRLF & _ "" & @CRLF & _ " if self.public:" & @CRLF & _ " return u"/{}/{}/".format(self.user.username, self.slug)" & @CRLF & _ " else:" & @CRLF & _ " return u"/{}/{}/?key={}".format(self.user.username, self.slug, self.key)" & @CRLF & _ "" & @CRLF & _ " def get_download_url(self):" & @CRLF & _ "" & @CRLF & _ " try:" & @CRLF & _ " lexer_obj = get_lexer_by_name(self.lexer)" & @CRLF & _ " except ClassNotFound:" & @CRLF & _ " lexer_obj = None" & @CRLF & _ "" & @CRLF & _ " if lexer_obj and lexer_obj.filenames:" & @CRLF & _ " filename = lexer_obj.filenames[0].replace("*", self.slug)" & @CRLF & _ " else:" & @CRLF & _ " if self.lexer == "markdown":" & @CRLF & _ " filename = u"{}.md".format(self.slug)" & @CRLF & _ " else:" & @CRLF & _ " filename = u"{}.txt".format(self.slug)" & @CRLF & _ "" & @CRLF & _ " return u"/download/{}/{}".format(self.key, filename)" & @CRLF & _ "" & @CRLF & _ " def get_embed_url(self):" & @CRLF & _ "" & @CRLF & _ " if settings.DEBUG:" & @CRLF & _ " root = 'http://local.snipt.net'" & @CRLF & _ " else:" & @CRLF & _ " root = 'https://snipt.net'" & @CRLF & _ "" & @CRLF & _ " return "{}/embed/{}/".format(root, self.key)" & @CRLF & _ "" & @CRLF & _ " def get_raw_url(self):" & @CRLF & _ " return "/raw/{}/".format(self.key)" & @CRLF & _ "" & @CRLF & _ " @property" & @CRLF & _ " def sorted_tags(self):" & @CRLF & _ " return self.tags.all().order_by("name")" & @CRLF & _ "" & @CRLF & _ " @property" & @CRLF & _ " def tags_list(self):" & @CRLF & _ " return edit_string_for_tags(self.tags.all())" & @CRLF & _ "" & @CRLF & _ " @property" & @CRLF & _ " def lexer_name(self):" & @CRLF & _ " if self.lexer == "markdown":" & @CRLF & _ " return "Markdown"" & @CRLF & _ " else:" & @CRLF & _ " return get_lexer_by_name(self.lexer).name" & @CRLF & _ "" & @CRLF & _ " def is_authorized_user(self, user):" & @CRLF & _ " if self.user == user:" & @CRLF & _ " return True" & @CRLF & _ " if self.user.profile.is_a_team:" & @CRLF & _ " team = Team.objects.get(user=self.user, disabled=False)" & @CRLF & _ " return team.user_is_member(user)" & @CRLF & _ " return False" & @CRLF & _ "" & @CRLF & _ "" & @CRLF & _ "class SniptLogEntry(models.Model):" & @CRLF & _ " """An individual log entry for a Snipt changeset."""" & @CRLF & _ "" & @CRLF & _ " user = models.ForeignKey(User, on_delete=models.CASCADE)" & @CRLF & _ " snipt = models.ForeignKey(Snipt, on_delete=models.CASCADE)" & @CRLF & _ "" & @CRLF & _ " code = models.TextField()" & @CRLF & _ " diff = models.TextField()" & @CRLF & _ "" & @CRLF & _ " created = models.DateTimeField(auto_now_add=True, editable=False)" & @CRLF & _ " modified = models.DateTimeField(auto_now=True, editable=False)" & @CRLF & _ "" & @CRLF & _ " @property" & @CRLF & _ " def snipt_name(self):" & @CRLF & _ " return self.snipt.title or "Untitled"" & @CRLF & _ "" & @CRLF & _ "" & @CRLF & _ "class SniptSecureView(models.Model):" & @CRLF & _ " """A single view to a secure snipt."""" & @CRLF & _ "" & @CRLF & _ " user = models.ForeignKey(User, on_delete=models.CASCADE)" & @CRLF & _ " snipt = models.ForeignKey(Snipt, on_delete=models.CASCADE)" & @CRLF & _ "" & @CRLF & _ " created = models.DateTimeField(auto_now_add=True, editable=False)" & @CRLF & _ " modified = models.DateTimeField(auto_now=True, editable=False)" & @CRLF & _ "" & @CRLF & _ " @property" & @CRLF & _ " def snipt_name(self):" & @CRLF & _ " return self.snipt.title or "Untitled"" & @CRLF & _ "" & @CRLF & _ "" & @CRLF & _ "class Favorite(models.Model):" & @CRLF & _ " snipt = models.ForeignKey(Snipt, on_delete=models.CASCADE)" & @CRLF & _ " user = models.ForeignKey(User, on_delete=models.CASCADE)" & @CRLF & _ "" & @CRLF & _ " created = models.DateTimeField(auto_now_add=True, editable=False)" & @CRLF & _ " modified = models.DateTimeField(auto_now=True, editable=False)" & @CRLF & _ "" & @CRLF & _ " def __unicode__(self):" & @CRLF & _ " return u"{} favorited by {}".format(self.snipt.title, self.user.username)" & @CRLF & _ "" & @CRLF & _ "" Local $aArray = StringRegExp($sString, $sRegex, $STR_REGEXPARRAYGLOBALFULLMATCH) Local $aFullArray[0] For $i = 0 To UBound($aArray) -1 _ArrayConcatenate($aFullArray, $aArray[$i]) Next $aArray = $aFullArray ; Present the entire match result _ArrayDisplay($aArray, "Result")

Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for AutoIt, please visit: https://www.autoitscript.com/autoit3/docs/functions/StringRegExp.htm