Regex: Sticky flag "y", searching at position
JavaScript offers a range of powerful tools for string manipulation, and among these tools, the sticky flag (y) in regular expressions holds a unique position.
The y flag — the sticky flag — is one of the flags you can add to a JavaScript regular expression. It anchors every search to one exact position: the regex's lastIndex. If a match cannot start exactly at lastIndex, the match fails — the engine does not scan forward looking for one elsewhere.
This page covers what the sticky flag does, how it differs from the global (g) flag, how lastIndex is read and updated, the common gotchas, and where the flag is genuinely worth using (tokenizers and sequential parsers).
The Concept of the Sticky Flag (y)
The sticky flag (y) ensures that the match starts exactly at the index stored in the regex object's lastIndex property. This is the key contrast with the global (g) flag: g lets the engine scan forward from lastIndex to find the next match anywhere later in the string, while y requires the match to begin at lastIndex or not at all. That "no scanning forward" behavior is exactly what a tokenizer needs — it guarantees the input is consumed contiguously, with no unexpected gaps between tokens.
y does not scan forward — g does
The clearest way to see the difference is to give both flags a pattern that does not match at position 0:
The g flag finds abc even though it starts at index 3. The y flag returns null, because position 0 holds a ., not the start of abc.
In the example above, the y flag ensures that the second test call starts matching at the position immediately following the previous match. Two details are worth noting:
- A successful match advances
lastIndexto the index right after the match (0 → 3 → 6). This auto-advance is what lets you calltest/execin a loop. - A failed match resets
lastIndexto 0. After the third call returnsfalse,lastIndexis back at 0, ready to start over.
lastIndex is read and written
lastIndex is not just an input you set — the engine updates it for you on every test/exec call that uses y (or g). So the normal pattern is: set lastIndex once if you want to start somewhere other than 0, then let the loop manage it.
Sticky also affects anchors
With the y flag, the start-of-string anchor ^ is not re-anchored to lastIndex — ^ still means "start of the whole string" (or start of a line with the m flag). The sticky behavior comes from the implicit "match at lastIndex" rule, not from rewriting ^. So a pattern like /^x/y will fail at any lastIndex greater than 0, because ^ can never be satisfied there.
Practical Applications of the Sticky Flag
Parsing Data Streams
The sticky flag is particularly advantageous when parsing data streams where you need to match tokens sequentially.
Tokenizing Strings
Another common use case is tokenizing strings where you need to ensure that the tokenizer proceeds from one match to the next without skipping any characters.
Searching at a Specific Position
JavaScript's lastIndex property combined with the sticky flag can be employed to search for patterns starting from a specific position in a string.
In this example, setting lastIndex to 6 allows the test method to find the word "world" starting from the specified position.
Combining Sticky Flag with Other Flags
The sticky flag can be combined with other flags such as g (global) to enhance pattern matching capabilities. In this example, the g flag allows for a global search throughout the string, while the y flag ensures that each match starts exactly at the lastIndex position. This combination allows you to perform a global search with the strict sequential matching behavior of the sticky flag.
In this example, we updated the regex to consume the comma delimiter. This ensures the next match starts at the correct position without manual index manipulation.
Advanced Examples
Extracting Key-Value Pairs
Consider a more complex scenario where you need to extract key-value pairs from a string with various separators. Each piece of the pair is pulled out with a capturing group — match[1] is the key and match[3] is the value.
Parsing Logs
The sticky flag can be incredibly useful when parsing structured logs where entries must be matched from specific positions.
Note the message group is [^;]+ ("everything up to the next ;") rather than \w+. With \w+, a message containing a space would stop the match mid-entry; because the sticky flag refuses to skip ahead, the very next exec would fail and the loop would end early — silently dropping the remaining entries. This is the most common sticky-flag gotcha: your pattern must consume the input contiguously, or parsing stops dead.
When to use y (and when not to)
Reach for the sticky flag when:
- You are writing a tokenizer or parser and need to consume the input contiguously, one token at a time, with no gaps allowed.
- You want to test whether a pattern matches at one exact position, without the engine wandering off to find a match later in the string.
Prefer the plain global flag (g) when you simply want all matches anywhere in the string and you don't care whether they are adjacent — for example, finding every email address in a document.
Remember the two rules that cause most sticky-flag bugs: a failed match resets lastIndex to 0, and your pattern must consume every character between matches or the loop stops early.
Conclusion
The sticky flag (y) trades the "scan anywhere" convenience of g for strict, position-locked matching at lastIndex. That trade-off is exactly what you want when building tokenizers and sequential parsers, where contiguous consumption matters. Combine it with capturing groups to extract structured data, and keep an eye on lastIndex — once you understand how it advances and resets, sticky matching becomes a precise, predictable tool.
Related topics
- Patterns and flags
- Anchors: string start
^and end$ - Capturing groups
- Regular expressions in JavaScript