JavaScript replace regex produces two trailing commas for "a,b,c " string

4 days ago 9
ARTICLE AD BOX

Background

I'm working on processing a comma-separated username list (for an ACL whitelist optimization in my project) and need to normalize whitespace around commas, as well as trim leading/trailing whitespace from the string.

Code & Issue

I used this regex replacement to clean up the string:

const input = "a,b,c "; const result = input.replace(/\s*,\s*|^\s*|\s*$/g, ','); console.log(result); // Outputs "a,b,c,," (two trailing commas) "a,b,c ".replace(/\s*,\s*|^\s*|\s*$/g, ',') // outputs two tailing commas "c ".replace(/(\s*$)/g, ','); // outputs two tailing commas function checkByIndexOf(commaStr, target) { const wrappedStr = `,${commaStr},`; const wrappedTarget = `,${target},`; return wrappedStr.indexOf(wrappedTarget) !== -1; } /** * High-performance check: indexOf + boundary validation (supports spaces/dots/no special chars) * @param {string} commaStr - Comma-separated string (may contain spaces, dots) * @param {string} target - Target item (may contain dots) * @returns {boolean} Whether the target is included as a standalone item */ function checkByIndexOfWithBoundary(commaStr, target) { const targetLen = target.length; const strLen = commaStr.length; let pos = commaStr.indexOf(target); // Return false immediately if target is not found if (pos === -1) return false; // Loop through all matching positions (avoid missing matches, e.g., duplicate items) while (pos !== -1) { // Check front boundary: start of string / previous char is comma/space const prevOk = pos === 0 || /[, ]/.test(commaStr[pos - 1]); // Check rear boundary: end of string / next char is comma/space const nextOk = (pos + targetLen) === strLen || /[, ]/.test(commaStr[pos + targetLen]); // Return true if both boundaries match (target is a standalone item) if (prevOk && nextOk) return true; // Find next matching position (avoid re-matching the same position) pos = commaStr.indexOf(target, pos + 1); } // All matching positions fail boundary validation return false; } /** * Check if a comma-separated string contains a specified standalone item * @param {string} commaStr - Original comma-separated string (e.g. "apple,banana,orange") * @param {string} target - Target string to check (e.g. "banana") * @returns {boolean} Whether the target item is included as a standalone entry */ function checkCommaStrInclude(commaStr, target) { // Escape regex special characters in the target string (e.g. . * + ? $ ^ [ ] ( ) { } | \ /) const escapedTarget = target.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // Build regex pattern: match (start of string | comma) + escaped target + (comma | end of string) // Ensures the target is a standalone item (avoids partial matches) const regex = new RegExp(`(^|,)${escapedTarget}(,|$)`, 'g'); // Test if the regex matches the comma-separated string return regex.test(commaStr); }

Problem

The expected output is "a,b,c" (no trailing commas, normalized commas), but the current code produces two trailing commas instead. I don't understand why the regex is matching in a way that adds extra commas at the end.

What I've Tried

I checked the regex pattern /\s*,\s*|^\s*|\s*$/g and understand it's meant to match: Whitespace around commas (\s*,\s*) Leading whitespace (^\s*) Trailing whitespace (\s*$) I replaced all matches with ,, but the trailing space in the input seems to trigger two replacements that result in double commas.

Question

Why does this regex produce two trailing commas for the input "a,b,c "? How can I adjust the regex (or use a better approach) to get the clean output "a,b,c" for comma-separated strings with extra whitespace/commas?
Read Entire Article