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

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