const regex = /(\$)
# Regexp for textmate dynamic variables
#TM_(
# BUNDLE_SUPPORT|COMMENT_(?:END|MODE|START)|CURRENT_(?:LINE|WORD)|DIRECTORY|FILE(?:NAME|PATH)|
# LINE_(?:INDEX|NUMBER)|PROJECT_DIRECTORY|SCOPE|SELECTED_(?:FILE[S]?|TEXT)|SOFT_TABS|SUPPORT_PATH|TAB_SIZE
#)
(?:
# BASIC
# BASIC: Variable name, no brackets
(?:(TM_[A-Z]+(?:_[A-Z]+)*)|([\d]))(?!\{)
|
# BRACKETED
([\{])
# BRACKETED: Variable name
(?:(TM_[A-Z]+(?:_[A-Z]+)*)|([\d]))
# BRACKETED: Post variable name expression
(?:
# Default keyword, single
([:].+?(?=[\}]))
|
# Default keyword, options
([\|].+?[\|](?=[\}]))
|
# Regular expression
(?:
([\/])
(.+?(?=\/))
([\/])
(.+?(?=\/))
([\/])
# Flags
# Not sure how to validate fully without back references?
([imx]{3})
(?=\})
)
|
(?:
([\/])
([^\/\}]+?)
(
(?<![\\]{2})
[\/]
)
([^\/\}]+?)
(
(?<![\\]{2})
[\/]
)
# Flags
# Not sure how to validate fully without back references?
([imx]{3})
)
|
# Match to bracket
(.+?(?=[\}]))?
)?
([\}])
)/gm;
// Alternative syntax using RegExp constructor
// const regex = new RegExp('(\\$)
# Regexp for textmate dynamic variables
#TM_(
# BUNDLE_SUPPORT|COMMENT_(?:END|MODE|START)|CURRENT_(?:LINE|WORD)|DIRECTORY|FILE(?:NAME|PATH)|
# LINE_(?:INDEX|NUMBER)|PROJECT_DIRECTORY|SCOPE|SELECTED_(?:FILE[S]?|TEXT)|SOFT_TABS|SUPPORT_PATH|TAB_SIZE
#)
(?:
# BASIC
# BASIC: Variable name, no brackets
(?:(TM_[A-Z]+(?:_[A-Z]+)*)|([\\d]))(?!\\{)
|
# BRACKETED
([\\{])
# BRACKETED: Variable name
(?:(TM_[A-Z]+(?:_[A-Z]+)*)|([\\d]))
# BRACKETED: Post variable name expression
(?:
# Default keyword, single
([:].+?(?=[\\}]))
|
# Default keyword, options
([\\|].+?[\\|](?=[\\}]))
|
# Regular expression
(?:
([\\\/])
(.+?(?=\\\/))
([\\\/])
(.+?(?=\\\/))
([\\\/])
# Flags
# Not sure how to validate fully without back references?
([imx]{3})
(?=\\})
)
|
(?:
([\\\/])
([^\\\/\\}]+?)
(
(?<![\\\\]{2})
[\\\/]
)
([^\\\/\\}]+?)
(
(?<![\\\\]{2})
[\\\/]
)
# Flags
# Not sure how to validate fully without back references?
([imx]{3})
)
|
# Match to bracket
(.+?(?=[\\}]))?
)?
([\\}])
)', 'gm')
const str = `~~ Number Variables ~~~~~~~~~
Basic
"\$0"
Bracketed
"\${1}
Default Value
"\${2:default}"
Default Values
"\${3|defaultA,defaultB|}"
Regex Replace
"\${4/find/replace/gmi}"
~~ Dynamic Variables ~~~~~~~~
Basic
"\$TM_SELECTION_START"
Bracketed
"\${TM_SELECTION_END}"
Default Value
"\${TM_SELECTED_FILE:default}"
Default Values
"\${TM_SELECTED_TEXT|defaultA,defaultB|}"
Regex Replace
"\${TM_SELECTED_FILES/find/replace/gmi}"
`;
// Reset `lastIndex` if this regex is defined globally
// regex.lastIndex = 0;
let m;
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
console.log(`Found match, group ${groupIndex}: ${match}`);
});
}
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 JavaScript, please visit: https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions