Skip to content

Proposal: Add an overload of string.Replace that accepts CultureInfo and CompareOption (and additionally Span-based overloads) #29111

Closed
@Gnbrkm41

Description

@Gnbrkm41

Rationale and Usage

Related issue: https://github.com/dotnet/corefx/issues/36251, dotnet/vblang#390

Currently there is no way to treat Japanese characters that only differ in its width (e.g. アイウエオ, アイウエオ) when replacing characters in a string. The closest existing API out-of-the-box is string.Replace(String, String, Boolean, CultureInfo) method, however ignoring Kana type / Width cannot be done through CultureInfo and is usually specified through CompareOption enum. (e.g. string.Compare(String, String, CultureInfo, CompareOptions)). From what I can see, this is somewhat tedious to implement on one's own as there is no overload of IndexOf or similar method that enables one to ignore the width/kana type.

Therefore, I suggest that we add an overload of string.Replace that accepts string, string, CultureInfo, CompareOptions to allow people to have fine-grained control over the replacement.

Proposed API

namespace System
{
    public class String
    {
        // On top of the existing methods...
        public string Replace(string oldValue, string? newValue, CultureInfo? culture, CompareOptions options);
    }
}

(The order of the CultureInfo/CompareOptions is the same as string.Compare(String, String, Boolean, CultureInfo), just in case if someone's wondering why it's not the other way around)

Details

Currently, Replace(String, String, Boolean, CultureInfo) method is implemented as follows, calling the internal method ReplaceCore that accepts a CompareOptions:

public string Replace(string oldValue, string? newValue, bool ignoreCase, CultureInfo? culture)
{
    return ReplaceCore(oldValue, newValue, culture, ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None);
}

Instead of using ternary to pass only the IgnoreCase option, we can validate the option passed from the caller (e.g. if any flags not defined in the enum is set, Ordinal is set with others...) then call the ReplaceCore method as usual to perform the operation.

Open Questions

  • Upon a quick glance over the code, it seems that the ReplaceCore calls some methods (e.g. CompareInfo.IndexOf) which call Windows native functions to perform certain operations. Is the method available in other platforms as well?
  • Should this be provided for StringBuilder as well? it appears that the type has some similar methods, albeit with much less overloads. Maybe we could open a separate issue regarding this.

Span-based overloads are discussed below.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions