Regular Expressions 101

Save & Manage Regex

  • Current Version: 3
  • Save & Share
  • Community Library

Flavor

  • PCRE2 (PHP)
  • ECMAScript (JavaScript)
  • Python
  • Golang
  • Java
  • .NET 7.0 (C#)
  • Rust
  • PCRE (Legacy)
  • Regex Flavor Guide

Function

  • Match
  • Substitution
  • List
  • Unit Tests
Sponsors
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
Processing...

Test String

Code Generator

Generated Code

import re regex = re.compile(r"removed?\W*remove", flags=re.IGNORECASE) test_str = (" I'd like to stop Galleriffic slider at the last thumbs image, but I don't know how.\n" "Here is the code:\n\n" "// Primary Galleriffic initialization function that should be called on the thumbnail container.\n" "`$.fn.galleriffic = function(settings) {\n" " // Extend Gallery Object\n" " $.extend(this, {\n" " // Returns the version of the script\n" " version: $.galleriffic.version,\n\n" " // Current state of the slideshow\n" " isSlideshowRunning: false,\n" " slideshowTimeout: undefined,\n\n" " // This function is attached to the click event of generated hyperlinks within the gallery\n" " clickHandler: function(e, link) {\n" " this.play();\n\n" " if (!this.enableHistory) {\n" " // The href attribute holds the unique hash for an image\n" " var hash = $.galleriffic.normalizeHash($(link).attr('href'));\n" " $.galleriffic.gotoImage(hash);\n" " e.preventDefault();\n" " }\n" " },\n\n" " // Appends an image to the end of the set of images. Argument listItem can be either a jQuery DOM element or arbitrary html.\n" " // @param listItem Either a jQuery object or a string of html of the list item that is to be added to the gallery.\n" " appendImage: function(listItem) {\n" " this.addImage(listItem, false, false);\n" " return this;\n" " },\n\n" " // Inserts an image into the set of images. Argument listItem can be either a jQuery DOM element or arbitrary html.\n" " // @param listItem Either a jQuery object or a string of html of the list item that is to be added to the gallery.\n" " // @param {Integer} position The index within the gallery where the item shouold be added.\n" " insertImage: function(listItem, position) {\n" " this.addImage(listItem, false, true, position);\n" " return this;\n" " },\n\n" " // Adds an image to the gallery and optionally inserts/appends it to the DOM (thumbExists)\n" " // @param listItem Either a jQuery object or a string of html of the list item that is to be added to the gallery.\n" " // @param {Boolean} thumbExists Specifies whether the thumbnail already exists in the DOM or if it needs to be added.\n" " // @param {Boolean} insert Specifies whether the the image is appended to the end or inserted into the gallery.\n" " // @param {Integer} position The index within the gallery where the item shouold be added.\n" " addImage: function(listItem, thumbExists, insert, position) {\n" " var $li = ( typeof listItem === \"string\" ) ? $(listItem) : listItem; \n" " var $aThumb = $li.find('a.thumb');\n" " var slideUrl = $aThumb.attr('href');\n" " var title = $aThumb.attr('title');\n" " var $caption = $li.find('.caption').remove();\n" " var hash = $aThumb.attr('name');\n\n" " // Increment the image counter\n" " imageCounter++;\n\n" " // Autogenerate a hash value if none is present or if it is a duplicate\n" " if (!hash || allImages[''+hash]) {\n" " hash = imageCounter;\n" " }\n\n" " // Set position to end when not specified\n" " if (!insert)\n" " position = this.data.length;\n" " \n" " var imageData = {\n" " title:title,\n" " slideUrl:slideUrl,\n" " caption:$caption,\n" " hash:hash,\n" " gallery:this,\n" " index:position\n" " };\n\n" " // Add the imageData to this gallery's array of images\n" " if (insert) {\n" " this.data.splice(position, 0, imageData);\n\n" " // Reset index value on all imageData objects\n" " this.updateIndices(position);\n" " }\n" " else {\n" " this.data.push(imageData);\n" " }\n\n" " var gallery = this;\n\n" " // Add the element to the DOM\n" " if (!thumbExists) {\n" " // Update thumbs passing in addition post transition out handler\n" " this.updateThumbs(function() {\n" " var $thumbsUl = gallery.find('ul.thumbs');\n" " if (insert)\n" " $thumbsUl.children(':eq('+position+')').before($li);\n" " else\n" " $thumbsUl.append($li);\n" " \n" " if (gallery.onImageAdded)\n" " gallery.onImageAdded(imageData, $li);\n" " });\n" " }\n\n" " // Register the image globally\n" " allImages[''+hash] = imageData;\n\n" " // Setup attributes and click handler\n" " $aThumb.attr('rel', 'history')\n" " .attr('href', '#'+hash)\n" " .removeAttr('name')\n" " .click(function(e) {\n" " gallery.clickHandler(e, this);\n" " });\n\n" " return this;\n" " },\n\n" " // Removes an image from the gallery based on its index.\n" " // Returns false when the index is out of range.\n" " removeImageByIndex: function(index) {\n" " if (index < 0 || index >= this.data.length)\n" " return false;\n" " \n" " var imageData = this.data[index];\n" " if (!imageData)\n" " return false;\n" " \n" " this.removeImage(imageData);\n" " \n" " return true;\n" " },\n\n" " // Convenience method that simply calls the global removeImageByHash method.\n" " removeImageByHash: function(hash) {\n" " return $.galleriffic.removeImageByHash(hash, this);\n" " },\n\n" " // Removes an image from the gallery.\n" " removeImage: function(imageData) {\n" " var index = imageData.index;\n" " \n" " // Remove the image from the gallery data array\n" " this.data.splice(index, 1);\n" " \n" " // Remove the global registration\n" " delete allImages[''+imageData.hash];\n" " \n" " // Remove the image's list item from the DOM\n" " this.updateThumbs(function() {\n" " var $li = gallery.find('ul.thumbs')\n" " .children(':eq('+index+')')\n" " .remove();\n\n" " if (gallery.onImageRemoved)\n" " gallery.onImageRemoved(imageData, $li);\n" " });\n\n" " // Update each image objects index value\n" " this.updateIndices(index);\n\n" " return this;\n" " },\n\n" " // Updates the index values of the each of the images in the gallery after the specified index\n" " updateIndices: function(startIndex) {\n" " for (i = startIndex; i < this.data.length; i++) {\n" " this.data[i].index = i;\n" " }\n" " \n" " return this;\n" " },\n\n" " // Scraped the thumbnail container for thumbs and adds each to the gallery\n" " initializeThumbs: function() {\n" " this.data = [];\n" " var gallery = this;\n\n" " this.find('ul.thumbs > li').each(function(i) {\n" " gallery.addImage($(this), true, false);\n" " });\n\n" " return this;\n" " },\n\n" " isPreloadComplete: false,\n\n" " // Initalizes the image preloader\n" " preloadInit: function() {\n" " if (this.preloadAhead == 0) return this;\n" " \n" " this.preloadStartIndex = this.currentImage.index;\n" " var nextIndex = this.getNextIndex(this.preloadStartIndex);\n" " return this.preloadRecursive(this.preloadStartIndex, nextIndex);\n" " },\n\n" " // Changes the location in the gallery the preloader should work\n" " // @param {Integer} index The index of the image where the preloader should restart at.\n" " preloadRelocate: function(index) {\n" " // By changing this startIndex, the current preload script will restart\n" " this.preloadStartIndex = index;\n" " return this;\n" " },\n\n" " // Recursive function that performs the image preloading\n" " // @param {Integer} startIndex The index of the first image the current preloader started on.\n" " // @param {Integer} currentIndex The index of the current image to preload.\n" " preloadRecursive: function(startIndex, currentIndex) {\n" " // Check if startIndex has been relocated\n" " if (startIndex != this.preloadStartIndex) {\n" " var nextIndex = this.getNextIndex(this.preloadStartIndex);\n" " return this.preloadRecursive(this.preloadStartIndex, nextIndex);\n" " }\n\n" " var gallery = this;\n\n" " // Now check for preloadAhead count\n" " var preloadCount = currentIndex - startIndex;\n" " if (preloadCount < 0)\n" " preloadCount = this.data.length-1-startIndex+currentIndex;\n" " if (this.preloadAhead >= 0 && preloadCount > this.preloadAhead) {\n" " // Do this in order to keep checking for relocated start index\n" " setTimeout(function() { gallery.preloadRecursive(startIndex, currentIndex); }, 500);\n" " return this;\n" " }\n\n" " var imageData = this.data[currentIndex];\n" " if (!imageData)\n" " return this;\n\n" " // If already loaded, continue\n" " if (imageData.image)\n" " return this.preloadNext(startIndex, currentIndex); \n" " \n" " // Preload the image\n" " var image = new Image();\n" " \n" " image.onload = function() {\n" " imageData.image = this;\n" " gallery.preloadNext(startIndex, currentIndex);\n" " };\n\n" " image.alt = imageData.title;\n" " image.src = imageData.slideUrl;\n\n" " return this;\n" " },\n" " \n" " // Called by preloadRecursive in order to preload the next image after the previous has loaded.\n" " // @param {Integer} startIndex The index of the first image the current preloader started on.\n" " // @param {Integer} currentIndex The index of the current image to preload.\n" " preloadNext: function(startIndex, currentIndex) {\n" " var nextIndex = this.getNextIndex(currentIndex);\n" " if (nextIndex == startIndex) {\n" " this.isPreloadComplete = true;\n" " } else {\n" " // Use setTimeout to free up thread\n" " var gallery = this;\n" " setTimeout(function() { gallery.preloadRecursive(startIndex, nextIndex); }, 100);\n" " }\n\n" " return this;\n" " },\n\n" " // Safe way to get the next image index relative to the current image.\n" " // If the current image is the last, returns 0\n" " getNextIndex: function(index) {\n" " var nextIndex = index+1;\n" " if (nextIndex >= this.data.length)\n" " nextIndex = 0;\n" " return nextIndex;\n" " },\n\n" " // Safe way to get the previous image index relative to the current image.\n" " // If the current image is the first, return the index of the last image in the gallery.\n" " getPrevIndex: function(index) {\n" " var prevIndex = index-1;\n" " if (prevIndex < 0)\n" " prevIndex = this.data.length-1;\n" " return prevIndex;\n" " },\n\n" " // Pauses the slideshow\n" " pause: function() {\n" " this.isSlideshowRunning = false;\n" " if (this.slideshowTimeout) {\n" " clearTimeout(this.slideshowTimeout);\n" " this.slideshowTimeout = undefined;\n" " }\n\n" " if (this.$controlsContainer) {\n" " this.$controlsContainer\n" " .find('div.ss-controls a').removeClass().addClass('play')\n" " .attr('title', this.playLinkText)\n" " .attr('href', '#play')\n" " .html(this.playLinkText);\n" " }\n" " \n" " return this;\n" " },\n\n" " // Plays the slideshow\n" " play: function() {\n" " this.isSlideshowRunning = true;\n\n" " if (this.$controlsContainer) {\n" " this.$controlsContainer\n" " .find('.ss-controls a').removeClass().addClass('pause')\n" " .attr('title', this.pauseLinkText)\n" " .attr('href', '#pause')\n" " .html(this.pauseLinkText);\n" " }\n\n" " if (!this.slideshowTimeout) {\n" " var gallery = this;\n" " this.slideshowTimeout = setTimeout(function() { gallery.ssAdvance(); }, this.delay);\n" " }\n\n" " return this;\n" " },\n\n" " // Toggles the state of the slideshow (playing/paused)\n" " toggleSlideshow: function() {\n" " if (this.isSlideshowRunning)\n" " this.pause();\n" " else\n" " this.play();\n\n" " return this;\n" " },\n\n" " // Advances the slideshow to the next image and delegates navigation to the\n" " // history plugin when history is enabled\n" " // enableHistory is true\n" " ssAdvance: function() {\n" " if (this.isSlideshowRunning)\n" " this.next(true);\n\n" " return this;\n" " },\n\n" " // Advances the gallery to the next image.\n" " // @param {Boolean} dontPause Specifies whether to pause the slideshow.\n" " // @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled. \n" " next: function(dontPause, bypassHistory) {\n" " this.gotoIndex(this.getNextIndex(this.currentImage.index), dontPause, bypassHistory);\n" " return this;\n" " },\n\n" " // Navigates to the previous image in the gallery.\n" " // @param {Boolean} dontPause Specifies whether to pause the slideshow.\n" " // @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled.\n" " previous: function(dontPause, bypassHistory) {\n" " this.gotoIndex(this.getPrevIndex(this.currentImage.index), dontPause, bypassHistory);\n" " return this;\n" " },\n\n" " // Navigates to the next page in the gallery.\n" " // @param {Boolean} dontPause Specifies whether to pause the slideshow.\n" " // @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled.\n" " nextPage: function(dontPause, bypassHistory) {\n" " var page = this.getCurrentPage();\n" " var lastPage = this.getNumPages() - 1;\n" " if (page < lastPage) {\n" " var startIndex = page * this.numThumbs;\n" " var nextPage = startIndex + this.numThumbs;\n" " this.gotoIndex(nextPage, dontPause, bypassHistory);\n" " }\n\n" " return this;\n" " },\n\n" " // Navigates to the previous page in the gallery.\n" " // @param {Boolean} dontPause Specifies whether to pause the slideshow.\n" " // @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled.\n" " previousPage: function(dontPause, bypassHistory) {\n" " var page = this.getCurrentPage();\n" " if (page > 0) {\n" " var startIndex = page * this.numThumbs;\n" " var prevPage = startIndex - this.numThumbs; \n" " this.gotoIndex(prevPage, dontPause, bypassHistory);\n" " }\n" " \n" " return this;\n" " },\n\n" " // Navigates to the image at the specified index in the gallery\n" " // @param {Integer} index The index of the image in the gallery to display.\n" " // @param {Boolean} dontPause Specifies whether to pause the slideshow.\n" " // @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled.\n" " gotoIndex: function(index, dontPause, bypassHistory) {\n" " if (!dontPause)\n" " this.pause();\n" " \n" " if (index < 0) index = 0;\n" " else if (index >= this.data.length) index = this.data.length-1;\n" " \n" " var imageData = this.data[index];\n" " \n" " if (!bypassHistory && this.enableHistory)\n" " $.historyLoad(String(imageData.hash)); // At the moment, historyLoad only accepts string arguments\n" " else\n" " this.gotoImage(imageData);\n\n" " return this;\n" " },\n\n" " // This function is garaunteed to be called anytime a gallery slide changes.\n" " // @param {Object} imageData An object holding the image metadata of the image to navigate to.\n" " gotoImage: function(imageData) {\n" " var index = imageData.index;\n\n" " if (this.onSlideChange)\n" " this.onSlideChange(this.currentImage.index, index);\n" " \n" " this.currentImage = imageData;\n" " this.preloadRelocate(index);\n" " \n" " this.refresh();\n" " \n" " return this;\n" " },\n\n" " // Returns the default transition duration value. The value is halved when not\n" " // performing a synchronized transition.\n" " // @param {Boolean} isSync Specifies whether the transitions are synchronized.\n" " getDefaultTransitionDuration: function(isSync) {\n" " if (isSync)\n" " return this.defaultTransitionDuration;\n" " return this.defaultTransitionDuration / 2;\n" " },\n\n" " // Rebuilds the slideshow image and controls and performs transitions\n" " refresh: function() {\n" " var imageData = this.currentImage;\n" " if (!imageData)\n" " return this;\n\n" " var index = imageData.index;\n\n" " // Update Controls\n" " if (this.$controlsContainer) {\n" " this.$controlsContainer\n" " .find('.nav-controls a.prev').attr('href', '#'+this.data[this.getPrevIndex(index)].hash).end()\n" " .find('.nav-controls a.next').attr('href', '#'+this.data[this.getNextIndex(index)].hash);\n" " }\n\n" " var previousSlide = this.$imageContainer.find('span.current').addClass('previous').removeClass('current');\n" " var previousCaption = 0;\n\n" " if (this.$captionContainer) {\n" " previousCaption = this.$captionContainer.find('span.current').addClass('previous').removeClass('current');\n" " }\n\n" " // Perform transitions simultaneously if syncTransitions is true and the next image is already preloaded\n" " var isSync = this.syncTransitions && imageData.image;\n\n" " // Flag we are transitioning\n" " var isTransitioning = true;\n" " var gallery = this;\n\n" " var transitionOutCallback = function() {\n" " // Flag that the transition has completed\n" " isTransitioning = false;\n\n" " // Remove the old slide\n" " previousSlide.remove();\n\n" " // Remove old caption\n" " if (previousCaption)\n" " previousCaption.remove();\n\n" " if (!isSync) {\n" " if (imageData.image && imageData.hash == gallery.data[gallery.currentImage.index].hash) {\n" " gallery.buildImage(imageData, isSync);\n" " } else {\n" " // Show loading container\n" " if (gallery.$loadingContainer) {\n" " gallery.$loadingContainer.show();\n" " }\n" " }\n" " }\n" " };\n\n" " if (previousSlide.length == 0) {\n" " // For the first slide, the previous slide will be empty, so we will call the callback immediately\n" " transitionOutCallback();\n" " } else {\n" " if (this.onTransitionOut) {\n" " this.onTransitionOut(previousSlide, previousCaption, isSync, transitionOutCallback);\n" " } else {\n" " previousSlide.fadeTo(this.getDefaultTransitionDuration(isSync), 0.0, transitionOutCallback);\n" " if (previousCaption)\n" " previousCaption.fadeTo(this.getDefaultTransitionDuration(isSync), 0.0);\n" " }\n" " }\n\n" " // Go ahead and begin transitioning in of next image\n" " if (isSync)\n" " this.buildImage(imageData, isSync);\n\n" " if (!imageData.image) {\n" " var image = new Image();\n" " \n" " // Wire up mainImage onload event\n" " image.onload = function() {\n" " imageData.image = this;\n\n" " // Only build image if the out transition has completed and we are still on the same image hash\n" " if (!isTransitioning && imageData.hash == gallery.data[gallery.currentImage.index].hash) {\n" " gallery.buildImage(imageData, isSync);\n" " }\n" " };\n\n" " // set alt and src\n" " image.alt = imageData.title;\n" " image.src = imageData.slideUrl;\n" " }\n\n" " // This causes the preloader (if still running) to relocate out from the currentIndex\n" " this.relocatePreload = true;\n\n" " return this.syncThumbs();\n" " },\n\n" " // Called by the refresh method after the previous image has been transitioned out or at the same time\n" " // as the out transition when performing a synchronous transition.\n" " // @param {Object} imageData An object holding the image metadata of the image to build.\n" " // @param {Boolean} isSync Specifies whether the transitions are synchronized.\n" " buildImage: function(imageData, isSync) {\n" " var gallery = this;\n" " var nextIndex = this.getNextIndex(imageData.index);\n\n" " // Construct new hidden span for the image\n" " var newSlide = this.$imageContainer\n" " .append('<span class=\"image-wrapper current\"><a class=\"advance-link\" rel=\"history\" href=\"#'+this.data[nextIndex].hash+'\" title=\"'+imageData.title+'\">&nbsp;</a></span>')\n" " .find('span.current').css('opacity', '0');\n" " \n" " newSlide.find('a')\n" " .append(imageData.image)\n" " .click(function(e) {\n" " gallery.clickHandler(e, this);\n" " });\n" " \n" " var newCaption = 0;\n" " if (this.$captionContainer) {\n" " // Construct new hidden caption for the image\n" " newCaption = this.$captionContainer\n" " .append('<span class=\"image-caption current\"></span>')\n" " .find('span.current').css('opacity', '0')\n" " .append(imageData.caption);\n" " }\n\n" " // Hide the loading conatiner\n" " if (this.$loadingContainer) {\n" " this.$loadingContainer.hide();\n" " }\n\n" " // Transition in the new image\n" " if (this.onTransitionIn) {\n" " this.onTransitionIn(newSlide, newCaption, isSync);\n" " } else {\n" " newSlide.fadeTo(this.getDefaultTransitionDuration(isSync), 1.0);\n" " if (newCaption)\n" " newCaption.fadeTo(this.getDefaultTransitionDuration(isSync), 1.0);\n" " }\n" " \n" " if (this.isSlideshowRunning) {\n" " if (this.slideshowTimeout)\n" " clearTimeout(this.slideshowTimeout);\n\n" " this.slideshowTimeout = setTimeout(function() { gallery.ssAdvance(); }, this.delay);\n" " }\n\n" " return this;\n" " },\n\n" " // Returns the current page index that should be shown for the currentImage\n" " getCurrentPage: function() {\n" " return Math.floor(this.currentImage.index / this.numThumbs);\n" " },\n\n" " // Applies the selected class to the current image's corresponding thumbnail.\n" " // Also checks if the current page has changed and updates the displayed page of thumbnails if necessary.\n" " syncThumbs: function() {\n" " var page = this.getCurrentPage();\n" " if (page != this.displayedPage)\n" " this.updateThumbs();\n\n" " // Remove existing selected class and add selected class to new thumb\n" " var $thumbs = this.find('ul.thumbs').children();\n" " $thumbs.filter('.selected').removeClass('selected');\n" " $thumbs.eq(this.currentImage.index).addClass('selected');\n\n" " return this;\n" " },\n\n" " // Performs transitions on the thumbnails container and updates the set of\n" " // thumbnails that are to be displayed and the navigation controls.\n" " // @param {Delegate} postTransitionOutHandler An optional delegate that is called after\n" " // the thumbnails container has transitioned out and before the thumbnails are rebuilt.\n" " updateThumbs: function(postTransitionOutHandler) {\n" " var gallery = this;\n" " var transitionOutCallback = function() {\n" " // Call the Post-transition Out Handler\n" " if (postTransitionOutHandler)\n" " postTransitionOutHandler();\n" " \n" " gallery.rebuildThumbs();\n\n" " // Transition In the thumbsContainer\n" " if (gallery.onPageTransitionIn)\n" " gallery.onPageTransitionIn();\n" " else\n" " gallery.show();\n" " };\n\n" " // Transition Out the thumbsContainer\n" " if (this.onPageTransitionOut) {\n" " this.onPageTransitionOut(transitionOutCallback);\n" " } else {\n" " this.hide();\n" " transitionOutCallback();\n" " }\n\n" " return this;\n" " },\n\n" " // Updates the set of thumbnails that are to be displayed and the navigation controls.\n" " rebuildThumbs: function() {\n" " var needsPagination = this.data.length > this.numThumbs;\n\n" " // Rebuild top pager\n" " if (this.enableTopPager) {\n" " var $topPager = this.find('div.top');\n" " if ($topPager.length == 0)\n" " $topPager = this.prepend('<div class=\"top pagination\"></div>').find('div.top');\n" " else\n" " $topPager.empty();\n\n" " if (needsPagination)\n" " this.buildPager($topPager);\n" " }\n\n" " // Rebuild bottom pager\n" " if (this.enableBottomPager) {\n" " var $bottomPager = this.find('div.bottom');\n" " if ($bottomPager.length == 0)\n" " $bottomPager = this.append('<div class=\"bottom pagination\"></div>').find('div.bottom');\n" " else\n" " $bottomPager.empty();\n\n" " if (needsPagination)\n" " this.buildPager($bottomPager);\n" " }\n\n" " var page = this.getCurrentPage();\n" " var startIndex = page*this.numThumbs;\n" " var stopIndex = startIndex+this.numThumbs-1;\n" " if (stopIndex >= this.data.length)\n" " stopIndex = this.data.length-1;\n\n" " // Show/Hide thumbs\n" " var $thumbsUl = this.find('ul.thumbs');\n" " $thumbsUl.find('li').each(function(i) {\n" " var $li = $(this);\n" " if (i >= startIndex && i <= stopIndex) {\n" " $li.show();\n" " } else {\n" " $li.hide();\n" " }\n" " });\n\n" " this.displayedPage = page;\n\n" " // Remove the noscript class from the thumbs container ul\n" " $thumbsUl.removeClass('noscript');\n" " \n" " return this;\n" " },\n\n" " // Returns the total number of pages required to display all the thumbnails.\n" " getNumPages: function() {\n" " return Math.ceil(this.data.length/this.numThumbs);\n" " },\n\n" " // Rebuilds the pager control in the specified matched element.\n" " // @param {jQuery} pager A jQuery element set matching the particular pager to be rebuilt.\n" " buildPager: function(pager) {\n" " var gallery = this;\n" " var numPages = this.getNumPages();\n" " var page = this.getCurrentPage();\n" " var startIndex = page * this.numThumbs;\n" " var pagesRemaining = this.maxPagesToShow - 1;\n" " \n" " var pageNum = page - Math.floor((this.maxPagesToShow - 1) / 2) + 1;\n" " if (pageNum > 0) {\n" " var remainingPageCount = numPages - pageNum;\n" " if (remainingPageCount < pagesRemaining) {\n" " pageNum = pageNum - (pagesRemaining - remainingPageCount);\n" " }\n" " }\n\n" " if (pageNum < 0) {\n" " pageNum = 0;\n" " }\n\n" " // Prev Page Link\n" " if (page > 0) {\n" " var prevPage = startIndex - this.numThumbs;\n" " pager.append('<a rel=\"history\" href=\"#'+this.data[prevPage].hash+'\" title=\"'+this.prevPageLinkText+'\">'+this.prevPageLinkText+'</a>');\n" " }\n\n" " // Create First Page link if needed\n" " if (pageNum > 0) {\n" " this.buildPageLink(pager, 0, numPages);\n" " if (pageNum > 1)\n" " pager.append('<span class=\"ellipsis\">&hellip;</span>');\n" " \n" " pagesRemaining--;\n" " }\n\n" " // Page Index Links\n" " while (pagesRemaining > 0) {\n" " this.buildPageLink(pager, pageNum, numPages);\n" " pagesRemaining--;\n" " pageNum++;\n" " }\n\n" " // Create Last Page link if needed\n" " if (pageNum < numPages) {\n" " var lastPageNum = numPages - 1;\n" " if (pageNum < lastPageNum)\n" " pager.append('<span class=\"ellipsis\">&hellip;</span>');\n\n" " this.buildPageLink(pager, lastPageNum, numPages);\n" " }\n\n" " // Next Page Link\n" " var nextPage = startIndex + this.numThumbs;\n" " if (nextPage < this.data.length) {\n" " pager.append('<a rel=\"history\" href=\"#'+this.data[nextPage].hash+'\" title=\"'+this.nextPageLinkText+'\">'+this.nextPageLinkText+'</a>');\n" " }\n\n" " pager.find('a').click(function(e) {\n" " gallery.clickHandler(e, this);\n" " });\n\n" " return this;\n" " },\n\n" " // Builds a single page link within a pager. This function is called by buildPager\n" " // @param {jQuery} pager A jQuery element set matching the particular pager to be rebuilt.\n" " // @param {Integer} pageNum The page number of the page link to build.\n" " // @param {Integer} numPages The total number of pages required to display all thumbnails.\n" " buildPageLink: function(pager, pageNum, numPages) {\n" " var pageLabel = pageNum + 1;\n" " var currentPage = this.getCurrentPage();\n" " if (pageNum == currentPage)\n" " pager.append('<span class=\"current\">'+pageLabel+'</span>');\n" " else if (pageNum < numPages) {\n" " var imageIndex = pageNum*this.numThumbs;\n" " pager.append('<a rel=\"history\" href=\"#'+this.data[imageIndex].hash+'\" title=\"'+pageLabel+'\">'+pageLabel+'</a>');\n" " }\n" " \n" " return this;\n" " }\n" " });\n\n" " // Now initialize the gallery\n" " $.extend(this, defaults, settings);\n" " \n" " // Verify the history plugin is available\n" " if (this.enableHistory && !$.historyInit)\n" " this.enableHistory = false;\n" " \n" " // Select containers\n" " if (this.imageContainerSel) this.$imageContainer = $(this.imageContainerSel);\n" " if (this.captionContainerSel) this.$captionContainer = $(this.captionContainerSel);\n" " if (this.loadingContainerSel) this.$loadingContainer = $(this.loadingContainerSel);\n\n" " // Initialize the thumbails\n" " this.initializeThumbs();\n" " \n" " if (this.maxPagesToShow < 3)\n" " this.maxPagesToShow = 3;\n\n" " this.displayedPage = -1;\n" " this.currentImage = this.data[0];\n" " var gallery = this;\n\n" " // Hide the loadingContainer\n" " if (this.$loadingContainer)\n" " this.$loadingContainer.hide();\n\n" " // Setup controls\n" " if (this.controlsContainerSel) {\n" " this.$controlsContainer = $(this.controlsContainerSel).empty();\n" " \n" " if (this.renderSSControls) {\n" " if (this.autoStart) {\n" " this.$controlsContainer\n" " .append('<div class=\"ss-controls\"><a href=\"#pause\" class=\"pause\" title=\"'+this.pauseLinkText+'\">'+this.pauseLinkText+'</a></div>');\n" " } else {\n" " this.$controlsContainer\n" " .append('<div class=\"ss-controls\"><a href=\"#play\" class=\"play\" title=\"'+this.playLinkText+'\">'+this.playLinkText+'</a></div>');\n" " }\n\n" " this.$controlsContainer.find('div.ss-controls a')\n" " .click(function(e) {\n" " gallery.toggleSlideshow();\n" " e.preventDefault();\n" " return false;\n" " });\n" " }\n" " \n" " if (this.renderNavControls) {\n" " this.$controlsContainer\n" " .append('<div class=\"nav-controls\"><a class=\"prev\" rel=\"history\" title=\"'+this.prevLinkText+'\">'+this.prevLinkText+'</a><a class=\"next\" rel=\"history\" title=\"'+this.nextLinkText+'\">'+this.nextLinkText+'</a></div>')\n" " .find('div.nav-controls a')\n" " .click(function(e) {\n" " gallery.clickHandler(e, this);\n" " });\n" " }\n" " }\n\n" " var initFirstImage = !this.enableHistory || !location.hash;\n" " if (this.enableHistory && location.hash) {\n" " var hash = $.galleriffic.normalizeHash(location.hash);\n" " var imageData = allImages[hash];\n" " if (!imageData)\n" " initFirstImage = true;\n" " }\n\n" " // Setup gallery to show the first image\n" " if (initFirstImage)\n" " this.gotoIndex(0, false, true);\n\n" " // Setup Keyboard Navigation\n" " if (this.enableKeyboardNavigation) {\n" " $(document).keydown(function(e) {\n" " var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;\n" " switch(key) {\n" " case 32: // space\n" " gallery.next();\n" " e.preventDefault();\n" " break;\n" " case 33: // Page Up\n" " gallery.previousPage();\n" " e.preventDefault();\n" " break;\n" " case 34: // Page Down\n" " gallery.nextPage();\n" " e.preventDefault();\n" " break;\n" " case 35: // End\n" " gallery.gotoIndex(gallery.data.length-1);\n" " e.preventDefault();\n" " break;\n" " case 36: // Home\n" " gallery.gotoIndex(0);\n" " e.preventDefault();\n" " break;\n" " case 37: // left arrow\n" " gallery.previous();\n" " e.preventDefault();\n" " break;\n" " case 39: // right arrow\n" " gallery.next();\n" " e.preventDefault();\n" " break;\n" " }\n" " });\n" " }\n\n" " // Auto start the slideshow\n" " if (this.autoStart)\n" " this.play();\n\n" " // Kickoff Image Preloader after 1 second\n" " setTimeout(function() { gallery.preloadInit(); }, 0);\n\n" " return this;\n" "};\n" "})(jQuery);`") match = regex.search(test_str) if match: print(f"Match was found at {match.start()}-{match.end()}: {match.group()}") for group_num, group in enumerate(match.groups(), start=1): print(f"Group {group_num} found at {match.start(group_num)}-{match.end(group_num)}: {group}")

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 Python, please visit: https://docs.python.org/3/library/re.html