Regular Expressions 101

Save & Share

Flavor

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

Function

  • Match
  • Substitution
  • List
  • Unit Tests

Tools

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

Regular Expression

/
/
g

Test String

Substitution

Processing...

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 = "function\\(([^)]*)\\) \\{\\s+(?:return )?([^;\\v]+);\\s+\\}"; final String string = "goog.provide('smb.controllers.SearchboxForDashboards');\n\n" + "goog.require('goog.array');\n" + "goog.require('goog.functions');\n" + "goog.require('goog.iter');\n" + "goog.require('goog.object');\n" + "goog.require('goog.string.format');\n" + "goog.require('smb.model.Dashboard');\n" + "goog.require('smb.model.User');\n\n" + "goog.scope(function() {\n\n\n\n" + "var User = smb.model.User;\n\n" + "/**\n" + " * @param {!angular.Scope} $scope Injected Angular scope.\n" + " * @param {!angular.Route} $route Injected angular route.\n" + " * @param {!angular.Location} $location Injected angular location.\n" + " * @param {!angular.Resource} $resource Injected angular resource.\n" + " * @param {!smb.services.navigation} navigationService The navigationService.\n" + " * @constructor\n" + " */\n" + "smb.controllers.SearchboxForDashboards = function($scope, $route, $location,\n" + " $resource, navigationService) {\n" + " /** @private {!angular.Scope} */\n" + " this.scope_ = $scope;\n\n" + " /** @private {!smb.services.navigation} */\n" + " this.navigationService_ = navigationService;\n\n" + " /** @private {!angular.Route} */\n" + " this.route_ = $route;\n\n" + " /** @private {!angular.Location} */\n" + " this.location_ = $location;\n\n" + " /** @private {!angular.Resource} */\n" + " this.resource_ = $resource;\n\n" + " /** @private */\n" + " this.active_ = this.scope_.active;\n\n" + " /**\n" + " * Current search string.\n" + " * @export {string}\n" + " */\n" + " this.search = '';\n\n" + " /**\n" + " * The list of current search results.\n" + " * @export {!Array<!SearchboxForDashboards.SearchResultStruct>}\n" + " */\n" + " this.searchResults = [];\n" + "};\n\n" + "var SearchboxForDashboards = smb.controllers.SearchboxForDashboards;\n\n" + "/**\n" + " * @return {boolean} Whether there are no search results.\n" + " * @private\n" + " */\n" + "SearchboxForDashboards.prototype.hasNoSearchResults_ = function() {\n" + " return this.searchResults.length == 0;\n" + "};\n\n" + "/**\n" + " * Types of component contained in a search result.\n" + " * @enum {string}\n" + " */\n" + "SearchboxForDashboards.ComponentType = {\n" + " TAG: 'tag',\n" + " TITLE: 'title',\n" + " DESCRIPTION: 'description'\n" + "};\n\n" + "/**\n" + " * FIRST_SUBSEARCH is a multiplier applied for matches starting at the beginning\n" + " * of the text as a whole. STARTING_MATCH is applies for matches at the\n" + " * beginning of any word.\n" + " * @typedef {{\n" + " * FIRST_SUBSEARCH: number,\n" + " * STARTING_MATCH: number\n" + " * }}\n" + " */\n" + "SearchboxForDashboards.ComponentWeight;\n\n" + "/**\n" + " * Weight settings for the various components, can be tweaked to change results.\n" + " * @const {!Object<!SearchboxForDashboards.ComponentType,\n" + " * !SearchboxForDashboards.ComponentWeight>}\n" + " */\n" + "SearchboxForDashboards.WEIGHTS = goog.object.create(\n" + " SearchboxForDashboards.ComponentType.TAG, {\n" + " FIRST_SUBSEARCH: 1,\n" + " STARTING_MATCH: 2\n" + " },\n" + " SearchboxForDashboards.ComponentType.TITLE, {\n" + " FIRST_SUBSEARCH: 10,\n" + " STARTING_MATCH: 10\n" + " },\n" + " SearchboxForDashboards.ComponentType.DESCRIPTION, {\n" + " FIRST_SUBSEARCH: 10,\n" + " STARTING_MATCH: 10\n" + " }\n" + ");\n\n" + "/**\n" + " * One feature of the search result.\n" + " * @typedef {{\n" + " * type: !SearchboxForDashboards.ComponentType,\n" + " * match: string,\n" + " * tag: (string|undefined),\n" + " * title: (string|undefined),\n" + " * score: number,\n" + " * }}\n" + " */\n" + "SearchboxForDashboards.SearchResultComponent;\n\n" + "/**\n" + " * Search result with scoring information.\n" + " * @typedef {{\n" + " * dashboard: !smb.model.Dashboard,\n" + " * components: !Array<!SearchResultComponent>,\n" + " * bestTitleMatch: ?string,\n" + " * bestDescriptionMatch: ?string,\n" + " * score: number,\n" + " * }}\n" + "*/\n" + "SearchboxForDashboards.SearchResultStruct;\n\n\n" + "/**\n" + " * Gives a match score for a dashboard.\n" + " * TODO(b/27602041) Do more in-depth research into whether there are feasible\n" + " * alternatives to writing custom search logic that still give us fine\n" + " * control over ranking.\n" + " * @param {string} search The text to search.\n" + " * @param {!smb.model.Dashboard} dashboard The dashboard to which to apply the\n" + " * search.\n" + " * @param {boolean=} opt_recur Whether to recursively perform subsearches\n" + " * for the different words in the search, i.e \"word1 word2 word3\" would\n" + " * do \"word1 word2\" and \"word2 word3\", and then the same recursively.\n" + " * @param {boolean=} opt_isFirstSearch Whether this is should be treated as\n" + " * matching at the beginning of a search.\n" + " * @return {!SearchResultStruct} The result of the search.\n" + " * @private\n" + " */\n" + "SearchboxForDashboards.prototype.doDashboardSearch_ =\n" + " function(search, dashboard, opt_recur, opt_isFirstSearch) {\n" + " var isFirstSearch = opt_isFirstSearch;\n" + " var struct = {dashboard: dashboard, components: []};\n\n" + " var titleSearchComponent =\n" + " this.doTitleSearch_(search, dashboard, isFirstSearch);\n" + " if (titleSearchComponent != null) {\n" + " struct.components.push(titleSearchComponent);\n" + " }\n\n" + " var descriptionSearchComponent =\n" + " this.doDescriptionSearch_(search, dashboard, isFirstSearch);\n" + " if (descriptionSearchComponent != null) {\n" + " struct.components.push(descriptionSearchComponent);\n" + " }\n\n" + " var tagSearchComponent = this.doTagSearch_(search, dashboard);\n" + " if (tagSearchComponent != null) {\n" + " struct.components.push(tagSearchComponent);\n" + " }\n\n" + " // now we search for all the n-gram substrings\n" + " if (opt_recur) {\n" + " var re = /\\s+/;\n" + " var tokens = search.split(re);\n" + " var len = tokens.length;\n" + " for (var runLength = len - 1; runLength > 0; runLength--) {\n" + " for (var start = 0; start <= len - runLength; start++) {\n" + " var subArr = tokens.slice(start, start + runLength);\n" + " var newSearch = subArr.join(' ');\n" + " var isFirstSearch = start == 0;\n" + " var subStruct =\n" + " this.doDashboardSearch_(newSearch, dashboard, false, isFirstSearch);\n" + " struct.components = struct.components.concat(subStruct.components);\n" + " }\n" + " }\n" + " }\n\n" + " struct.components = struct.components.sort(function(a, b) {\n" + " return b.score - a.score;\n" + " });\n\n" + " var bestTitleMatch = goog.array.find(struct.components, function(component) {\n" + " return component.type == SearchboxForDashboards.TITLE;\n" + " });\n" + " if (bestTitleMatch) {\n" + " struct.bestTitleMatch = bestTitleMatch.title;\n" + " }\n\n" + " var bestDescriptionMatch = goog.array.find(struct.components,\n" + " function(component) {\n" + " return component.type == SearchboxForDashboards.DESCRIPTION;\n" + " });\n" + " if (bestDescriptionMatch) {\n" + " struct.bestDescriptionMatch = bestDescriptionMatch.description;\n" + " }\n\n" + " this.computeAndSetSearchResultScore_(struct);\n" + " return struct;\n" + "};\n\n" + "/**\n" + " * Computes score for the search result and sets score for the search result.\n" + " * @param {!SearchResultStruct} searchResult The search result to operate on.\n" + " * @private\n" + " */\n" + "SearchboxForDashboards.prototype.computeAndSetSearchResultScore_ =\n" + " function(searchResult) {\n" + " searchResult.score = searchResult.components.map(function(component) {\n" + " return component.score;\n" + " }).reduce(function(a, b) { return a + b; }, 0);\n" + " };\n\n" + "/**\n" + " * Performs search on dashboard title.\n" + " * @param {string} search The text to search.\n" + " * @param {!smb.model.Dashboard} dashboard The dashboard to perform search on.\n" + " * @param {boolean} isFirstSearch Whether to treat this as matching at the\n" + " * beginning of a search.\n" + " * @return {?SearchboxForDashboards.SearchResultComponent} The search match\n" + " * component.\n" + " * @private\n" + " */\n" + "SearchboxForDashboards.prototype.doTitleSearch_ =\n" + " function(search, dashboard, isFirstSearch) {\n" + " var title = dashboard.titleDisplayText || dashboard.menuDisplayText;\n" + " return this.doTextSearch_(search, title, isFirstSearch,\n" + " SearchboxForDashboards.ComponentType.TITLE);\n" + "};\n\n" + "/**\n" + " * Performs search on dashboard description.\n" + " * @param {string} search The text to search.\n" + " * @param {!smb.model.Dashboard} dashboard The dashboard to perform search on.\n" + " * @param {boolean} isFirstSearch Whether to treat this as matching at the\n" + " * beginning of a search.\n" + " * @return {?SearchboxForDashboards.SearchResultComponent} The search match\n" + " * component.\n" + " * @private\n" + " */\n" + "SearchboxForDashboards.prototype.doDescriptionSearch_ =\n" + " function(search, dashboard, isFirstSearch) {\n" + " var title = dashboard.titleDisplayText || dashboard.menuDisplayText;\n" + " return this.doTextSearch_(search, title, isFirstSearch,\n" + " SearchboxForDashboards.ComponentType.DESCRIPTION);\n" + "};\n\n" + "/**\n" + " * Searches the text.\n" + " * @param {string} search\n" + " * @param {string} text\n" + " * @param {boolean} isFirstSearch\n" + " * @param {smb.controllers.SearchboxForDashboards.ComponentType} type\n" + " * @return {?SearchboxForDashboards.SearchResultComponent} The search match\n" + " * component.\n" + " * @private\n" + " */\n" + "SearchboxForDashboards.prototype.doTextSearch_ = function(search, text,\n" + " isFirstSearch, type) {\n" + " var score = 0;\n" + " var searchRegex = new RegExp(search, 'i');\n" + " var match = text.match(searchRegex);\n" + " if (!match) {\n" + " return null;\n" + " }\n\n" + " score = match[0].length;\n" + " var weight = SearchboxForDashboards.WEIGHTS[type];\n" + " if (text.toLowerCase().startsWith(match[0].toLowerCase())) {\n" + " score *= weight.STARTING_MATCH;\n" + " if (isFirstSearch) {\n" + " score *= weight.FIRST_SUBSEARCH;\n" + " }\n" + " }\n\n" + " return goog.object.create(\n" + " type, match[0],\n" + " 'score', score,\n" + " 'type', type,\n" + " 'match', search\n" + " );\n" + "};\n\n" + "/**\n" + " * Perform search on dashboard tags.\n" + " * @param {string} search The text to search.\n" + " * @param {!smb.model.Dashboard} dashboard The dashboard to perform search on.\n" + " * @param {boolean} isFirstSearch\n" + " * @return {?SearchboxForDashboards.SearchResultComponent} The search match\n" + " * component.\n" + " * @private\n" + " */\n" + "SearchboxForDashboards.prototype.doTagSearch_ = function(search, dashboard,\n" + " isFirstSearch) {\n" + " if (!('tags' in dashboard)) {\n" + " return null;\n" + " }\n" + " var tagMatches = dashboard.tags.map(function(tag) {\n" + " return this.doTextSearch_(search, tag, isFirstSearch,\n" + " SearchboxForDashboards.ComponentType.TAG);\n" + " }, this);\n\n" + " var tagMatches = [];\n" + " var groups = goog.iter.groupBy(tagMatches,\n" + " function(tagMatch) { return tagMatch.match; });\n\n" + " var scores = [];\n" + " var score = 0;\n" + " var iterLeft = true;\n" + " while (iterLeft) {\n" + " try {\n" + " var matchTup = groups.next();\n" + " var key = matchTup[0];\n" + " var matches = matchTup[1];\n" + " var numMatches = matches.length;\n" + " var scores = matches.map(function(match) { return match.score; })\n" + " .reduce(function(a, b) { return a + b; }, 0);\n" + " var average = scores / numMatches;\n" + " // numMatches + 1 because the score for one should not be zero\n" + " // have to do log because too many dups for sqrt to make sense\n" + " score += (average * Math.log(numMatches + 1));\n" + " } catch (e) {\n" + " // goog.iter throws exception at the end rather than having a flag\n" + " // to check\n" + " iterLeft = false;\n" + " }\n" + " }\n\n" + " return {\n" + " score: score,\n" + " type: SearchboxForDashboards.ComponentType.TAG,\n" + " match: search\n" + " };\n" + "};\n\n" + "/**\n" + " * @param {string} search The text to search for.\n" + " * @param {!Array<!smb.model.Dashboard>} dashboards The dashboards to search\n" + " * over.\n" + " * @return {!Array<!SearchResultStruct>} The results, sorted.\n" + " * @private\n" + " */\n" + "SearchboxForDashboards.prototype.doSearch_ = function(search, dashboards) {\n" + " var scoreStructs = dashboards.map(function(dashboard) {\n" + " return this.doDashboardSearch_(search, dashboard, true, true);\n" + " }, this);\n" + " return scoreStructs\n" + " .filter(function(struct) { return struct.score > 0; }, this)\n" + " .sort(function(aStruct, bStruct) {\n" + " return bStruct.score - aStruct.score;\n" + " });\n" + "};\n\n" + "/**\n" + " * Updates the autocomplete results, showing the appropriate amount for the\n" + " * current search text.\n" + " */\n" + "SearchboxForDashboards.prototype.updateAutoComplete = function() {\n" + " var dashboards = this.navigationService_.getSearchableDashboards();\n" + " if (!dashboards) return;\n" + " var searchResults = this.doSearch_(this.search, dashboards);\n" + " var searchResultsShow = searchResults.length > 0;\n\n" + " this.searchResults = searchResults;\n" + " this.saveAutoCompleteEvent_();\n" + "};\n\n" + "/**\n" + " * Logs autocomplete search.\n" + " * @private\n" + " */\n" + "SearchboxForDashboards.prototype.saveAutoCompleteEvent_ = function() {\n" + " var urlQuery = this.location_.url();\n" + " // @see onlinesales.revenueprograms.sas.discovery.server.services.UserEventProvider\n" + " var endpoint = this.getUserEventResource_('persist');\n" + " var evnt = {\n" + " type: User.Event.SEARCH,\n" + " urlQuery: urlQuery,\n" + " search: this.search,\n" + " session: smbuser.session\n" + " };\n" + " endpoint.save(evnt);\n" + "};\n\n" + "/**\n" + " * Logs search result click.\n" + " * @param {number} dashboardId the id of the relavant dashboard\n" + " * @private\n" + " */\n" + "SearchboxForDashboards.prototype.saveSearchResultClick_ = function(dashboardId) {\n" + " var urlQuery = this.location_.url();\n" + " // @see onlinesales.revenueprograms.sas.discovery.server.services.UserEventProvider\n" + " var endpoint = this.getUserEventResource_('persist');\n" + " var evnt = {\n" + " dashboardId: dashboardId,\n" + " type: User.Event.SEARCH_CLICK,\n" + " urlQuery: urlQuery,\n" + " search: this.search,\n" + " session: smbuser.session\n" + " };\n" + " endpoint.save(evnt);\n" + "};\n\n" + "/**\n" + " * @param {string} action The action path for which to get endpoint.\n" + " * @return {!ngResource} Angular resource for the action on user events.\n" + " * @private\n" + " */\n" + "SearchboxForDashboards.prototype.getUserEventResource_ = function(action) {\n" + " return this.resource_(\n" + " goog.string.format('%s/%s', User.EVENT_ENDPOINT, action));\n" + "};\n\n" + "/**\n" + " * Currently returns the arguments, here because of past and potentially\n" + " * future formatting.\n" + " * @param {string} tag The tag string.\n" + " * @return {string} the tag display text\n" + " */\n" + "SearchboxForDashboards.prototype.getTagDisplayText = goog.functions.identity;\n\n" + "/**\n" + " * Gets the class for the given tag.\n" + " * @param {string} tag The tag.\n" + " * @return {string} The class name.\n" + " */\n" + "SearchboxForDashboards.prototype.getTagDisplayClass = function(tag) {\n" + " if (tag) {\n" + " var strArr = tag.split(':');\n" + " if (strArr.length == 2) {\n" + " return goog.string.format('tags-style-%s', strArr[0]);\n" + " } else {\n" + " return '';\n" + " }\n" + " }\n" + " return '';\n" + "};\n\n" + "/**\n" + " * Goes to the search results page, if that feature is enabled.\n" + " *\n" + " * @param {!jQuery.Event|!JQLite.Event} evt The fired event on keypress.\n" + " *\n" + " * @export\n" + " */\n" + "SearchboxForDashboards.prototype.searchBoxKeypressed = function(evt) {\n" + "};\n\n" + "/**\n" + " * Handler for clicking search result item. Navigates to the dashboard.\n" + " * @param {!smb.model.Dashboard} dashboard The dashboard selection clicked.\n" + " * @param {!jQuery.Event|!JQLite.Event} $event The event for the click.\n" + " */\n" + "SearchboxForDashboards.prototype.resultItemClicked = function(dashboard, $event) {\n" + " $event.stopPropagation();\n" + " this.saveSearchResultClick_(dashboard.id);\n" + " this.navigateToDashboard_(dashboard);\n" + "};\n\n" + "/**\n" + " * Navigates to the given dashboard.\n" + " * @param {!smb.model.Dashboard} dashboard The dashboard to navigate to.\n" + " * @private\n" + " */\n" + "SearchboxForDashboards.prototype.navigateToDashboard_ = function(dashboard) {\n" + " this.reset_();\n" + " this.location_.search({});\n" + " this.location_.path(dashboard.navigationURLPath);\n" + " this.route_.reload();\n" + "};\n\n" + "/**\n" + " * @param {!SearchboxForDashboards.SearchResultStruct} resultObj Representation of the\n" + " * search result.\n" + " * @return {?string} The title text for the search result, if there is any.\n" + " */\n" + "SearchboxForDashboards.prototype.getTitleText = function(resultObj) {\n" + " var dash = resultObj.dashboard;\n" + " return dash.titleDisplayText || dash.menuDisplayText;\n" + "};\n\n" + "/**\n" + " * @param {!SearchboxForDashboards.SearchResultStruct} resultObj Representation of the\n" + " * search result.\n" + " * @return {string} The description text for the search result.\n" + " */\n" + "SearchboxForDashboards.prototype.getDescriptionText = function(resultObj) {\n" + " return resultObj.dashboard.flatDescription;\n" + "};\n\n" + "/**\n" + " * @return {boolean} Whether to show the search box on this page.\n" + " */\n" + "SearchboxForDashboards.prototype.shouldShowResultBox = function() {\n" + " // Shows when it is active, there are results, and there is a search\n" + " return this.scope_.active && !this.hasNoSearchResults_() &&\n" + " this.search.length > 0;\n" + "};\n\n" + "/**\n" + " * Sets the search text to the empty string.\n" + " * @private\n" + " */\n" + "SearchboxForDashboards.prototype.clearSearchBoxText_ = function() {\n" + " this.search = '';\n" + "};\n\n" + "/**\n" + " * Sets the search results to an empty array.\n" + " * @private\n" + " */\n" + "SearchboxForDashboards.prototype.clearSearchResults_ = function() {\n" + " this.searchResults = [];\n" + "};\n\n" + "/**\n" + " * Reverts to initial state.\n" + " * @private\n" + " */\n" + "SearchboxForDashboards.prototype.reset_ = function() {\n" + " this.clearSearchBoxText_();\n" + " this.clearSearchResults_();\n" + "};\n\n" + "}); // goog.scope\n"; final String subst = "($1) => $2"; final Pattern pattern = Pattern.compile(regex); final Matcher matcher = pattern.matcher(string); // The substituted value will be contained in the result variable final String result = matcher.replaceAll(subst); System.out.println("Substitution result: " + result); } }

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