Regular Expressions 101

Save & Share

  • Regex Version: ver. 1
  • Update Regex
    ctrl+⇧+s
  • Save new Regex
    ctrl+s
  • Add to Community Library

Flavor

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

Function

  • Match
  • Substitution
  • List
  • Unit Tests

Tools

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

Regular Expression

/
/
gm

Test String

Code Generator

Generated Code

import java.util.regex.Matcher; import java.util.regex.Pattern; public class Example { public static void main(String[] args) { final String regex = "(<\\s*[^>]*)(href=|src=)(.?)(\\/[^\\/])"; final String string = "<div id=\"blog\"><div id=\"content\">\n" + " <div id=\"content\">\n\n" + " <div class=\"Article\" data-slug=\"/blog/execution-traces-2024\">\n" + " \n" + " <h1 class=\"small\"><a href=\"//go.dev/blog/\">The Go Blog</a></h1>\n" + " \n\n" + " <h1>More powerful Go execution traces</h1>\n" + " \n" + " <p class=\"author\">\n" + " Michael Knyszek<br>\n" + " 14 March 2024\n" + " </p>\n" + " \n" + " <p>The <a href=\"/pkg/runtime/trace\">runtime/trace</a> package contains a powerful tool for understanding and\n" + "troubleshooting Go programs.\n" + "The functionality within allows one to produce a trace of each goroutine&rsquo;s execution over some\n" + "time period.\n" + "With the <a href=\"/pkg/cmd/trace\"><code>go tool trace</code> command</a> (or the excellent open source\n" + "<a href=\"https://gotraceui.dev/\" rel=\"noreferrer\" target=\"_blank\">gotraceui tool</a>), one may then visualize and explore the data within these\n" + "traces.</p>\n" + "<p>The magic of a trace is that it can easily reveal things about a program that are hard to see in\n" + "other ways.\n" + "For example, a concurrency bottleneck where lots of goroutines block on the same channel might be\n" + "quite difficult to see in a CPU profile, because there&rsquo;s no execution to sample.\n" + "But in an execution trace, the <em>lack</em> of execution will show up with amazing clarity, and the stack\n" + "traces of blocked goroutines will quickly point at the culprit.</p>\n" + "<div class=\"image\">\n" + " <img src=\"execution-traces-2024/gotooltrace.png\" alt=\"\">\n" + "</div>\n" + "<p>Go developers are even able to instrument their own programs with <a href=\"//go.dev/pkg/runtime/trace#Task\">tasks</a>,\n" + "<a href=\"//go.dev/pkg/runtime/trace#WithRegion\">regions</a>, and <a href=\"//go.dev/pkg/runtime/trace#Log\">logs</a> that\n" + "they can use to correlate their higher-level concerns with lower-level execution details.</p>\n" + "<h2 id=\"issues\">Issues</h2>\n" + "<p>Unfortunately, the wealth of information in execution traces can often be out of reach.\n" + "Four big issues with traces have historically gotten in the way.</p>\n" + "<ul>\n" + "<li>Traces had high overheads.</li>\n" + "<li>Traces didn&rsquo;t scale well, and could become too big to analyze.</li>\n" + "<li>It was often unclear when to start tracing to capture a specific bad behavior.</li>\n" + "<li>Only the most adventurous gophers could programmatically analyze traces, given the lack of a\n" + "public package for parsing and interpreting execution traces.</li>\n" + "</ul>\n" + "<p>If you&rsquo;ve used traces in the last few years, you&rsquo;ve likely been frustrated by one or more of these\n" + "problems.\n" + "But we&rsquo;re excited to share that over the last two Go releases we&rsquo;ve made big progress in all four\n" + "of these areas.</p>\n" + "<h2 id=\"low-overhead-tracing\">Low-overhead tracing</h2>\n" + "<p>Prior to Go 1.21, the run-time overhead of tracing was somewhere between 10–20% CPU for many\n" + "applications, which limits tracing to situational usage, rather than continuous usage like CPU\n" + "profiling.\n" + "It turned out that much of the cost of tracing came down to tracebacks.\n" + "Many events produced by the runtime have stack traces attached, which are invaluable to actually\n" + "identifying what goroutines were doing at key moments in their execution.</p>\n" + "<p>Thanks to work by Felix Geisendörfer and Nick Ripley on optimizing the efficiency of tracebacks,\n" + "the run-time CPU overhead of execution traces has been cut dramatically, down to 1–2% for many\n" + "applications.\n" + "You can read more about the work done here in <a href=\"https://blog.felixge.de/reducing-gos-execution-tracer-overhead-with-frame-pointer-unwinding/\" rel=\"noreferrer\" target=\"_blank\">Felix&rsquo;s great blog\n" + "post</a>\n" + "on the topic.</p>\n" + "<h2 id=\"scalable-traces\">Scalable traces</h2>\n" + "<p>The trace format and its events were designed around relatively efficient emission, but required\n" + "tooling to parse and keep around the state of the entirety of a trace.\n" + "A few hundred MiB trace could require several GiB of RAM to analyze!</p>\n" + "<p>This issue is unfortunately fundamental to how traces are generated.\n" + "To keep run-time overheads low, all events are written to the equivalent of thread-local buffers.\n" + "But this means events appear out of their true order, and the burden is placed on the trace\n" + "tooling to figure out what really happened.</p>\n" + "<p>The key insight to making traces scale while keeping overheads low was to occasionally split the\n" + "trace being generated.\n" + "Each split point would behave a bit like simultaneously disabling and reenabling tracing in one\n" + "go.\n" + "All the trace data so far would represent a complete and self-contained trace, while the new trace\n" + "data would seamlessly pick up from where it left off.</p>\n" + "<p>As you might imagine, fixing this required <a href=\"//go.dev/issue/60773\">rethinking and rewriting a lot of the foundation of\n" + "the trace implementation</a> in the runtime.\n" + "We&rsquo;re happy to say that the work landed in Go 1.22 and is now generally available.\n" + "<a href=\"//go.dev/doc/go1.22#runtime/trace\">A lot of nice improvements</a> came with the rewrite, including some\n" + "improvements to the <a href=\"//go.dev/doc/go1.22#trace\"><code>go tool trace</code> command</a> as well.\n" + "The gritty details are all in the <a href=\"https://github.com/golang/proposal/blob/master/design/60773-execution-tracer-overhaul.md\" rel=\"noreferrer\" target=\"_blank\">design\n" + "document</a>,\n" + "if you&rsquo;re curious.</p>\n" + "<p>(Note: <code>go tool trace</code> still loads the full trace into memory, but <a href=\"//go.dev/issue/65315\">removing this\n" + "limitation</a> for traces produced by Go 1.22+ programs is now feasible.)</p>\n" + "<h2 id=\"flight-recording\">Flight recording</h2>\n" + "<p>Suppose you work on a web service and an RPC took a very long time.\n" + "You couldn&rsquo;t start tracing at the point you knew the RPC was already taking a while, because the\n" + "root cause of the slow request already happened and wasn&rsquo;t recorded.</p>\n" + "<p>There&rsquo;s a technique that can help with this called flight recording, which you may already be\n" + "familiar with from other programming environments.\n" + "The insight with flight recording is to have tracing on continuously and always keep the most\n" + "recent trace data around, just in case.\n" + "Then, once something interesting happens, the program can just write out whatever it has!</p>\n" + "<p>Before traces could be split, this was pretty much a non-starter.\n" + "But because continuous tracing is now viable thanks to low overheads, and the fact that the runtime\n" + "can now split traces any time it needs, it turns out it was straightforward to implement flight\n" + "recording.</p>\n" + "<p>As a result, we&rsquo;re happy to announce a flight recorder experiment, available in the\n" + "<a href=\"//go.dev/pkg/golang.org/x/exp/trace#FlightRecorder\">golang.org/x/exp/trace package</a>.</p>\n" + "<p>Please try it out!\n" + "Below is an example that sets up flight recording to capture a long HTTP request to get you started.</p>\n" + "<div class=\"code\">\n" + "<pre> <span class=\"comment\">// Set up the flight recorder.</span>\n" + " fr := trace.NewFlightRecorder()\n" + " fr.Start()\n\n" + " <span class=\"comment\">// Set up and run an HTTP server.</span>\n" + " var once sync.Once\n" + " http.HandleFunc(&#34;/my-endpoint&#34;, func(w http.ResponseWriter, r *http.Request) {\n" + " start := time.Now()\n\n" + " <span class=\"comment\">// Do the work...</span>\n" + " doWork(w, r)\n\n" + " <span class=\"comment\">// We saw a long request. Take a snapshot!</span>\n" + " if time.Since(start) &gt; 300*time.Millisecond {\n" + " <span class=\"comment\">// Do it only once for simplicity, but you can take more than one.</span>\n" + " once.Do(func() {\n" + " <span class=\"comment\">// Grab the snapshot.</span>\n" + " var b bytes.Buffer\n" + " _, err = fr.WriteTo(&amp;b)\n" + " if err != nil {\n" + " log.Print(err)\n" + " return\n" + " }\n" + " <span class=\"comment\">// Write it to a file.</span>\n" + " if err := os.WriteFile(&#34;trace.out&#34;, b.Bytes(), 0o755); err != nil {\n" + " log.Print(err)\n" + " return\n" + " }\n" + " })\n" + " }\n" + " })\n" + " log.Fatal(http.ListenAndServe(&#34;:8080&#34;, nil))\n" + "</pre>\n" + "</div>\n" + "<p>If you have any feedback, positive or negative, please share it to the <a href=\"//go.dev/issue/63185\">proposal\n" + "issue</a>!</p>\n" + "<h2 id=\"trace-reader-api\">Trace reader API</h2>\n" + "<p>Along with the trace implementation rewrite came an effort to clean up the other trace internals,\n" + "like <code>go tool trace</code>.\n" + "This spawned an attempt to create a trace reader API that was good enough to share and that could\n" + "make traces more accessible.</p>\n" + "<p>Just like the flight recorder, we&rsquo;re happy to announce that we also have an experimental trace reader\n" + "API that we&rsquo;d like to share.\n" + "It&rsquo;s available in the <a href=\"//go.dev/pkg/golang.org/x/exp/trace#Reader\">same package as the flight recorder,\n" + "golang.org/x/exp/trace</a>.</p>\n" + "<p>We think it&rsquo;s good enough to start building things on top of, so please try it out!\n" + "Below is an example that measures the proportion of goroutine block events that blocked to wait on\n" + "the network.</p>\n" + "<div class=\"code\">\n" + "<pre> <span class=\"comment\">// Start reading from STDIN.</span>\n" + " r, err := trace.NewReader(os.Stdin)\n" + " if err != nil {\n" + " log.Fatal(err)\n" + " }\n\n" + " var blocked int\n" + " var blockedOnNetwork int\n" + " for {\n" + " <span class=\"comment\">// Read the event.</span>\n" + " ev, err := r.ReadEvent()\n" + " if err == io.EOF {\n" + " break\n" + " } else if err != nil {\n" + " log.Fatal(err)\n" + " }\n\n" + " <span class=\"comment\">// Process it.</span>\n" + " if ev.Kind() == trace.EventStateTransition {\n" + " st := ev.StateTransition()\n" + " if st.Resource.Kind == trace.ResourceGoroutine {\n" + " from, to := st.Goroutine()\n\n" + " <span class=\"comment\">// Look for goroutines blocking, and count them.</span>\n" + " if from.Executing() &amp;&amp; to == trace.GoWaiting {\n" + " blocked++\n" + " if strings.Contains(st.Reason, &#34;network&#34;) {\n" + " blockedOnNetwork++\n" + " }\n" + " }\n" + " }\n" + " }\n" + " }\n" + " <span class=\"comment\">// Print what we found.</span>\n" + " p := 100 * float64(blockedOnNetwork) / float64(blocked)\n" + " fmt.Printf(&#34;%2.3f%% instances of goroutines blocking were to block on the network\\n&#34;, p)\n" + "</pre>\n" + "</div>\n" + "<p>And just like the flight recorder, there&rsquo;s a <a href=\"//go.dev/issue/62627\">proposal issue</a> that would\n" + "be a great place to leave feedback!</p>\n" + "<p>We&rsquo;d like to quickly call out Dominik Honnef as someone who tried it out early, provided great\n" + "feedback, and has contributed support for older trace versions to the API.</p>\n" + "<h2 id=\"thank-you\">Thank you!</h2>\n" + "<p>This work was completed, in no small part, thanks to the help of the those in the <a href=\"//go.dev/issue/57175\">diagnostics\n" + "working group</a>, started over a year ago as a collaboration between stakeholders from\n" + "across the Go community, and open to the public.</p>\n" + "<p>We&rsquo;d like to take a moment to thank those community members who have attended the diagnostic\n" + "meetings regularly over the last year: Felix Geisendörfer, Nick Ripley, Rhys Hiltner, Dominik\n" + "Honnef, Bryan Boreham, thepudds.</p>\n" + "<p>The discussions, feedback, and work you all put in have been instrumental to getting us to where we\n" + "are today.\n" + "Thank you!</p>\n\n" + " </div>\n\n" + " \n" + " <div class=\"Article prevnext\">\n" + " \n" + " \n" + " \n" + " <p>\n" + " \n" + " \n" + " \n" + " <b>Previous article: </b><a href=\"//go.dev/blog/generic-slice-functions\">Robust generic functions on slices</a><br>\n" + " \n" + " \n" + " <b><a href=\"//go.dev/blog/all\">Blog Index</a></b>\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " </div>\n" + " \n\n" + " </div>\n" + "</div>\n\n" + "<script src=\"/js/jquery.js\"></script>\n" + "<script src=\"/js/playground.js\"></script>\n" + "<script src=\"/js/play.js\"></script>\n" + "<script src=\"/js/godocs.js\"></script>"; final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE); final Matcher matcher = pattern.matcher(string); while (matcher.find()) { System.out.println("Full match: " + matcher.group(0)); for (int i = 1; i <= matcher.groupCount(); i++) { System.out.println("Group " + i + ": " + matcher.group(i)); } } } }

Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for Java, please visit: https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html