@@ -2202,7 +2202,8 @@ func replace*(s, sub: string, by = ""): string {.rtl,
22022202 # # * `replace func<#replace,string,char,char>`_ for replacing
22032203 # # single characters
22042204 # # * `replaceWord func<#replaceWord,string,string,string>`_
2205- # # * `multiReplace func<#multiReplace,string,varargs[]>`_
2205+ # # * `multiReplace func<#multiReplace,string,varargs[]>`_ for substrings
2206+ # # * `multiReplace func<#multiReplace,openArray[char],varargs[]>`_ for single characters
22062207 result = " "
22072208 let subLen = sub.len
22082209 if subLen == 0 :
@@ -2245,7 +2246,8 @@ func replace*(s: string, sub, by: char): string {.rtl,
22452246 # # See also:
22462247 # # * `find func<#find,string,char,Natural,int>`_
22472248 # # * `replaceWord func<#replaceWord,string,string,string>`_
2248- # # * `multiReplace func<#multiReplace,string,varargs[]>`_
2249+ # # * `multiReplace func<#multiReplace,string,varargs[]>`_ for substrings
2250+ # # * `multiReplace func<#multiReplace,openArray[char],varargs[]>`_ for single characters
22492251 result = newString (s.len)
22502252 var i = 0
22512253 while i < s.len:
@@ -2330,7 +2332,39 @@ func multiReplace*(s: string, replacements: varargs[(string, string)]): string =
23302332 add result , s[i]
23312333 inc (i)
23322334
2333-
2335+ func multiReplace * (s: openArray [char ]; replacements: varargs [(set [char ], char )]): string {.noinit .} =
2336+ # # Performs multiple character replacements in a single pass through the input.
2337+ # #
2338+ # # `multiReplace` scans the input `s` from left to right and replaces
2339+ # # characters based on character sets, applying the first matching replacement
2340+ # # at each position. Useful for sanitizing or transforming strings with
2341+ # # predefined character mappings.
2342+ # #
2343+ # # The order of the `replacements` matters:
2344+ # # - First matching replacement is applied
2345+ # # - Subsequent replacements are not considered for the same character
2346+ # #
2347+ # # See also:
2348+ # # - `multiReplace(s: string; replacements: varargs[(string, string)]) <#multiReplace,string,varargs[]>`_,
2349+ runnableExamples:
2350+ const WinSanitationRules = [
2351+ ({'\0 ' .. '\31 ' }, ' ' ),
2352+ ({'"' }, '\' ' ),
2353+ ({'/' , '\\ ' , ':' , '|' }, '-' ),
2354+ ({'*' , '?' , '<' , '>' }, '_' ),
2355+ ]
2356+ # Sanitize a filename with Windows-incompatible characters
2357+ const file = " a/file:with?invalid*chars.txt"
2358+ doAssert file.multiReplace (WinSanitationRules ) == " a-file-with_invalid_chars.txt"
2359+ {.cast (noSideEffect).}:
2360+ result = newStringUninit (s.len)
2361+ for i in 0 ..< s.len:
2362+ var nextChar = s[i]
2363+ for subs, by in replacements.items:
2364+ if nextChar in subs:
2365+ nextChar = by
2366+ break
2367+ result [i] = nextChar
23342368
23352369func insertSep * (s: string , sep = '_' , digits = 3 ): string {.rtl ,
23362370 extern : " nsuInsertSep" .} =
0 commit comments