From 04aac03d6e224f3f768cd5461757df19f437f680 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 15 Jun 2017 14:21:30 +0000 Subject: [PATCH] Fixed global matching for simple strings in 'Find / Replace' operation. Closes #25. --- src/core/Utils.js | 16 ++++++++++++++++ src/core/config/OperationConfig.js | 2 +- src/core/operations/StrUtils.js | 12 +++++++----- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/core/Utils.js b/src/core/Utils.js index 9b0d2a30..9011880f 100755 --- a/src/core/Utils.js +++ b/src/core/Utils.js @@ -259,6 +259,22 @@ const Utils = { }, + /** + * Escape a string containing regex control characters so that it can be safely + * used in a regex without causing unintended behaviours. + * + * @param {string} str + * @returns {string} + * + * @example + * // returns "\[example\]" + * Utils.escapeRegex("[example]"); + */ + escapeRegex: function(str) { + return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); + }, + + /** * Expand an alphabet range string into a list of the characters in that range. * diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 585bf600..0397b50e 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -1919,7 +1919,7 @@ const OperationConfig = { args: [] }, "Find / Replace": { - description: "Replaces all occurrences of the first string with the second.

The three match options are only relevant to regex search strings.", + description: "Replaces all occurrences of the first string with the second.

Includes support for regular expressions (regex), simple strings and extended strings (which support \\n, \\r, \\t, \\b, \\f and escaped hex bytes using \\x notation, e.g. \\x00 for a null byte).", run: StrUtils.runFindReplace, manualBake: true, inputType: "string", diff --git a/src/core/operations/StrUtils.js b/src/core/operations/StrUtils.js index 78a0e838..093de39b 100755 --- a/src/core/operations/StrUtils.js +++ b/src/core/operations/StrUtils.js @@ -227,14 +227,16 @@ const StrUtils = { if (type === "Regex") { find = new RegExp(find, modifiers); - } else if (type.indexOf("Extended") === 0) { + return input.replace(find, replace); + } + + if (type.indexOf("Extended") === 0) { find = Utils.parseEscapedChars(find); } - return input.replace(find, replace, modifiers); - // Non-standard addition of flags in the third argument. This will work in Firefox but - // probably nowhere else. The purpose is to allow global matching when the `find` parameter - // is just a string. + find = new RegExp(Utils.escapeRegex(find), modifiers); + + return input.replace(find, replace); },