我需要搜索一个字符串并用从数据库中提取的值替换%FirstName%和%PolicyAmount%的所有出现。问题是FirstName的大小写不同。这阻止了我使用String.Replace()方法。我看过相关网页,上面写着

Regex.Replace(strInput, strToken, strReplaceWith, RegexOptions.IgnoreCase);

然而,由于某种原因,当我尝试将%PolicyAmount%替换为$0时,替换从未发生。我假设这与美元符号在正则表达式中是保留字符有关。

是否有另一种方法,我可以使用,不涉及消毒输入处理正则表达式特殊字符?


当前回答

下面是执行Regex替换的另一个选项,因为很多人似乎没有注意到匹配包含字符串中的位置:

    public static string ReplaceCaseInsensative( this string s, string oldValue, string newValue ) {
        var sb = new StringBuilder(s);
        int offset = oldValue.Length - newValue.Length;
        int matchNo = 0;
        foreach (Match match in Regex.Matches(s, Regex.Escape(oldValue), RegexOptions.IgnoreCase))
        {
            sb.Remove(match.Index - (offset * matchNo), match.Length).Insert(match.Index - (offset * matchNo), newValue);
            matchNo++;
        }
        return sb.ToString();
    }

其他回答

看起来像绳子。Replace应该有一个重载,接受StringComparison参数。因为它没有,你可以尝试这样做:

public static string ReplaceString(string str, string oldValue, string newValue, StringComparison comparison)
{
    StringBuilder sb = new StringBuilder();

    int previousIndex = 0;
    int index = str.IndexOf(oldValue, comparison);
    while (index != -1)
    {
        sb.Append(str.Substring(previousIndex, index - previousIndex));
        sb.Append(newValue);
        index += oldValue.Length;

        previousIndex = index;
        index = str.IndexOf(oldValue, index, comparison);
    }
    sb.Append(str.Substring(previousIndex));

    return sb.ToString();
}

从MSDN $0 - "替换组号number(十进制)匹配的最后一个子字符串。"

在。net正则表达式中,0组总是整个匹配。对于字面上的$,你需要

string value = Regex.Replace("%PolicyAmount%", "%PolicyAmount%", @"$$0", RegexOptions.IgnoreCase);

受到cfeduke答案的启发,我做了这个函数,它使用IndexOf来查找字符串中的旧值,然后用新值替换它。我在处理数百万行的SSIS脚本中使用了这个方法,regex方法要比这个慢得多。

public static string ReplaceCaseInsensitive(this string str, string oldValue, string newValue)
{
    int prevPos = 0;
    string retval = str;
    // find the first occurence of oldValue
    int pos = retval.IndexOf(oldValue, StringComparison.InvariantCultureIgnoreCase);

    while (pos > -1)
    {
        // remove oldValue from the string
        retval = retval.Remove(pos, oldValue.Length);

        // insert newValue in it's place
        retval = retval.Insert(pos, newValue);

        // check if oldValue is found further down
        prevPos = pos + newValue.Length;
        pos = retval.IndexOf(oldValue, prevPos, StringComparison.InvariantCultureIgnoreCase);
    }

    return retval;
}

正则表达式方法应该可以工作。但是,您还可以将数据库中的字符串小写,将您拥有的%variables%小写,然后从数据库中定位小写字符串中的位置和长度。记住,字符串中的位置不会因为小写而改变。

然后使用一个反向循环(它更容易,如果你不这样做,你将不得不保持一个运行的计数,后来的点移动到哪里)从你的非小写字符串从数据库中删除%变量%的位置和长度,并插入替换值。

一个类似C. Dragon的版本,但如果你只需要一个替换:

int n = myText.IndexOf(oldValue, System.StringComparison.InvariantCultureIgnoreCase);
if (n >= 0)
{
    myText = myText.Substring(0, n)
        + newValue
        + myText.Substring(n + oldValue.Length);
}