• Skip to main content
  • Skip to search
  • Skip to select language
HTML

Structure of content on the web

  • Web APIs

    Interfaces for building web applications

  • Learn
    • CSS

      Learn to style content using CSS

    • Overview

      A customized MDN experience

    • FAQ

      Frequently asked questions about MDN Plus

  • HTTP Observatory

    Scan a website for free

  • JavaScript
  • lastIndex
      • Deutsch
      • Français
      • 日本語
      • Русский
      • 中文 (简体)

    In this article

    • Try it
    • Value
    • Description
    • Examples
    • Specifications
    • Browser compatibility
    • See also
    1. escape()
  • Static properties
    1. $1, …, $9 Deprecated
    2. input ($_) Deprecated
    3. lastMatch ($&) Deprecated
    4. lastParen ($+) Deprecated
    5. leftContext ($`) Deprecated
    6. rightContext ($') Deprecated
    7. compile() Deprecated
    8. [Symbol.match]()
    9. [Symbol.split]()
  • Instance properties
    1. global
    2. source
    3. Object/Function
    4. Static methods
      1. toString()
      2. displayName Non-standard
      3. arguments Non-standard Deprecated
      4. caller Non-standard Deprecated
    5. Instance methods
      1. __defineGetter__() Deprecated
      2. __defineSetter__() Deprecated
      3. __lookupGetter__() Deprecated
      4. __lookupSetter__() Deprecated
      5. toLocaleString()
      6. __proto__ Deprecated
      7. RegExp instance specifies the index at which to start the next match.

  • Try it

    const regex1 = /foo/g;
    const str1 = "table football, foosball";
    
    regex1.test(str1);
    
    console.log(regex1.lastIndex);
    / Expected output: 9
    
    regex1.test(str1);
    
    console.log(regex1.lastIndex);
    / Expected output: 19
    

    Value

    A non-negative integer.

    Property attributes of RegExp: lastIndex
    Writableyes
    Enumerableno
    Configurableno

    Description

    This property is set only if the regular expression instance used the g flag to indicate a global search, or the y flag to indicate a sticky search. The following rules apply when exec() is called on a given input:

    • If lastIndex is greater than the length of the input, exec() will not find a match, and lastIndex will be set to 0.
    • If lastIndex is equal to or less than the length of the input, exec() will attempt to match the input starting from lastIndex.
      • If exec() finds a match, then lastIndex will be set to the position of the end of the matched string in the input.
      • If exec() does not find a match, then lastIndex will be set to 0.

    Other regex-related methods, such as String.prototype.replace(), etc., call exec() under the hood, so they have different effects on lastIndex. See their respective pages for details.

    Examples

    Using lastIndex

    Consider the following sequence of statements:

    js
    const re = /(hi)?/g;
    

    Matches the empty string.

    js
    console.log(re.exec("hi"));
    console.log(re.lastIndex);
    

    Returns ["hi", "hi"] with lastIndex equal to 2.

    js
    console.log(re.exec("hi"));
    console.log(re.lastIndex);
    

    Returns ["", undefined], an empty array whose zeroth element is the match string. In this case, the empty string because lastIndex was 2 (and still is 2) and hi has length 2.

    Using lastIndex with sticky regexes

    The lastIndex property is writable. You can set it to make the regex start its next search at a given index.

    The y flag almost always requires setting lastIndex. It always matches strictly at lastIndex and does not attempt any later positions. This is usually useful for writing parsers, when you want to match tokens only at the current position.

    js
    const stringPattern = /"[^"]*"/y;
    const input = `const message = "Hello world";`;
    
    stringPattern.lastIndex = 6;
    console.log(stringPattern.exec(input)); / null
    
    stringPattern.lastIndex = 16;
    console.log(stringPattern.exec(input)); / ['"Hello world"']
    

    Rewinding lastIndex

    The g flag also benefits from setting lastIndex. One common use case is when the string is modified in the middle of a global search. In this case, we may miss a particular match if the string is shortened. We can avoid this by rewinding lastIndex.

    js
    const mdLinkPattern = /\[[^[\]]+\]\((?<link>[^()\s]+)\)/dg;
    
    function resolveMDLink(line) {
      let match;
      let modifiedLine = line;
      while ((match = mdLinkPattern.exec(modifiedLine))) {
        const originalLink = match.groups.link;
        const resolvedLink = originalLink.replaceAll(/^files|\/index\.md$/g, "");
        modifiedLine =
          modifiedLine.slice(0, match.indices.groups.link[0]) +
          resolvedLink +
          modifiedLine.slice(match.indices.groups.link[1]);
        / Rewind the pattern to the end of the resolved link
        mdLinkPattern.lastIndex += resolvedLink.length - originalLink.length;
      }
      return modifiedLine;
    }
    
    console.log(
      resolveMDLink(
        "[`lastIndex`](files/en-us/web/javascript/reference/global_objects/regexp/lastindex/index.md)",
      ),
    ); / [`lastIndex`](/en-us/web/javascript/reference/global_objects/regexp/lastindex)
    console.log(
      resolveMDLink(
        "[`ServiceWorker`](files/en-us/web/api/sharedworker/index.md)",
      ),
    ); / [`ServiceWorker`](/en-us/web/api/sharedworker)
    

    Try deleting the mdLinkPattern.lastIndex += resolvedLink.length - originalLink.length line and running the second example. You will find that the second link is not replaced correctly, because the lastIndex is already past the link's index after the string is shortened.

    Warning: This example is for demonstration only. To deal with Markdown, you should probably use a parsing library instead of regex.

    Optimizing searching

    You can optimize searching by setting lastIndex to a point where previous possible occurrences can be ignored. For example, instead of this:

    js
    const stringPattern = /"[^"]*"/g;
    const input = `const message = "Hello " + "world";`;
    
    / Pretend we've already dealt with the previous parts of the string
    let offset = 26;
    const remainingInput = input.slice(offset);
    const nextString = stringPattern.exec(remainingInput);
    console.log(nextString[0]); / "world"
    offset += nextString.index + nextString.length;
    

    Consider this:

    js
    stringPattern.lastIndex = offset;
    const nextString = stringPattern.exec(remainingInput);
    console.log(nextString[0]); / "world"
    offset = stringPattern.lastIndex;
    

    This is potentially more performant because we avoid string slicing.

    Avoiding side effects

    The side effects caused by exec() can be confusing, especially if the input is different for each exec().

    js
    const re = /foo/g;
    console.log(re.test("foo bar")); / true
    console.log(re.test("foo baz")); / false, because lastIndex is non-zero
    

    This is even more confusing when you are hand-modifying lastIndex. To contain the side effects, remember to reset lastIndex after each input is completely processed.

    js
    const re = /foo/g;
    console.log(re.test("foo bar")); / true
    re.lastIndex = 0;
    console.log(re.test("foo baz")); / true
    

    With some abstraction, you can require lastIndex to be set to a particular value before each exec() call.

    js
    function createMatcher(pattern) {
      / Create a copy, so that the original regex is never updated
      const regex = new RegExp(pattern, "g");
      return (input, offset) => {
        regex.lastIndex = offset;
        return regex.exec(input);
      };
    }
    
    const matchFoo = createMatcher(/foo/);
    console.log(matchFoo("foo bar", 0)[0]); / "foo"
    console.log(matchFoo("foo baz", 0)[0]); / "foo"
    

    Specifications

    Specification
    ECMAScript® 2026 Language Specification
    # sec-properties-of-regexp-instances

    Browser compatibility

    See also

    • RegExp.prototype.dotAll
    • RegExp.prototype.global
    • RegExp.prototype.hasIndices
    • RegExp.prototype.ignoreCase
    • RegExp.prototype.multiline
    • RegExp.prototype.source
    • RegExp.prototype.sticky
    • RegExp.prototype.unicode

    Help improve MDN

    RegExp object represents a regular expression, a notation for matching text patterns.","name":"Regular expressions"}},"browserCompat":["javascript.builtins.RegExp.lastIndex"],"pageType":"javascript-instance-data-property"}}

    Follow Lee on X/Twitter - Father, Husband, Serial builder creating AI, crypto, games & web tools. We are friends :) AI Will Come To Life!

    Check out: eBank.nz (Art Generator) | Netwrck.com (AI Tools) | Text-Generator.io (AI API) | BitBank.nz (Crypto AI) | ReadingTime (Kids Reading) | RewordGame | BigMultiplayerChess | WebFiddle | How.nz | Helix AI Assistant