mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
#1629 Use string replace instead of while loop
This commit is contained in:
@ -6,20 +6,33 @@ export {
|
|||||||
runRegexScript,
|
runRegexScript,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum {number} Where the regex script should be applied
|
||||||
|
*/
|
||||||
const regex_placement = {
|
const regex_placement = {
|
||||||
// MD Display is deprecated. Do not use.
|
/**
|
||||||
|
* @deprecated MD Display is deprecated. Do not use.
|
||||||
|
*/
|
||||||
MD_DISPLAY: 0,
|
MD_DISPLAY: 0,
|
||||||
USER_INPUT: 1,
|
USER_INPUT: 1,
|
||||||
AI_OUTPUT: 2,
|
AI_OUTPUT: 2,
|
||||||
SLASH_COMMAND: 3,
|
SLASH_COMMAND: 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum {number} How the regex script should replace the matched string
|
||||||
|
*/
|
||||||
const regex_replace_strategy = {
|
const regex_replace_strategy = {
|
||||||
REPLACE: 0,
|
REPLACE: 0,
|
||||||
OVERLAY: 1,
|
OVERLAY: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Originally from: https://github.com/IonicaBizau/regex-parser.js/blob/master/lib/index.js
|
/**
|
||||||
|
* Instantiates a regular expression from a string.
|
||||||
|
* @param {string} input The input string.
|
||||||
|
* @returns {RegExp} The regular expression instance.
|
||||||
|
* @copyright Originally from: https://github.com/IonicaBizau/regex-parser.js/blob/master/lib/index.js
|
||||||
|
*/
|
||||||
function regexFromString(input) {
|
function regexFromString(input) {
|
||||||
try {
|
try {
|
||||||
// Parse input
|
// Parse input
|
||||||
@ -37,8 +50,21 @@ function regexFromString(input) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parent function to fetch a regexed version of a raw string
|
/**
|
||||||
|
* Parent function to fetch a regexed version of a raw string
|
||||||
|
* @param {string} rawString The raw string to be regexed
|
||||||
|
* @param {regex_placement} placement The placement of the string
|
||||||
|
* @param {RegexParams} params The parameters to use for the regex script
|
||||||
|
* @returns {string} The regexed string
|
||||||
|
* @typedef {{characterOverride?: string, isMarkdown?: boolean, isPrompt?: boolean }} RegexParams The parameters to use for the regex script
|
||||||
|
*/
|
||||||
function getRegexedString(rawString, placement, { characterOverride, isMarkdown, isPrompt } = {}) {
|
function getRegexedString(rawString, placement, { characterOverride, isMarkdown, isPrompt } = {}) {
|
||||||
|
// WTF have you passed me?
|
||||||
|
if (typeof rawString !== 'string') {
|
||||||
|
console.warn('getRegexedString: rawString is not a string. Returning empty string.');
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
let finalString = rawString;
|
let finalString = rawString;
|
||||||
if (extension_settings.disabledExtensions.includes('regex') || !rawString || placement === undefined) {
|
if (extension_settings.disabledExtensions.includes('regex') || !rawString || placement === undefined) {
|
||||||
return finalString;
|
return finalString;
|
||||||
@ -66,8 +92,9 @@ function getRegexedString(rawString, placement, { characterOverride, isMarkdown,
|
|||||||
* Runs the provided regex script on the given string
|
* Runs the provided regex script on the given string
|
||||||
* @param {object} regexScript The regex script to run
|
* @param {object} regexScript The regex script to run
|
||||||
* @param {string} rawString The string to run the regex script on
|
* @param {string} rawString The string to run the regex script on
|
||||||
* @param {object} params The parameters to use for the regex script
|
* @param {RegexScriptParams} params The parameters to use for the regex script
|
||||||
* @returns {string} The new string
|
* @returns {string} The new string
|
||||||
|
* @typedef {{characterOverride?: string}} RegexScriptParams The parameters to use for the regex script
|
||||||
*/
|
*/
|
||||||
function runRegexScript(regexScript, rawString, { characterOverride } = {}) {
|
function runRegexScript(regexScript, rawString, { characterOverride } = {}) {
|
||||||
let newString = rawString;
|
let newString = rawString;
|
||||||
@ -75,7 +102,6 @@ function runRegexScript(regexScript, rawString, { characterOverride } = {}) {
|
|||||||
return newString;
|
return newString;
|
||||||
}
|
}
|
||||||
|
|
||||||
let match;
|
|
||||||
const findRegex = regexFromString(regexScript.substituteRegex ? substituteParams(regexScript.findRegex) : regexScript.findRegex);
|
const findRegex = regexFromString(regexScript.substituteRegex ? substituteParams(regexScript.findRegex) : regexScript.findRegex);
|
||||||
|
|
||||||
// The user skill issued. Return with nothing.
|
// The user skill issued. Return with nothing.
|
||||||
@ -83,46 +109,31 @@ function runRegexScript(regexScript, rawString, { characterOverride } = {}) {
|
|||||||
return newString;
|
return newString;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((match = findRegex.exec(rawString)) !== null) {
|
newString = rawString.replace(findRegex, (fencedMatch) => {
|
||||||
const fencedMatch = match[0];
|
let trimFencedMatch = filterString(fencedMatch, regexScript.trimStrings, { characterOverride });
|
||||||
const capturedMatch = match[1];
|
|
||||||
|
|
||||||
let trimCapturedMatch;
|
|
||||||
let trimFencedMatch;
|
|
||||||
if (capturedMatch) {
|
|
||||||
const tempTrimCapture = filterString(capturedMatch, regexScript.trimStrings, { characterOverride });
|
|
||||||
trimFencedMatch = fencedMatch.replaceAll(capturedMatch, tempTrimCapture);
|
|
||||||
trimCapturedMatch = tempTrimCapture;
|
|
||||||
} else {
|
|
||||||
trimFencedMatch = filterString(fencedMatch, regexScript.trimStrings, { characterOverride });
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Use substrings for replacement. But not necessary at this time.
|
|
||||||
// A substring is from match.index to match.index + match[0].length or fencedMatch.length
|
|
||||||
const subReplaceString = substituteRegexParams(
|
const subReplaceString = substituteRegexParams(
|
||||||
regexScript.replaceString,
|
regexScript.replaceString,
|
||||||
trimCapturedMatch ?? trimFencedMatch,
|
trimFencedMatch,
|
||||||
{
|
{
|
||||||
characterOverride,
|
characterOverride,
|
||||||
replaceStrategy: regexScript.replaceStrategy ?? regex_replace_strategy.REPLACE,
|
replaceStrategy: regexScript.replaceStrategy ?? regex_replace_strategy.REPLACE,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (!newString) {
|
|
||||||
newString = rawString.slice(0, match.index) + rawString.slice(match.index).replace(fencedMatch, subReplaceString);
|
|
||||||
} else {
|
|
||||||
newString = newString.slice(0, match.index) + newString.slice(match.index).replace(fencedMatch, subReplaceString);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the regex isn't global, break out of the loop
|
return subReplaceString;
|
||||||
if (!findRegex.flags.includes('g')) {
|
});
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return newString;
|
return newString;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filters anything to trim from the regex match
|
/**
|
||||||
|
* Filters anything to trim from the regex match
|
||||||
|
* @param {string} rawString The raw string to filter
|
||||||
|
* @param {string[]} trimStrings The strings to trim
|
||||||
|
* @param {RegexScriptParams} params The parameters to use for the regex filter
|
||||||
|
* @returns {string} The filtered string
|
||||||
|
*/
|
||||||
function filterString(rawString, trimStrings, { characterOverride } = {}) {
|
function filterString(rawString, trimStrings, { characterOverride } = {}) {
|
||||||
let finalString = rawString;
|
let finalString = rawString;
|
||||||
trimStrings.forEach((trimString) => {
|
trimStrings.forEach((trimString) => {
|
||||||
@ -133,7 +144,14 @@ function filterString(rawString, trimStrings, { characterOverride } = {}) {
|
|||||||
return finalString;
|
return finalString;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Substitutes regex-specific and normal parameters
|
/**
|
||||||
|
* Substitutes regex-specific and normal parameters
|
||||||
|
* @param {string} rawString
|
||||||
|
* @param {string} regexMatch
|
||||||
|
* @param {RegexSubstituteParams} params The parameters to use for the regex substitution
|
||||||
|
* @returns {string} The substituted string
|
||||||
|
* @typedef {{characterOverride?: string, replaceStrategy?: number}} RegexSubstituteParams The parameters to use for the regex substitution
|
||||||
|
*/
|
||||||
function substituteRegexParams(rawString, regexMatch, { characterOverride, replaceStrategy } = {}) {
|
function substituteRegexParams(rawString, regexMatch, { characterOverride, replaceStrategy } = {}) {
|
||||||
let finalString = rawString;
|
let finalString = rawString;
|
||||||
finalString = substituteParams(finalString, undefined, characterOverride);
|
finalString = substituteParams(finalString, undefined, characterOverride);
|
||||||
@ -188,8 +206,13 @@ function substituteRegexParams(rawString, regexMatch, { characterOverride, repla
|
|||||||
return finalString;
|
return finalString;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Splices common sentence symbols and whitespace from the beginning and end of a string
|
/**
|
||||||
// Using a for loop due to sequential ordering
|
* Splices common sentence symbols and whitespace from the beginning and end of a string.
|
||||||
|
* Using a for loop due to sequential ordering.
|
||||||
|
* @param {string} rawString The raw string to splice
|
||||||
|
* @param {boolean} isSuffix String is a suffix
|
||||||
|
* @returns {string} The spliced string
|
||||||
|
*/
|
||||||
function spliceSymbols(rawString, isSuffix) {
|
function spliceSymbols(rawString, isSuffix) {
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user