Regular Expressions For Regular Folk

Introduction

Regular expressions (“regexes”) allow defining a pattern and executing it against strings. Substrings which match the pattern are termed “matches”.

A regular expression is a sequence of characters that define a search pattern.

Regex finds utility in:

Simultaneously, regular expressions are ill-suited for other kinds of problems:

There are several regex implementations—regex engines—each with its own quirks and features. This book will avoid going into the differences between these, instead sticking to features that are, for the most part, common across engines.

The example blocks throughout the book use JavaScript under the hood. As a result, the book may be slightly biased towards JavaScript’s regex engine.

Basics

Regular expressions are typically formatted as /<rules>/<flags>. Often people will drop the slashes and flags for brevity. We’ll get into the details of flags in a later chapter.

Let’s start with the regex /p/g. For now, please take the g flag for granted.

/p/g[RegExr] [Visual]
  • 1 matchpancake
    1. p
  • 3 matchespineapple
    1. p
    2. p
    3. p
  • 2 matchesapple
    1. p
    2. p
  • 0 matchesmango
    1. 0 matchesPlum

      As we can see, /p/g matches all lowercase p characters.

      Note

      Regular expressions are case-sensitive by default.

      Instances of the regex pattern found in an input string are termed “matches”.

      /pp/g[RegExr] [Visual]
      • 1 matchapple
        1. pp
      • 1 matchpineapple
        1. pp
      • 1 matchhappiness
        1. pp
      • 2 matchessipping apple juice
        1. pp
        2. pp
      • 0 matchespapaya

        Character Classes

        It’s possible to match a character from within a set of characters.

        /[aeiou]/g[RegExr] [Visual]
        • 4 matchesavocado
          1. a
          2. o
          3. a
          4. o
        • 2 matchesbrinjal
          1. i
          2. a
        • 3 matchesonion
          1. o
          2. i
          3. o
        • 0 matchesrhythm

          /[aeiou]/g matches all vowels in our input strings.

          Here’s another example of these in action:

          /p[aeiou]t/g[RegExr] [Visual]
          • 1 matchpat
            1. pat
          • 1 matchpet
            1. pet
          • 1 matchpit
            1. pit
          • 1 matchspat
            1. pat
          • 2 matchesspot a pet
            1. pot
            2. pet
          • 0 matchesbat

            We match a p, followed by one of the vowels, followed by a t.

            There’s an intuitive shortcut for matching a character from within a continuous range.

            /[a-z]/g[RegExr] [Visual]
            • 5 matchesjohn_s
              1. j
              2. o
              3. h
              4. n
              5. s
            • 5 matchesmatej29
              1. m
              2. a
              3. t
              4. e
              5. j
            • 5 matchesAyesha?!
              1. y
              2. e
              3. s
              4. h
              5. a
            • 0 matches4952
              1. 0 matchesLOUD
                Warning

                The regex /[a-z]/g matches only one character. In the example above, the strings have several matches each, each one character long. Not one long match.

                We can combine ranges and individual characters in our regexes.

                /[A-Za-z0-9_-]/g[RegExr] [Visual]
                • 6 matchesjohn_s
                  1. j
                  2. o
                  3. h
                  4. n
                  5. _
                  6. s
                • 7 matchesmatej29
                  1. m
                  2. a
                  3. t
                  4. e
                  5. j
                  6. 2
                  7. 9
                • 6 matchesAyesha?!
                  1. A
                  2. y
                  3. e
                  4. s
                  5. h
                  6. a
                • 4 matches4952
                  1. 4
                  2. 9
                  3. 5
                  4. 2
                • 4 matchesLOUD
                  1. L
                  2. O
                  3. U
                  4. D

                Our regex /[A-Za-z0-9_-]/g matches a single character, which must be (at least) one of the following:

                We can also “negate” these rules:

                /[^aeiou]/g[RegExr] [Visual]
                • 6 matchesUmbrella
                  1. U
                  2. m
                  3. b
                  4. r
                  5. l
                  6. l
                • 6 matchescauliflower
                  1. c
                  2. l
                  3. f
                  4. l
                  5. w
                  6. r
                • 0 matchesou

                  The only difference between the first regex of this chapter and /[^aeiou]/g is the ^ immediately after the opening bracket. Its purpose is to negate the rules defined within the brackets. We are now saying:

                  “match any character that is not any of a, e, i, o, and u

                  Examples

                  Prohibited username characters

                  /[^a-zA-Z_0-9-]/g[RegExr] [Visual]
                  • 0 matchesTheLegend27
                    1. 0 matchesWaterGuy12
                      1. 0 matchesSmokie_Bear
                        1. 7 matchesRobert'); DROP TABLE Students;--
                          1. '
                          2. )
                          3. ;
                          4. ;

                        Unambiguous characters

                        /[A-HJ-NP-Za-kmnp-z2-9]/g[RegExr] [Visual]
                        • 1 matchfoo
                          1. f
                        • 2 matcheslily
                          1. i
                          2. y
                        • 0 matcheslI0O1
                          1. 11 matchesunambiguity
                            1. u
                            2. n
                            3. a
                            4. m
                            5. b
                            6. i
                            7. g
                            8. u
                            9. i
                            10. t
                            11. y

                          Character Escapes

                          Character escapes act as shorthands for some common character classes.

                          Digit character — \d

                          The character escape \d matches digit characters, from 0 to 9. It is equivalent to the character class [0-9].

                          /\d/g[RegExr] [Visual]
                          • 4 matches2020
                            1. 2
                            2. 0
                            3. 2
                            4. 0
                          • 6 matches100/100
                            1. 1
                            2. 0
                            3. 0
                            4. 1
                            5. 0
                            6. 0
                          • 3 matchesIt costs $5.45
                            1. 5
                            2. 4
                            3. 5
                          • 6 matches3.14159
                            1. 3
                            2. 1
                            3. 4
                            4. 1
                            5. 5
                            6. 9
                          /\d\d/g[RegExr] [Visual]
                          • 2 matches2020
                            1. 20
                            2. 20
                          • 2 matches100/100
                            1. 10
                            2. 10
                          • 1 matchIt costs $5.45
                            1. 45
                          • 2 matches3.14159
                            1. 14
                            2. 15

                          \D is the negation of \d and is equivalent to [^0-9].

                          /\D/g[RegExr] [Visual]
                          • 0 matches2020
                            1. 1 match100/100
                              1. /
                            2. 11 matchesIt costs $5.45
                              1. I
                              2. t
                              3. c
                              4. o
                              5. s
                              6. t
                              7. s
                              8. $
                              9. .
                            3. 1 match3.14159
                              1. .

                            Word character — \w

                            The escape \w matches characters deemed “word characters”. These include:

                            It is thus equivalent to the character class [a-zA-Z0-9_].

                            /\w/g[RegExr] [Visual]
                            • 6 matchesjohn_s
                              1. j
                              2. o
                              3. h
                              4. n
                              5. _
                              6. s
                            • 7 matchesmatej29
                              1. m
                              2. a
                              3. t
                              4. e
                              5. j
                              6. 2
                              7. 9
                            • 6 matchesAyesha?!
                              1. A
                              2. y
                              3. e
                              4. s
                              5. h
                              6. a
                            • 4 matches4952
                              1. 4
                              2. 9
                              3. 5
                              4. 2
                            • 4 matchesLOUD
                              1. L
                              2. O
                              3. U
                              4. D
                            • 4 matcheslo-fi
                              1. l
                              2. o
                              3. f
                              4. i
                            • 6 matchesget out
                              1. g
                              2. e
                              3. t
                              4. o
                              5. u
                              6. t
                            • 6 matches21*2 = 42(1)
                              1. 2
                              2. 1
                              3. 2
                              4. 4
                              5. 2
                              6. 1
                            /\W/g[RegExr] [Visual]
                            • 0 matchesjohn_s
                              1. 2 matchesAyesha?!
                                1. ?
                                2. !
                              2. 0 matches4952
                                1. 0 matchesLOUD
                                  1. 1 matchlo-fi
                                    1. -
                                  2. 1 matchget out
                                  3. 3 matches;-;
                                    1. ;
                                    2. -
                                    3. ;
                                  4. 6 matches21*2 = 42(1)
                                    1. *
                                    2. =
                                    3. (
                                    4. )

                                  Whitespace character — \s

                                  The escape \s matches whitespace characters. The exact set of characters matched is dependent on the regex engine, but most include at least:

                                  Many also include vertical tabs (\v). Unicode-aware engines usually match all characters in the separator category.

                                  The technicalities, however, will usually not be important.

                                  /\s/g[RegExr] [Visual]
                                  • 1 matchword word
                                  • 2 matchestabs vs spaces
                                  • 0 matchessnake_case.jpg
                                    /\S/g[RegExr] [Visual]
                                    • 8 matchesword word
                                      1. w
                                      2. o
                                      3. r
                                      4. d
                                      5. w
                                      6. o
                                      7. r
                                      8. d
                                    • 12 matchestabs vs spaces
                                      1. t
                                      2. a
                                      3. b
                                      4. s
                                      5. v
                                      6. s
                                      7. s
                                      8. p
                                      9. a
                                      10. c
                                      11. e
                                      12. s
                                    • 14 matchessnake_case.jpg
                                      1. s
                                      2. n
                                      3. a
                                      4. k
                                      5. e
                                      6. _
                                      7. c
                                      8. a
                                      9. s
                                      10. e
                                      11. .
                                      12. j
                                      13. p
                                      14. g

                                    Any character — .

                                    While not a typical character escape, . matches any1 character.

                                    /./g[RegExr] [Visual]
                                    • 6 matchesjohn_s
                                      1. j
                                      2. o
                                      3. h
                                      4. n
                                      5. _
                                      6. s
                                    • 8 matchesAyesha?!
                                      1. A
                                      2. y
                                      3. e
                                      4. s
                                      5. h
                                      6. a
                                      7. ?
                                      8. !
                                    • 4 matches4952
                                      1. 4
                                      2. 9
                                      3. 5
                                      4. 2
                                    • 4 matchesLOUD
                                      1. L
                                      2. O
                                      3. U
                                      4. D
                                    • 5 matcheslo-fi
                                      1. l
                                      2. o
                                      3. -
                                      4. f
                                      5. i
                                    • 7 matchesget out
                                      1. g
                                      2. e
                                      3. t
                                      4. o
                                      5. u
                                      6. t
                                    • 3 matches;-;
                                      1. ;
                                      2. -
                                      3. ;
                                    • 12 matches21*2 = 42(1)
                                      1. 2
                                      2. 1
                                      3. *
                                      4. 2
                                      5. =
                                      6. 4
                                      7. 2
                                      8. (
                                      9. 1
                                      10. )

                                    1. Except the newline character \n. This can be changed using the “dotAll” flag, if supported by the regex engine in question.

                                    Escapes

                                    In regex, some characters have special meanings as we will explore across the chapters:


                                    When we wish to match these characters literally, we need to “escape” them.

                                    This is done by prefixing the character with a \.


                                    /\(paren\)/g[RegExr] [Visual]
                                    • 0 matchesparen
                                      1. 0 matchesparents
                                        1. 1 match(paren)
                                          1. (paren)
                                        2. 1 matcha (paren)
                                          1. (paren)
                                        /(paren)/g[RegExr] [Visual]
                                        • 1 matchparen
                                          1. paren
                                        • 1 matchparents
                                          1. paren
                                        • 1 match(paren)
                                          1. paren
                                        • 1 matcha (paren)
                                          1. paren

                                        /example\.com/g[RegExr] [Visual]
                                        • 1 matchexample.com
                                          1. example.com
                                        • 1 matcha.example.com/foo
                                          1. example.com
                                        • 0 matchesexample_com
                                          1. 0 matchesexample@com
                                            1. 0 matchesexample_com/foo
                                              /example.com/g[RegExr] [Visual]
                                              • 1 matchexample.com
                                                1. example.com
                                              • 1 matcha.example.com/foo
                                                1. example.com
                                              • 1 matchexample_com
                                                1. example_com
                                              • 1 matchexample@com
                                                1. example@com
                                              • 1 matchexample_com/foo
                                                1. example_com

                                              /A\+/g[RegExr] [Visual]
                                              • 1 matchA+
                                                1. A+
                                              • 1 matchA+B
                                                1. A+
                                              • 1 match5A+
                                                1. A+
                                              • 0 matchesAAA
                                                /A+/g[RegExr] [Visual]
                                                • 1 matchA+
                                                  1. A
                                                • 1 matchA+B
                                                  1. A
                                                • 1 match5A+
                                                  1. A
                                                • 1 matchAAA
                                                  1. AAA

                                                /worth \$5/g[RegExr] [Visual]
                                                • 1 matchworth $5
                                                  1. worth $5
                                                • 1 matchworth $54
                                                  1. worth $5
                                                • 1 matchnot worth $5
                                                  1. worth $5
                                                /worth $5/g[RegExr] [Visual]
                                                • 0 matchesworth $5
                                                  1. 0 matchesworth $54
                                                    1. 0 matchesnot worth $5

                                                      Examples

                                                      JavaScript in-line comments

                                                      /\/\/.*/g[RegExr] [Visual]
                                                      • 1 matchconsole.log(); // comment
                                                        1. // comment
                                                      • 1 matchconsole.log(); // // comment
                                                        1. // // comment
                                                      • 0 matchesconsole.log();

                                                        Asterisk-surrounded substrings

                                                        /\*[^\*]*\*/g[RegExr] [Visual]
                                                        • 1 matchhere be *italics*
                                                          1. *italics*
                                                        • 1 matchpermitted**
                                                          1. **
                                                        • 1 matcha*b*c*d
                                                          1. *b*
                                                        • 2 matchesa*b*c*d*e
                                                          1. *b*
                                                          2. *d*
                                                        • 0 matchesa️bcd

                                                          The first and last asterisks are literal since they are escaped — \*.

                                                          The asterisk inside the character class does not necessarily need to be escaped1, but I’ve escaped it anyway for clarity.

                                                          The asterisk immediately following the character class indicates repetition of the character class, which we’ll explore in chapters that follow.


                                                          1. Many special characters that would otherwise have special meanings are treated literally by default inside character classes.

                                                          Groups

                                                          Groups, as the name suggests, are meant to be used to “group” components of regular expressions. These groups can be used to:

                                                          We’ll see how to do a lot of this in later chapters, but learning how groups work will allow us to study some great examples in these later chapters.

                                                          Capturing groups

                                                          Capturing groups are denoted by (). Here’s an expository example:

                                                          /a(bcd)e/g[RegExr] [Visual]
                                                          • 1 matchabcde
                                                            1. abcde
                                                          • 1 matchabcdefg?
                                                            1. abcde
                                                          • 1 matchabcde
                                                            1. abcde

                                                          Capturing groups allow extracting parts of matches.

                                                          /\{([^{}]*)\}/g[RegExr] [Visual]
                                                          • 1 match{braces}
                                                            1. {braces}
                                                          • 2 matches{two} {pairs}
                                                            1. {two}
                                                            2. {pairs}
                                                          • 1 match{ {nested} }
                                                            1. {nested}
                                                          • 1 match{ incomplete } }
                                                            1. { incomplete }
                                                          • 1 match{}
                                                            1. {}
                                                          • 0 matches{unmatched

                                                            Using your language’s regex functions, you would be able to extract the text between the matched braces for each of these strings.

                                                            Capturing groups can also be used to group regex parts for ease of repetition of said group. While we will cover repetition in detail in chapters that follow, here’s an example that demonstrates the utility of groups.

                                                            /a(bcd)+e/g[RegExr] [Visual]
                                                            • 1 matchabcdefg
                                                              1. abcde
                                                            • 1 matchabcdbcde
                                                              1. abcdbcde
                                                            • 1 matchabcdbcdbcdef
                                                              1. abcdbcdbcde
                                                            • 0 matchesae

                                                              Other times, they are used to group logically similar parts of the regex for readability.

                                                              /(\d\d\d\d)-W(\d\d)/g[RegExr] [Visual]
                                                              • 1 match2020-W12
                                                                1. 2020-W12
                                                              • 1 match1970-W01
                                                                1. 1970-W01
                                                              • 1 match2050-W50-6
                                                                1. 2050-W50
                                                              • 1 match12050-W50
                                                                1. 2050-W50

                                                              Backreferences

                                                              Backreferences allow referring to previously captured substrings.

                                                              The match from the first group would be \1, that from the second would be \2, and so on…

                                                              /([abc])=\1=\1/g[RegExr] [Visual]
                                                              • 1 matcha=a=a
                                                                1. a=a=a
                                                              • 1 matchab=b=b
                                                                1. b=b=b
                                                              • 0 matchesa=b=c

                                                                Backreferences cannot be used to reduce duplication in regexes. They refer to the match of groups, not the pattern.

                                                                /[abc][abc][abc]/g[RegExr] [Visual]
                                                                • 1 matchabc
                                                                  1. abc
                                                                • 1 matcha cable
                                                                  1. cab
                                                                • 1 matchaaa
                                                                  1. aaa
                                                                • 1 matchbbb
                                                                  1. bbb
                                                                • 1 matchccc
                                                                  1. ccc
                                                                /([abc])\1\1/g[RegExr] [Visual]
                                                                • 0 matchesabc
                                                                  1. 0 matchesa cable
                                                                    1. 1 matchaaa
                                                                      1. aaa
                                                                    2. 1 matchbbb
                                                                      1. bbb
                                                                    3. 1 matchccc
                                                                      1. ccc

                                                                    Here’s an example that demonstrates a common use-case:

                                                                    /\w+([,|])\w+\1\w+/g[RegExr] [Visual]
                                                                    • 1 matchcomma,separated,values
                                                                      1. comma,separated,values
                                                                    • 1 matchpipe|separated|values
                                                                      1. pipe|separated|values
                                                                    • 0 matcheswb|mixed,delimiters
                                                                      1. 0 matcheswb,mixed|delimiters

                                                                        This cannot be achieved with a repeated character classes.

                                                                        /\w+[,|]\w+[,|]\w+/g[RegExr] [Visual]
                                                                        • 1 matchcomma,separated,values
                                                                          1. comma,separated,values
                                                                        • 1 matchpipe|separated|values
                                                                          1. pipe|separated|values
                                                                        • 1 matchwb|mixed,delimiters
                                                                          1. wb|mixed,delimiters
                                                                        • 1 matchwb,mixed|delimiters
                                                                          1. wb,mixed|delimiters

                                                                        Non-capturing groups

                                                                        Non-capturing groups are very similar to capturing groups, except that they don’t create “captures”. They take the form (?:).

                                                                        Non-capturing groups are usually used in conjunction with capturing groups. Perhaps you are attempting to extract some parts of the matches using capturing groups. You may wish to use a group without messing up the order of the captures. This is where non-capturing groups come handy.

                                                                        Examples

                                                                        Query String Parameters

                                                                        /^\?(\w+)=(\w+)(?:&(\w+)=(\w+))*$/g[RegExr] [Visual]
                                                                        • 0 matches
                                                                          1. 0 matches?
                                                                            1. 1 match?a=b
                                                                              1. ?a=b
                                                                            2. 1 match?a=b&foo=bar
                                                                              1. ?a=b&foo=bar

                                                                            We match the first key-value pair separately because that allows us to use &, the separator, as part of the repeating group.

                                                                            (Basic) HTML tags

                                                                            As a rule of thumb, do not use regex to match XML/HTML.1234

                                                                            However, it’s a relevant example:

                                                                            /<([a-z]+)+>(.*)<\/\1>/gi[RegExr] [Visual]
                                                                            • 1 match<p>paragraph</p>
                                                                              1. <p>paragraph</p>
                                                                            • 1 match<li>list item</li>
                                                                              1. <li>list item</li>
                                                                            • 1 match<p><span>nesting</span></p>
                                                                              1. <p><span>nesting</span></p>
                                                                            • 0 matches<p>hmm</li>
                                                                              1. 1 match<p><p>not clever</p></p></p>
                                                                                1. <p><p>not clever</p></p></p>

                                                                              Names

                                                                              Find: \b(\w+) (\w+)\b

                                                                              Replace: $2, $15

                                                                              Before

                                                                              John Doe
                                                                              Jane Doe
                                                                              Sven Svensson
                                                                              Janez Novak
                                                                              Janez Kranjski
                                                                              Tim Joe
                                                                              

                                                                              After

                                                                              Doe, John
                                                                              Doe, Jane
                                                                              Svensson, Sven
                                                                              Novak, Janez
                                                                              Kranjski, Janez
                                                                              Joe, Tim
                                                                              

                                                                              Backreferences and plurals

                                                                              Find: \bword(s?)\b

                                                                              Replace: phrase$15

                                                                              Before

                                                                              This is a paragraph with some words.
                                                                              
                                                                              Some instances of the word "word" are in their plural form: "words".
                                                                              
                                                                              Yet, some are in their singular form: "word".
                                                                              

                                                                              After

                                                                              This is a paragraph with some phrases.
                                                                              
                                                                              Some instances of the phrase "phrase" are in their plural form: "phrases".
                                                                              
                                                                              Yet, some are in their singular form: "phrase".
                                                                              

                                                                              Repetition

                                                                              Repetition is a powerful and ubiquitous regex feature. There are several ways to represent repetition in regex.

                                                                              Making things optional

                                                                              We can make parts of regex optional using the ? operator.

                                                                              /a?/g[RegExr] [Visual]
                                                                              • 1 match
                                                                              • 2 matchesa
                                                                                1. a
                                                                              • 3 matchesaa
                                                                                1. a
                                                                                2. a
                                                                              • 4 matchesaaa
                                                                                1. a
                                                                                2. a
                                                                                3. a
                                                                              • 5 matchesaaaa
                                                                                1. a
                                                                                2. a
                                                                                3. a
                                                                                4. a
                                                                              • 6 matchesaaaaa
                                                                                1. a
                                                                                2. a
                                                                                3. a
                                                                                4. a
                                                                                5. a

                                                                              Here’s another example:

                                                                              /https?/g[RegExr] [Visual]
                                                                              • 1 matchhttp
                                                                                1. http
                                                                              • 1 matchhttps
                                                                                1. https
                                                                              • 1 matchhttp/2
                                                                                1. http
                                                                              • 1 matchshttp
                                                                                1. http
                                                                              • 0 matchesftp

                                                                                Here the s following http is optional.

                                                                                We can also make capturing and non-capturing groups optional.

                                                                                /url: (www\.)?example\.com/g[RegExr] [Visual]
                                                                                • 1 matchurl: example.com
                                                                                  1. url: example.com
                                                                                • 1 matchurl: www.example.com/foo
                                                                                  1. url: www.example.com
                                                                                • 1 matchHere's the url: example.com.
                                                                                  1. url: example.com

                                                                                Zero or more

                                                                                If we wish to match zero or more of a token, we can suffix it with *.

                                                                                /a*/g[RegExr] [Visual]
                                                                                • 1 match
                                                                                • 2 matchesa
                                                                                  1. a
                                                                                • 2 matchesaa
                                                                                  1. aa
                                                                                • 2 matchesaaa
                                                                                  1. aaa
                                                                                • 2 matchesaaaa
                                                                                  1. aaaa
                                                                                • 2 matchesaaaaa
                                                                                  1. aaaaa

                                                                                Our regex matches even an empty string "".

                                                                                One or more

                                                                                If we wish to match one or more of a token, we can suffix it with a +.

                                                                                /a+/g[RegExr] [Visual]
                                                                                • 0 matches
                                                                                  1. 1 matcha
                                                                                    1. a
                                                                                  2. 1 matchaa
                                                                                    1. aa
                                                                                  3. 1 matchaaa
                                                                                    1. aaa
                                                                                  4. 1 matchaaaa
                                                                                    1. aaaa
                                                                                  5. 1 matchaaaaa
                                                                                    1. aaaaa

                                                                                  Exactly x times

                                                                                  If we wish to match a particular token exactly x times, we can suffix it with {x}. This is functionally identical to repeatedly copy-pasting the token x times.

                                                                                  /a{3}/g[RegExr] [Visual]
                                                                                  • 0 matches
                                                                                    1. 0 matchesa
                                                                                      1. 0 matchesaa
                                                                                        1. 1 matchaaa
                                                                                          1. aaa
                                                                                        2. 1 matchaaaa
                                                                                          1. aaa
                                                                                        3. 1 matchaaaaa
                                                                                          1. aaa

                                                                                        Here’s an example that matches an uppercase six-character hex colour code.

                                                                                        /#[0-9A-F]{6}/g[RegExr] [Visual]
                                                                                        • 1 match#AE25AE
                                                                                          1. #AE25AE
                                                                                        • 1 match#663399
                                                                                          1. #663399
                                                                                        • 1 matchHow about #73FA79?
                                                                                          1. #73FA79
                                                                                        • 1 matchPart of #73FA79BAC too
                                                                                          1. #73FA79
                                                                                        • 0 matches#FFF
                                                                                          1. 0 matches#a2ca2c

                                                                                            Here, the token {6} applies to the character class [0-9A-F].

                                                                                            Between min and max times

                                                                                            If we wish to match a particular token between min and max (inclusive) times, we can suffix it with {min,max}.

                                                                                            /a{2,4}/g[RegExr] [Visual]
                                                                                            • 0 matches
                                                                                              1. 0 matchesa
                                                                                                1. 1 matchaa
                                                                                                  1. aa
                                                                                                2. 1 matchaaa
                                                                                                  1. aaa
                                                                                                3. 1 matchaaaa
                                                                                                  1. aaaa
                                                                                                4. 1 matchaaaaa
                                                                                                  1. aaaa
                                                                                                Warning

                                                                                                There must be no space after the comma in {min,max}.

                                                                                                At least x times

                                                                                                If we wish to match a particular token at least x times, we can suffix it with {x,}. Think of it as {min,max}, but without an upper bound.

                                                                                                /a{2,}/g[RegExr] [Visual]
                                                                                                • 0 matches
                                                                                                  1. 0 matchesa
                                                                                                    1. 1 matchaa
                                                                                                      1. aa
                                                                                                    2. 1 matchaaa
                                                                                                      1. aaa
                                                                                                    3. 1 matchaaaa
                                                                                                      1. aaaa
                                                                                                    4. 1 matchaaaaa
                                                                                                      1. aaaaa

                                                                                                    A note on greediness

                                                                                                    Regular expressions, by default, are greedy. They attempt to match as much as possible.

                                                                                                    /a*/g[RegExr] [Visual]
                                                                                                    • 2 matchesaaaaaa
                                                                                                      1. aaaaaa
                                                                                                    /".*"/g[RegExr] [Visual]
                                                                                                    • 1 match"quote"
                                                                                                      1. "quote"
                                                                                                    • 1 match"quote", "quote"
                                                                                                      1. "quote", "quote"
                                                                                                    • 1 match"quote"quote"
                                                                                                      1. "quote"quote"

                                                                                                    Suffixing a repetition operator (?, *, +, …) with a ?, one can make it “lazy”.

                                                                                                    /".*?"/g[RegExr] [Visual]
                                                                                                    • 1 match"quote"
                                                                                                      1. "quote"
                                                                                                    • 2 matches"quote", "quote"
                                                                                                      1. "quote"
                                                                                                      2. "quote"
                                                                                                    • 1 match"quote"quote"
                                                                                                      1. "quote"

                                                                                                    Here, this could also be achieved by using [^"] instead of . (as is best practice).

                                                                                                    /"[^"]*"/g[RegExr] [Visual]
                                                                                                    • 1 match"quote"
                                                                                                      1. "quote"
                                                                                                    • 2 matches"quote", "quote"
                                                                                                      1. "quote"
                                                                                                      2. "quote"
                                                                                                    • 1 match"quote"quote"
                                                                                                      1. "quote"

                                                                                                    […] Lazy will stop as soon as the condition is satisfied, but greedy means it will stop only once the condition is not satisfied any more

                                                                                                    Andrew S on StackOverflow

                                                                                                    /<.+>/g[RegExr] [Visual]
                                                                                                    • 1 match<em>g r e e d y</em>
                                                                                                      1. <em>g r e e d y</em>
                                                                                                    /<.+?>/g[RegExr] [Visual]
                                                                                                    • 2 matches<em>lazy</em>
                                                                                                      1. <em>
                                                                                                      2. </em>

                                                                                                    Examples

                                                                                                    Bitcoin address

                                                                                                    /([13][a-km-zA-HJ-NP-Z0-9]{26,33})/g[RegExr] [Visual]
                                                                                                    • 1 match3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v
                                                                                                      1. 3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v
                                                                                                    • 1 match1HQ3Go3ggs8pFnXuHVHRytPCq5fGG8Hbhx
                                                                                                      1. 1HQ3Go3ggs8pFnXuHVHRytPCq5fGG8Hbhx
                                                                                                    • 1 match2016-03-09,18f1yugoAJuXcHAbsuRVLQC9TezJ
                                                                                                      1. 18f1yugoAJuXcHAbsuRVLQC9TezJ

                                                                                                    Youtube Video

                                                                                                    /(?:https?:\/\/)?(?:www\.)?youtube\.com\/watch\?.*?v=([^&\s]+).*/gm[RegExr] [Visual]
                                                                                                    • 1 matchyoutube.com/watch?feature=sth&v=dQw4w9WgXcQ
                                                                                                      1. youtube.com/watch?feature=sth&v=dQw4w9WgXcQ
                                                                                                    • 1 matchhttps://www.youtube.com/watch?v=dQw4w9WgXcQ
                                                                                                      1. https://www.youtube.com/watch?v=dQw4w9WgXcQ
                                                                                                    • 1 matchwww.youtube.com/watch?v=dQw4w9WgXcQ
                                                                                                      1. www.youtube.com/watch?v=dQw4w9WgXcQ
                                                                                                    • 1 matchyoutube.com/watch?v=dQw4w9WgXcQ
                                                                                                      1. youtube.com/watch?v=dQw4w9WgXcQ
                                                                                                    • 1 matchfakeyoutube.com/watch?v=dQw4w9WgXcQ
                                                                                                      1. youtube.com/watch?v=dQw4w9WgXcQ

                                                                                                    We can adjust this to not match the last broken link using anchors, which we shall encounter soon.

                                                                                                    Alternation

                                                                                                    Alternation allows matching one of several phrases. This is more powerful than character classes, which are limited to characters.

                                                                                                    Delimit the set of phrases with pipes—|.

                                                                                                    /foo|bar|baz/g[RegExr] [Visual]
                                                                                                    • 2 matchesfoo baz
                                                                                                      1. foo
                                                                                                      2. baz
                                                                                                    • 1 matchYour food
                                                                                                      1. foo
                                                                                                    • 1 matchBehind bars
                                                                                                      1. bar

                                                                                                    One of foo, bar, and baz


                                                                                                    If only a part of the regex is to be “alternated”, wrap that part with a group—capturing or non-capturing.

                                                                                                    /Try (foo|bar|baz)/g[RegExr] [Visual]
                                                                                                    • 1 matchTry foo
                                                                                                      1. Try foo
                                                                                                    • 1 matchTry bar
                                                                                                      1. Try bar
                                                                                                    • 1 matchTry baz
                                                                                                      1. Try baz
                                                                                                    • 1 matchTry food
                                                                                                      1. Try foo

                                                                                                    Try followed by one of foo, bar, and baz


                                                                                                    Matching numbers between 100 and 250:

                                                                                                    /1\d\d|2[0-4]\d|250/g[RegExr] [Visual]
                                                                                                    • 3 matches100, 157, 199
                                                                                                      1. 100
                                                                                                      2. 157
                                                                                                      3. 199
                                                                                                    • 2 matches139 + 140 = 279
                                                                                                      1. 139
                                                                                                      2. 140
                                                                                                    • 1 match201 INR
                                                                                                      1. 201
                                                                                                    • 1 match$220
                                                                                                      1. 220
                                                                                                    • 1 match250
                                                                                                      1. 250
                                                                                                    • 1 match1250
                                                                                                      1. 125
                                                                                                    • 2 matchese = 2.71828182...
                                                                                                      1. 182
                                                                                                      2. 182
                                                                                                    • 0 matches251
                                                                                                      1. 0 matches729

                                                                                                        This can be generalized to match arbitrary number ranges!

                                                                                                        Examples

                                                                                                        Hex colours

                                                                                                        Let’s improve one of our older examples to also match shorthand hex colours.

                                                                                                        /#([0-9A-F]{6}|[0-9A-F]{3})/g[RegExr] [Visual]
                                                                                                        • 1 match#AE25AE
                                                                                                          1. #AE25AE
                                                                                                        • 1 match#663399
                                                                                                          1. #663399
                                                                                                        • 1 matchHow about #73FA79?
                                                                                                          1. #73FA79
                                                                                                        • 1 matchPart of #73FA79BAC too
                                                                                                          1. #73FA79
                                                                                                        • 1 match#FFF
                                                                                                          1. #FFF
                                                                                                        • 0 matches#a2ca2c

                                                                                                          It is important that [0-9A-F]{6} comes before [0-9A-F]{3}. Else:

                                                                                                          /#([0-9A-F]{3}|[0-9A-F]{6})/g[RegExr] [Visual]
                                                                                                          • 1 match#AE25AE
                                                                                                            1. #AE2
                                                                                                          • 1 match#663399
                                                                                                            1. #663
                                                                                                          • 1 matchHow about #73FA79?
                                                                                                            1. #73F
                                                                                                          • 1 matchPart of #73FA79BAC too
                                                                                                            1. #73F
                                                                                                          • 1 match#FFF
                                                                                                            1. #FFF
                                                                                                          • 0 matches#a2ca2c
                                                                                                            Tip

                                                                                                            Regex engines try alternatives from the left to the right.

                                                                                                            Roman numerals

                                                                                                            /^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$/g[RegExr] [Visual]
                                                                                                            • 1 matchMMXX
                                                                                                              1. MMXX
                                                                                                            • 1 matchVI
                                                                                                              1. VI
                                                                                                            • 1 matchXX
                                                                                                              1. XX
                                                                                                            • 1 matchXI
                                                                                                              1. XI
                                                                                                            • 0 matchesIXI
                                                                                                              1. 0 matchesVV

                                                                                                                Flags

                                                                                                                Flags (or “modifiers”) allow us to put regexes into different “modes”.

                                                                                                                Flags are the part after the final / in /pattern/.

                                                                                                                Different engines support different flags. We’ll explore some of the most common flags here.

                                                                                                                Global (g)

                                                                                                                All examples thus far have had the global flag. When the global flag isn’t enabled, the regex doesn’t match anything beyond the first match.

                                                                                                                /[aeiou]/g[RegExr] [Visual]
                                                                                                                • 3 matchescorona
                                                                                                                  1. o
                                                                                                                  2. o
                                                                                                                  3. a
                                                                                                                • 2 matchescancel
                                                                                                                  1. a
                                                                                                                  2. e
                                                                                                                • 0 matchesrhythm
                                                                                                                  /[aeiou]/[RegExr] [Visual]
                                                                                                                  • 1 matchcorona
                                                                                                                    1. o
                                                                                                                  • 1 matchcancel
                                                                                                                    1. a
                                                                                                                  • 0 matchesrhythm

                                                                                                                    (Case) Insensitive (i)

                                                                                                                    As the name suggests, enabling this flag makes the regex case-insensitive in its matching.

                                                                                                                    /#[0-9A-F]{6}/i[RegExr] [Visual]
                                                                                                                    • 1 match#AE25AE
                                                                                                                      1. #AE25AE
                                                                                                                    • 1 match#663399
                                                                                                                      1. #663399
                                                                                                                    • 1 matchEven #a2ca2c?
                                                                                                                      1. #a2ca2c
                                                                                                                    • 0 matches#FFF
                                                                                                                      /#[0-9A-F]{6}/[RegExr] [Visual]
                                                                                                                      • 1 match#AE25AE
                                                                                                                        1. #AE25AE
                                                                                                                      • 1 match#663399
                                                                                                                        1. #663399
                                                                                                                      • 0 matchesEven #a2ca2c?
                                                                                                                        1. 0 matches#FFF
                                                                                                                          /#[0-9A-Fa-f]{6}/[RegExr] [Visual]
                                                                                                                          • 1 match#AE25AE
                                                                                                                            1. #AE25AE
                                                                                                                          • 1 match#663399
                                                                                                                            1. #663399
                                                                                                                          • 1 matchEven #a2ca2c?
                                                                                                                            1. #a2ca2c
                                                                                                                          • 0 matches#FFF

                                                                                                                            Multiline (m)

                                                                                                                            Limited Support

                                                                                                                            In Ruby, the m flag performs other functions.

                                                                                                                            The multiline flag has to do with the regex’s handling of anchors when dealing with “multiline” strings—strings that include newlines (\n). By default, the regex /^foo$/ would match only "foo".

                                                                                                                            We might want it to match foo when it is in a line by itself in a multiline string.

                                                                                                                            Let’s take the string "bar\nfoo\nbaz" as an example:

                                                                                                                            bar
                                                                                                                            foo
                                                                                                                            baz
                                                                                                                            

                                                                                                                            Without the multiline flag, the string above would be considered as a single line bar\nfoo\nbaz for matching purposes. The regex ^foo$ would thus not match anything.

                                                                                                                            With the multiline flag, the input would be considered as three “lines”: bar, foo, and baz. The regex ^foo$ would match the line in the middle—foo.

                                                                                                                            Dot-all (s)

                                                                                                                            Limited Support

                                                                                                                            JavaScript, prior to ES2018, did not support this flag. Ruby does not support the flag, instead using m for the same.

                                                                                                                            The . typically matches any character except newlines. With the dot-all flag, it matches newlines too.

                                                                                                                            Unicode (u)

                                                                                                                            In the presence of the u flag, the regex and the input string will be interpreted in a unicode-aware way. The details of this are implementation-dependent, but here are some things to expect:

                                                                                                                            Whitespace extended (x)

                                                                                                                            When this flag is set, whitespace in the pattern is ignored (unless escaped or in a character class). Additionally, characters following # on any line are ignored. This allows for comments and is useful when writing complex patterns.

                                                                                                                            Here’s an example from Advanced Examples, formatted to take advantage of the whitespace extended flag:

                                                                                                                            ^                   # start of line
                                                                                                                                (
                                                                                                                                    [+-]?       # sign
                                                                                                                                    (?=\.\d|\d) # don't match `.`
                                                                                                                                    (?:\d+)?    # integer part
                                                                                                                                    (?:\.?\d*)  # fraction part
                                                                                                                                )
                                                                                                                                (?:             # optional exponent part
                                                                                                                                    [eE]
                                                                                                                                    (
                                                                                                                                        [+-]?   # optional sign
                                                                                                                                        \d+     # power
                                                                                                                                    )
                                                                                                                                )?
                                                                                                                            $                   # end of line
                                                                                                                            

                                                                                                                            Anchors

                                                                                                                            Anchors do not match anything by themselves. Instead, they place restrictions on where matches may appear—“anchoring” matches.

                                                                                                                            You could also think about anchors as “invisible characters”.

                                                                                                                            Beginning of line — ^

                                                                                                                            Marked by a caret (^) at the beginning of the regex, this anchor makes it necessary for the rest of the regex to match from the beginning of the string.

                                                                                                                            You can think of it as matching an invisible character always present at the beginning of the string.

                                                                                                                            /^p/g[RegExr] [Visual]
                                                                                                                            • 1 matchphotoshop
                                                                                                                              1. p
                                                                                                                            • 1 matchpineapple
                                                                                                                              1. p
                                                                                                                            • 0 matchestap
                                                                                                                              1. 0 matchesapple
                                                                                                                                1. 1 matchppap
                                                                                                                                  1. p
                                                                                                                                2. 0 matchesmango

                                                                                                                                  End of line — $

                                                                                                                                  This anchor is marked by a dollar ($) at the end of the regex. It is analogous to the beginning of the line anchor.

                                                                                                                                  You can think of it as matching an invisible character always present at the end of the string.

                                                                                                                                  /p$/g[RegExr] [Visual]
                                                                                                                                  • 1 matchphotoshop
                                                                                                                                    1. p
                                                                                                                                  • 0 matchespineapple
                                                                                                                                    1. 0 matchesapple
                                                                                                                                      1. 1 matchapp
                                                                                                                                        1. p
                                                                                                                                      2. 0 matchesPlum
                                                                                                                                        1. 0 matchesmango

                                                                                                                                          The ^ and $ anchors are often used in conjunction to ensure that the regex matches the entirety of the string, rather than merely a part.

                                                                                                                                          /^p$/g[RegExr] [Visual]
                                                                                                                                          • 1 matchp
                                                                                                                                            1. p
                                                                                                                                          • 0 matchespi
                                                                                                                                            1. 0 matchespea
                                                                                                                                              1. 0 matchestarp
                                                                                                                                                1. 0 matchesapple

                                                                                                                                                  Let’s revisit an example from Repetition, and add the two anchors at the ends of the regex.

                                                                                                                                                  /^https?$/g[RegExr] [Visual]
                                                                                                                                                  • 1 matchhttp
                                                                                                                                                    1. http
                                                                                                                                                  • 1 matchhttps
                                                                                                                                                    1. https
                                                                                                                                                  • 0 matcheshttp/2
                                                                                                                                                    1. 0 matchesshttp
                                                                                                                                                      1. 0 matchesftp

                                                                                                                                                        In the absence of the anchors, http/2 and shttp would also match.

                                                                                                                                                        Word boundary — \b

                                                                                                                                                        A word boundary is a position between a word character and a non-word character.

                                                                                                                                                        The word boundary anchor, \b, matches an imaginary invisible character that exists between consecutive word and non-word characters.

                                                                                                                                                        /\bp/g[RegExr] [Visual]
                                                                                                                                                        • 1 matchpeach
                                                                                                                                                          1. p
                                                                                                                                                        • 1 matchbanana, peach
                                                                                                                                                          1. p
                                                                                                                                                        • 1 matchbanana+peach
                                                                                                                                                          1. p
                                                                                                                                                        • 1 matchbanana-peach
                                                                                                                                                          1. p
                                                                                                                                                        • 0 matchesbanana_peach
                                                                                                                                                          1. 0 matchesbanana%20peach
                                                                                                                                                            1. 0 matchesgrape
                                                                                                                                                              Note

                                                                                                                                                              Words characters include a-z, A-Z, 0-9, and _.

                                                                                                                                                              /\bp\b/g[RegExr] [Visual]
                                                                                                                                                              • 1 matchword p word
                                                                                                                                                                1. p
                                                                                                                                                              • 1 match(p)
                                                                                                                                                                1. p
                                                                                                                                                              • 1 matchp+q+r
                                                                                                                                                                1. p
                                                                                                                                                              • 0 matches(paren)
                                                                                                                                                                1. 0 matches(loop)
                                                                                                                                                                  1. 0 matchesloops
                                                                                                                                                                    /\bcat\b/g[RegExr] [Visual]
                                                                                                                                                                    • 1 matchcat
                                                                                                                                                                      1. cat
                                                                                                                                                                    • 1 matchthe cat?
                                                                                                                                                                      1. cat
                                                                                                                                                                    • 0 matchescatch
                                                                                                                                                                      1. 0 matchesconcat it
                                                                                                                                                                        1. 0 matchesconcatenate

                                                                                                                                                                          There is also a non-word-boundary anchors: \B.

                                                                                                                                                                          As the name suggests, it matches everything apart from word boundaries.

                                                                                                                                                                          /\Bp/g[RegExr] [Visual]
                                                                                                                                                                          • 1 matchape
                                                                                                                                                                            1. p
                                                                                                                                                                          • 1 matchleap
                                                                                                                                                                            1. p
                                                                                                                                                                          • 1 match(leap)
                                                                                                                                                                            1. p
                                                                                                                                                                          • 0 matchesa pot
                                                                                                                                                                            1. 0 matchespea
                                                                                                                                                                              /\Bp\B/g[RegExr] [Visual]
                                                                                                                                                                              • 1 matchape
                                                                                                                                                                                1. p
                                                                                                                                                                              • 1 match_peel
                                                                                                                                                                                1. p
                                                                                                                                                                              • 0 matchesleap
                                                                                                                                                                                1. 0 matches(leap)
                                                                                                                                                                                  1. 0 matchesa pot
                                                                                                                                                                                    1. 0 matchespea
                                                                                                                                                                                      Tip

                                                                                                                                                                                      ^…$ and \b…\b are common patterns and you will almost always need one or the other to prevent accidental matches.

                                                                                                                                                                                      Examples

                                                                                                                                                                                      Trailing whitespace

                                                                                                                                                                                      /\s+$/gm[RegExr] [Visual]
                                                                                                                                                                                      • 1 matchabc
                                                                                                                                                                                      • 1 matchdef
                                                                                                                                                                                      • 0 matchesabc def

                                                                                                                                                                                        Markdown headings

                                                                                                                                                                                        /^## /gm[RegExr] [Visual]
                                                                                                                                                                                        • 0 matches# Heading 1
                                                                                                                                                                                          1. 1 match## Heading 2
                                                                                                                                                                                            1. ##
                                                                                                                                                                                          2. 0 matches### Heading 3
                                                                                                                                                                                            1. 0 matches#### Heading 4

                                                                                                                                                                                              Without anchors:

                                                                                                                                                                                              /## /gm[RegExr] [Visual]
                                                                                                                                                                                              • 0 matches# Heading 1
                                                                                                                                                                                                1. 1 match## Heading 2
                                                                                                                                                                                                  1. ##
                                                                                                                                                                                                2. 1 match### Heading 3
                                                                                                                                                                                                  1. ##
                                                                                                                                                                                                3. 1 match#### Heading 4
                                                                                                                                                                                                  1. ##

                                                                                                                                                                                                Lookaround

                                                                                                                                                                                                Note

                                                                                                                                                                                                This section is a Work In Progress.

                                                                                                                                                                                                Lookarounds can be used to verify conditions, without matching any text.

                                                                                                                                                                                                You’re only looking, not moving.

                                                                                                                                                                                                Lookahead

                                                                                                                                                                                                Positive

                                                                                                                                                                                                /_(?=[aeiou])/g[RegExr] [Visual]
                                                                                                                                                                                                • 1 match_a
                                                                                                                                                                                                  1. _
                                                                                                                                                                                                • 1 matche_e
                                                                                                                                                                                                  1. _
                                                                                                                                                                                                • 0 matches_f

                                                                                                                                                                                                  Note how the character following the _ isn’t matched. Yet, its nature is confirmed by the positive lookahead.

                                                                                                                                                                                                  /(.+)_(?=[aeiou])(?=\1)/g[RegExr] [Visual]
                                                                                                                                                                                                  • 1 matche_e
                                                                                                                                                                                                    1. e_
                                                                                                                                                                                                  • 1 matchu_u
                                                                                                                                                                                                    1. u_
                                                                                                                                                                                                  • 1 matchuw_uw
                                                                                                                                                                                                    1. uw_
                                                                                                                                                                                                  • 1 matchuw_uwa
                                                                                                                                                                                                    1. uw_
                                                                                                                                                                                                  • 0 matchesf_f
                                                                                                                                                                                                    1. 0 matchesa_e

                                                                                                                                                                                                      After (?=[aeiou]), the regex engine hasn’t moved and checks for (?=\1) starting after the _.

                                                                                                                                                                                                      /(?=.*#).*/g[RegExr] [Visual]
                                                                                                                                                                                                      • 1 matchabc#def
                                                                                                                                                                                                        1. abc#def
                                                                                                                                                                                                      • 1 match#def
                                                                                                                                                                                                        1. #def
                                                                                                                                                                                                      • 1 matchabc#
                                                                                                                                                                                                        1. abc#
                                                                                                                                                                                                      • 0 matchesabcdef

                                                                                                                                                                                                        Negative

                                                                                                                                                                                                        /_(?![aeiou])/g[RegExr] [Visual]
                                                                                                                                                                                                        • 0 matches_a
                                                                                                                                                                                                          1. 0 matchese_e
                                                                                                                                                                                                            1. 1 match_f
                                                                                                                                                                                                              1. _
                                                                                                                                                                                                            /^(?!.*#).*$/g[RegExr] [Visual]
                                                                                                                                                                                                            • 0 matchesabc#def
                                                                                                                                                                                                              1. 0 matches#def
                                                                                                                                                                                                                1. 0 matchesabc#
                                                                                                                                                                                                                  1. 1 matchabcdef
                                                                                                                                                                                                                    1. abcdef

                                                                                                                                                                                                                  Without the anchors, this will match the part without the # in each test case.


                                                                                                                                                                                                                  Negative lookaheads are commonly used to prevent particular phrases from matching.

                                                                                                                                                                                                                  /foo(?!bar)/g[RegExr] [Visual]
                                                                                                                                                                                                                  • 1 matchfoobaz
                                                                                                                                                                                                                    1. foo
                                                                                                                                                                                                                  • 0 matchesfoobarbaz
                                                                                                                                                                                                                    1. 0 matchesbazfoobar
                                                                                                                                                                                                                      /---(?:(?!---).)*---/g[RegExr] [Visual]
                                                                                                                                                                                                                      • 1 match---foo---
                                                                                                                                                                                                                        1. ---foo---
                                                                                                                                                                                                                      • 1 match---fo-o---
                                                                                                                                                                                                                        1. ---fo-o---
                                                                                                                                                                                                                      • 1 match--------
                                                                                                                                                                                                                        1. ------

                                                                                                                                                                                                                      Lookbehind

                                                                                                                                                                                                                      Limited Support

                                                                                                                                                                                                                      JavaScript, prior to ES2018, did not support this flag.

                                                                                                                                                                                                                      Positive

                                                                                                                                                                                                                      Negative

                                                                                                                                                                                                                      Examples

                                                                                                                                                                                                                      Password validation

                                                                                                                                                                                                                      /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[a-zA-Z]).{8,}$/[RegExr] [Visual]
                                                                                                                                                                                                                      • 0 matcheshunter2
                                                                                                                                                                                                                        1. 0 matcheszsofpghedake
                                                                                                                                                                                                                          1. 0 matcheszsofpghedak4e
                                                                                                                                                                                                                            1. 1 matchzSoFpghEdaK4E
                                                                                                                                                                                                                              1. zSoFpghEdaK4E
                                                                                                                                                                                                                            2. 1 matchzSoFpg!hEd!aK4E
                                                                                                                                                                                                                              1. zSoFpg!hEd!aK4E

                                                                                                                                                                                                                            Lookarounds can be used verify multiple conditions.

                                                                                                                                                                                                                            Quoted strings

                                                                                                                                                                                                                            /(['"])(?:(?!\1).)*\1/g[RegExr] [Visual]
                                                                                                                                                                                                                            • 1 matchfoo "bar" baz
                                                                                                                                                                                                                              1. "bar"
                                                                                                                                                                                                                            • 1 matchfoo 'bar' baz
                                                                                                                                                                                                                              1. 'bar'
                                                                                                                                                                                                                            • 1 matchfoo 'bat's' baz
                                                                                                                                                                                                                              1. 'bat'
                                                                                                                                                                                                                            • 1 matchfoo "bat's" baz
                                                                                                                                                                                                                              1. "bat's"
                                                                                                                                                                                                                            • 1 matchfoo 'bat"s' baz
                                                                                                                                                                                                                              1. 'bat"s'

                                                                                                                                                                                                                            Without lookaheads, this is the best we can do:

                                                                                                                                                                                                                            /(['"])[^'"]*\1/g[RegExr] [Visual]
                                                                                                                                                                                                                            • 1 matchfoo "bar" baz
                                                                                                                                                                                                                              1. "bar"
                                                                                                                                                                                                                            • 1 matchfoo 'bar' baz
                                                                                                                                                                                                                              1. 'bar'
                                                                                                                                                                                                                            • 1 matchfoo 'bat's' baz
                                                                                                                                                                                                                              1. 'bat'
                                                                                                                                                                                                                            • 0 matchesfoo "bat's" baz
                                                                                                                                                                                                                              1. 0 matchesfoo 'bat"s' baz

                                                                                                                                                                                                                                Advanced Examples

                                                                                                                                                                                                                                Javascript comments

                                                                                                                                                                                                                                /\/\*[\s\S]*?\*\/|\/\/.*/g[RegExr] [Visual]
                                                                                                                                                                                                                                • 1 matchconst a = 0; // comment
                                                                                                                                                                                                                                  1. // comment
                                                                                                                                                                                                                                • 1 match/* multiline */
                                                                                                                                                                                                                                  1. /* multiline */

                                                                                                                                                                                                                                [\s\S] is a hack to match any character including newlines. We avoid the dot-all flag because we need to use the ordinary . for single-line comments.

                                                                                                                                                                                                                                24-Hour Time

                                                                                                                                                                                                                                /^([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$/g[RegExr] [Visual]
                                                                                                                                                                                                                                • 1 match23:59:00
                                                                                                                                                                                                                                  1. 23:59:00
                                                                                                                                                                                                                                • 1 match14:00
                                                                                                                                                                                                                                  1. 14:00
                                                                                                                                                                                                                                • 1 match23:00
                                                                                                                                                                                                                                  1. 23:00
                                                                                                                                                                                                                                • 0 matches29:00
                                                                                                                                                                                                                                  1. 0 matches32:32

                                                                                                                                                                                                                                    Meta

                                                                                                                                                                                                                                    /<Example source="(.*?)" flags="(.*?)">/gm[RegExr] [Visual]
                                                                                                                                                                                                                                    • 1 match<Example source="p[aeiou]t" flags="g">
                                                                                                                                                                                                                                      1. <Example source="p[aeiou]t" flags="g">
                                                                                                                                                                                                                                    • 1 match<Example source="s+$" flags="gm">
                                                                                                                                                                                                                                      1. <Example source="s+$" flags="gm">
                                                                                                                                                                                                                                    • 1 match<Example source="(['"])(?:(?!\1).)*\1" flags="g">
                                                                                                                                                                                                                                      1. <Example source="(['"])(?:(?!\1).)*\1" flags="g">
                                                                                                                                                                                                                                    • 0 matches<Example source='s+$' flags='gm'>
                                                                                                                                                                                                                                      1. 0 matches</Example>

                                                                                                                                                                                                                                        Replace: <Example regex={/$1/$2}>

                                                                                                                                                                                                                                        I performed this operation in commit d7a684f.

                                                                                                                                                                                                                                        Floating point numbers

                                                                                                                                                                                                                                        /^([+-]?(?=\.\d|\d)(?:\d+)?(?:\.?\d*))(?:[eE]([+-]?\d+))?$/g[RegExr] [Visual]
                                                                                                                                                                                                                                        • 1 match987
                                                                                                                                                                                                                                          1. 987
                                                                                                                                                                                                                                        • 1 match-8
                                                                                                                                                                                                                                          1. -8
                                                                                                                                                                                                                                        • 1 match0.1
                                                                                                                                                                                                                                          1. 0.1
                                                                                                                                                                                                                                        • 1 match2.
                                                                                                                                                                                                                                          1. 2.
                                                                                                                                                                                                                                        • 1 match.987
                                                                                                                                                                                                                                          1. .987
                                                                                                                                                                                                                                        • 1 match+4.0
                                                                                                                                                                                                                                          1. +4.0
                                                                                                                                                                                                                                        • 1 match1.1e+1
                                                                                                                                                                                                                                          1. 1.1e+1
                                                                                                                                                                                                                                        • 1 match1.e+1
                                                                                                                                                                                                                                          1. 1.e+1
                                                                                                                                                                                                                                        • 1 match1e2
                                                                                                                                                                                                                                          1. 1e2
                                                                                                                                                                                                                                        • 1 match0.2e2
                                                                                                                                                                                                                                          1. 0.2e2
                                                                                                                                                                                                                                        • 1 match.987e2
                                                                                                                                                                                                                                          1. .987e2
                                                                                                                                                                                                                                        • 1 match+4e-1
                                                                                                                                                                                                                                          1. +4e-1
                                                                                                                                                                                                                                        • 1 match-8.e+2
                                                                                                                                                                                                                                          1. -8.e+2
                                                                                                                                                                                                                                        • 0 matches.

                                                                                                                                                                                                                                          The positive lookahead (?=\.\d|\d) ensures that the regex does not match ..

                                                                                                                                                                                                                                          Latitude and Longitude

                                                                                                                                                                                                                                          /^((-?|\+?)?\d+(\.\d+)?),\s*((-?|\+?)?\d+(\.\d+)?)$/g[RegExr] [Visual]
                                                                                                                                                                                                                                          • 1 match30.0260736, -89.9766792
                                                                                                                                                                                                                                            1. 30.0260736, -89.9766792
                                                                                                                                                                                                                                          • 1 match45, 180
                                                                                                                                                                                                                                            1. 45, 180
                                                                                                                                                                                                                                          • 1 match-90.000, -180.0
                                                                                                                                                                                                                                            1. -90.000, -180.0
                                                                                                                                                                                                                                          • 1 match48.858093,2.294694
                                                                                                                                                                                                                                            1. 48.858093,2.294694
                                                                                                                                                                                                                                          • 1 match-3.14, 3.14
                                                                                                                                                                                                                                            1. -3.14, 3.14
                                                                                                                                                                                                                                          • 1 match045, 180.0
                                                                                                                                                                                                                                            1. 045, 180.0
                                                                                                                                                                                                                                          • 1 match0, 0
                                                                                                                                                                                                                                            1. 0, 0
                                                                                                                                                                                                                                          • 0 matches-90., -180.
                                                                                                                                                                                                                                            1. 0 matches.004, .15

                                                                                                                                                                                                                                              See also: Floating Point Numbers

                                                                                                                                                                                                                                              MAC Addresses

                                                                                                                                                                                                                                              /^[a-f0-9]{2}(:[a-f0-9]{2}){5}$/i[RegExr] [Visual]
                                                                                                                                                                                                                                              • 1 match01:02:03:04:ab:cd
                                                                                                                                                                                                                                                1. 01:02:03:04:ab:cd
                                                                                                                                                                                                                                              • 1 match9E:39:23:85:D8:C2
                                                                                                                                                                                                                                                1. 9E:39:23:85:D8:C2
                                                                                                                                                                                                                                              • 1 match00:00:00:00:00:00
                                                                                                                                                                                                                                                1. 00:00:00:00:00:00
                                                                                                                                                                                                                                              • 0 matches1N:VA:L1:DA:DD:R5
                                                                                                                                                                                                                                                1. 0 matches9:3:23:85:D8:C2
                                                                                                                                                                                                                                                  1. 0 matchesac::23:85:D8:C2

                                                                                                                                                                                                                                                    UUID

                                                                                                                                                                                                                                                    /[\da-f]{8}-([\da-f]{4}-){3}[\da-f]{12}/i[RegExr] [Visual]
                                                                                                                                                                                                                                                    • 1 match123e4567-e89b-12d3-a456-426655440000
                                                                                                                                                                                                                                                      1. 123e4567-e89b-12d3-a456-426655440000
                                                                                                                                                                                                                                                    • 1 matchc73bcdcc-2669-4bf6-81d3-e4ae73fb11fd
                                                                                                                                                                                                                                                      1. c73bcdcc-2669-4bf6-81d3-e4ae73fb11fd
                                                                                                                                                                                                                                                    • 1 matchC73BCDCC-2669-4Bf6-81d3-E4AE73FB11FD
                                                                                                                                                                                                                                                      1. C73BCDCC-2669-4Bf6-81d3-E4AE73FB11FD
                                                                                                                                                                                                                                                    • 0 matchesc73bcdcc-2669-4bf6-81d3-e4an73fb11fd
                                                                                                                                                                                                                                                      1. 0 matchesc73bcdcc26694bf681d3e4ae73fb11fd

                                                                                                                                                                                                                                                        IP Addresses

                                                                                                                                                                                                                                                        /\b(?:(?:2(?:[0-4][0-9]|5[0-5])|[0-1]?[0-9]?[0-9])\.){3}(?:(?:2([0-4][0-9]|5[0-5])|[0-1]?[0-9]?[0-9]))\b/g[RegExr] [Visual]
                                                                                                                                                                                                                                                        • 1 match9.9.9.9
                                                                                                                                                                                                                                                          1. 9.9.9.9
                                                                                                                                                                                                                                                        • 1 match127.0.0.1:8080
                                                                                                                                                                                                                                                          1. 127.0.0.1
                                                                                                                                                                                                                                                        • 1 matchIt's 192.168.1.9
                                                                                                                                                                                                                                                          1. 192.168.1.9
                                                                                                                                                                                                                                                        • 1 match255.193.09.243
                                                                                                                                                                                                                                                          1. 255.193.09.243
                                                                                                                                                                                                                                                        • 1 match123.123.123.123
                                                                                                                                                                                                                                                          1. 123.123.123.123
                                                                                                                                                                                                                                                        • 0 matches123.123.123.256
                                                                                                                                                                                                                                                          1. 0 matches0.0.x.0

                                                                                                                                                                                                                                                            HSL colours

                                                                                                                                                                                                                                                            Integers from 0 to 360

                                                                                                                                                                                                                                                            /^0*(?:360|3[0-5]\d|[12]?\d?\d)$/g[RegExr] [Visual]
                                                                                                                                                                                                                                                            • 1 match360
                                                                                                                                                                                                                                                              1. 360
                                                                                                                                                                                                                                                            • 1 match349
                                                                                                                                                                                                                                                              1. 349
                                                                                                                                                                                                                                                            • 1 match235
                                                                                                                                                                                                                                                              1. 235
                                                                                                                                                                                                                                                            • 1 match152
                                                                                                                                                                                                                                                              1. 152
                                                                                                                                                                                                                                                            • 1 match68
                                                                                                                                                                                                                                                              1. 68
                                                                                                                                                                                                                                                            • 1 match9
                                                                                                                                                                                                                                                              1. 9
                                                                                                                                                                                                                                                            • 0 matches361
                                                                                                                                                                                                                                                              1. 0 matches404

                                                                                                                                                                                                                                                                Percentages

                                                                                                                                                                                                                                                                /^(?:100(?:\.0+)?|\d?\d(?:\.\d+)?)%$/g[RegExr] [Visual]
                                                                                                                                                                                                                                                                • 1 match100%
                                                                                                                                                                                                                                                                  1. 100%
                                                                                                                                                                                                                                                                • 1 match100.0%
                                                                                                                                                                                                                                                                  1. 100.0%
                                                                                                                                                                                                                                                                • 1 match25%
                                                                                                                                                                                                                                                                  1. 25%
                                                                                                                                                                                                                                                                • 1 match52.32%
                                                                                                                                                                                                                                                                  1. 52.32%
                                                                                                                                                                                                                                                                • 1 match9%
                                                                                                                                                                                                                                                                  1. 9%
                                                                                                                                                                                                                                                                • 1 match0.5%
                                                                                                                                                                                                                                                                  1. 0.5%
                                                                                                                                                                                                                                                                • 0 matches100.5%
                                                                                                                                                                                                                                                                  1. 0 matches42

                                                                                                                                                                                                                                                                    Bringing it all together

                                                                                                                                                                                                                                                                    /^hsl\(\s*0*(?:360|3[0-5]\d|[12]?\d?\d)\s*(?:,\s*0*(?:100(?:\.0+)?|\d?\d(?:\.\d+)?)%\s*){2}\)$/gi[RegExr] [Visual]
                                                                                                                                                                                                                                                                    • 1 matchhsl(0,20%,100%)
                                                                                                                                                                                                                                                                      1. hsl(0,20%,100%)
                                                                                                                                                                                                                                                                    • 1 matchHSL(0350, 002%,4.1%)
                                                                                                                                                                                                                                                                      1. HSL(0350, 002%,4.1%)
                                                                                                                                                                                                                                                                    • 1 matchhsl(360,10% , 0.2% )
                                                                                                                                                                                                                                                                      1. hsl(360,10% , 0.2% )

                                                                                                                                                                                                                                                                    Next Steps

                                                                                                                                                                                                                                                                    Congratulations on getting this far!

                                                                                                                                                                                                                                                                    Obligatory xkcd:

                                                                                                                                                                                                                                                                    Cueball saves the day with regex

                                                                                                                                                                                                                                                                    If you’d like to read more about regular expressions and how they work:

                                                                                                                                                                                                                                                                    Thanks for reading!