mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Regex: Add trimStrings option
Sometimes the matched regex string needs to be pruned before replacement. Add a method for the user to provide strings which globally trims a regex match before any replacement is done. Example without trim: input - <Manami's thoughts: This is a thought> regex - /<([^>]*)>/g output - <Manami's thoughts: Manami's thoughts: This is a thought> With trim: input - <Manami's thoughts: This is a thought> regex - /<([^>]*)>/g trim - ["{{char}}'s thoughts: "] output - <Manami's thoughts: This is a thought> Signed-off-by: kingbri <bdashore3@proton.me>
This commit is contained in:
@@ -8,7 +8,7 @@
|
|||||||
<small data-i18n="Script Name">Script Name</small>
|
<small data-i18n="Script Name">Script Name</small>
|
||||||
</label>
|
</label>
|
||||||
<div>
|
<div>
|
||||||
<input class="regex_script_name text_pole textarea_compact" type="text" maxlength="100" />
|
<input class="regex_script_name text_pole textarea_compact" type="text" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex1">
|
<div class="flex1">
|
||||||
@@ -16,19 +16,30 @@
|
|||||||
<small data-i18n="Find Regex">Find Regex</small>
|
<small data-i18n="Find Regex">Find Regex</small>
|
||||||
</label>
|
</label>
|
||||||
<div>
|
<div>
|
||||||
<input class="find_regex text_pole textarea_compact" type="text" maxlength="100" />
|
<input class="find_regex text_pole textarea_compact" type="text" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex1">
|
<div class="flex1">
|
||||||
<label for="replace_string" class="title_restorable">
|
<label for="regex_replace_string" class="title_restorable">
|
||||||
<small data-i18n="Replace With">Replace With</small>
|
<small data-i18n="Replace With">Replace With</small>
|
||||||
</label>
|
</label>
|
||||||
<div>
|
<div>
|
||||||
<textarea
|
<textarea
|
||||||
class="regex_replace_string text_pole wide100p textarea_compact"
|
class="regex_replace_string text_pole wide100p textarea_compact"
|
||||||
placeholder="Use {{match}} to include the matched text from Find Regex"
|
placeholder="Use {{match}} to include the matched text from the Find Regex"
|
||||||
rows="2"
|
rows="2"
|
||||||
maxlength="100"
|
></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex1">
|
||||||
|
<label for="regex_trim_strings" class="title_restorable">
|
||||||
|
<small data-i18n="Trim Out">Trim Out</small>
|
||||||
|
</label>
|
||||||
|
<div>
|
||||||
|
<textarea
|
||||||
|
class="regex_trim_strings text_pole wide100p textarea_compact"
|
||||||
|
placeholder="Globally trims any unwanted parts from a regex match before replacement. Separate each element by an enter."
|
||||||
|
rows="3"
|
||||||
></textarea>
|
></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -30,9 +30,19 @@ function runRegexScript(regexScript, rawString) {
|
|||||||
const fencedMatch = match[0];
|
const fencedMatch = match[0];
|
||||||
const capturedMatch = match[1];
|
const capturedMatch = match[1];
|
||||||
|
|
||||||
|
let trimCapturedMatch;
|
||||||
|
let trimFencedMatch;
|
||||||
|
if (capturedMatch) {
|
||||||
|
const tempTrimCapture = filterString(capturedMatch, regexScript.trimStrings);
|
||||||
|
trimFencedMatch = fencedMatch.replaceAll(capturedMatch, tempTrimCapture);
|
||||||
|
trimCapturedMatch = tempTrimCapture;
|
||||||
|
} else {
|
||||||
|
trimFencedMatch = filterString(fencedMatch, regexScript.trimStrings);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Use substrings for replacement. But not necessary at this time.
|
// 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
|
// A substring is from match.index to match.index + match[0].length or fencedMatch.length
|
||||||
const subReplaceString = substituteRegexParams(regexScript.replaceString, { regexMatch: capturedMatch ?? fencedMatch });
|
const subReplaceString = substituteRegexParams(regexScript.replaceString, trimCapturedMatch ?? trimFencedMatch);
|
||||||
if (!newString) {
|
if (!newString) {
|
||||||
newString = rawString.replace(fencedMatch, subReplaceString);
|
newString = rawString.replace(fencedMatch, subReplaceString);
|
||||||
} else {
|
} else {
|
||||||
@@ -48,8 +58,19 @@ function runRegexScript(regexScript, rawString) {
|
|||||||
return newString;
|
return newString;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Substitutes parameters
|
// Filters anything to trim from the regex match
|
||||||
function substituteRegexParams(rawString, { regexMatch }) {
|
function filterString(rawString, trimStrings) {
|
||||||
|
let finalString = rawString;
|
||||||
|
trimStrings.forEach((trimString) => {
|
||||||
|
const subTrimString = substituteParams(trimString);
|
||||||
|
finalString = finalString.replaceAll(subTrimString, "");
|
||||||
|
});
|
||||||
|
|
||||||
|
return finalString;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Substitutes regex-specific and normal parameters
|
||||||
|
function substituteRegexParams(rawString, regexMatch) {
|
||||||
let finalString = rawString;
|
let finalString = rawString;
|
||||||
finalString = finalString.replace("{{match}}", regexMatch);
|
finalString = finalString.replace("{{match}}", regexMatch);
|
||||||
finalString = substituteParams(finalString);
|
finalString = substituteParams(finalString);
|
||||||
|
@@ -87,9 +87,10 @@ async function onRegexEditorOpenClick(existingId) {
|
|||||||
editorHtml.find(`.regex_script_name`).val(existingScript.scriptName);
|
editorHtml.find(`.regex_script_name`).val(existingScript.scriptName);
|
||||||
editorHtml.find(`.find_regex`).val(existingScript.findRegex);
|
editorHtml.find(`.find_regex`).val(existingScript.findRegex);
|
||||||
editorHtml.find(`.regex_replace_string`).val(existingScript.replaceString);
|
editorHtml.find(`.regex_replace_string`).val(existingScript.replaceString);
|
||||||
|
editorHtml.find(`.regex_trim_strings`).val(existingScript.trimStrings?.join("\n") || []);
|
||||||
editorHtml
|
editorHtml
|
||||||
.find(`input[name="disabled"]`)
|
.find(`input[name="disabled"]`)
|
||||||
.prop("checked", existingScript.disabled);
|
.prop("checked", existingScript.disabled ?? false);
|
||||||
editorHtml
|
editorHtml
|
||||||
.find(`input[name="run_on_edit"]`)
|
.find(`input[name="run_on_edit"]`)
|
||||||
.prop("checked", existingScript.runOnEdit);
|
.prop("checked", existingScript.runOnEdit);
|
||||||
@@ -116,13 +117,14 @@ async function onRegexEditorOpenClick(existingId) {
|
|||||||
scriptName: editorHtml.find(".regex_script_name").val(),
|
scriptName: editorHtml.find(".regex_script_name").val(),
|
||||||
findRegex: editorHtml.find(".find_regex").val(),
|
findRegex: editorHtml.find(".find_regex").val(),
|
||||||
replaceString: editorHtml.find(".regex_replace_string").val(),
|
replaceString: editorHtml.find(".regex_replace_string").val(),
|
||||||
|
trimStrings: editorHtml.find(".regex_trim_strings").val().split("\n").filter((e) => e.length !== 0) || [],
|
||||||
placement:
|
placement:
|
||||||
editorHtml
|
editorHtml
|
||||||
.find(`input[name="replace_position"]`)
|
.find(`input[name="replace_position"]`)
|
||||||
.filter(":checked")
|
.filter(":checked")
|
||||||
.map(function() { return parseInt($(this).val()) })
|
.map(function() { return parseInt($(this).val()) })
|
||||||
.get()
|
.get()
|
||||||
.filter((e) => e !== NaN) ?? [],
|
.filter((e) => e !== NaN) || [],
|
||||||
disabled:
|
disabled:
|
||||||
editorHtml
|
editorHtml
|
||||||
.find(`input[name="disabled"]`)
|
.find(`input[name="disabled"]`)
|
||||||
|
Reference in New Issue
Block a user