使用string.Replace匹配整个单词

时间:2011-12-22 14:30:51

标签: c# string replace .net-2.0

我正在使用NET 2.0和WinForms。

目前,我需要一个代码来替换给定文本中的另一个字符串,但在文本中它应该只查找整个单词。我的意思是:

string name = @"COUNTER = $40
CLOCK_COUNTER = $60";
name = name.Replace("COUNTER", "COUNT");

它应该只用COUNTER替换COUNT的第一个实例,因为这是整个单词。但是,似乎string.Replace并未考虑整个词。

请不要推荐正则表达式。我已经尝试过了,这对我的需求来说太慢了。我需要一些非常快速和有效的东西。我怎么能做到这一点?

3 个答案:

答案 0 :(得分:7)

string input = @"COUNTER = $40
CLOCK_COUNTER = $60";

string name = Regex.Replace(input, @"\bCOUNTER\b", "COUNT");

\b标记了单​​词边界。


Regex的唯一替代方法是开发自己的算法!搜索“COUNTER”并测试前一个和后一个字符是否为单词字符。


修改

以下是我作为扩展方法的解决方案:

public static class ReplaceWordNoRegex
{
    private static bool IsWordChar(char c)
    {
        return Char.IsLetterOrDigit(c) || c == '_';
    }

    public static string ReplaceFullWords(this string s, string oldWord, string newWord)
    {
        if (s == null) {
            return null;
        }
        int startIndex = 0;
        while (true) {
            int position = s.IndexOf(oldWord, startIndex);
            if (position == -1) {
                return s;
            }
            int indexAfter = position + oldWord.Length;
            if ((position == 0 || !IsWordChar(s[position - 1])) && (indexAfter == s.Length || !IsWordChar(s[indexAfter]))) {
                s = s.Substring(0, position) + newWord + s.Substring(indexAfter);
                startIndex = position + newWord.Length;
            } else {
                startIndex = position + oldWord.Length;
            }
        }
    }
}

编辑#2: 这是StringBuilder的解决方案。

public static string ReplaceFullWords(this string s, string oldWord, string newWord)
{
    if (s == null) {
        return null;
    }
    int startIndex = 0; // Where we start to search in s.
    int copyPos = 0; // Where we start to copy from s to sb.
    var sb = new StringBuilder();
    while (true) {
        int position = s.IndexOf(oldWord, startIndex);
        if (position == -1) {
            if (copyPos == 0) {
                return s;
            }
            if (s.Length > copyPos) { // Copy last chunk.
                sb.Append(s.Substring(copyPos, s.Length - copyPos));
            }
            return sb.ToString();
        }
        int indexAfter = position + oldWord.Length;
        if ((position == 0 || !IsWordChar(s[position - 1])) && (indexAfter == s.Length || !IsWordChar(s[indexAfter]))) {
            sb.Append(s.Substring(copyPos, position - copyPos)).Append(newWord);
            copyPos = position + oldWord.Length;
        }
        startIndex = position + oldWord.Length;
    }
}

答案 1 :(得分:0)

小解决方法:

string name = @"COUNTER = $40
CLOCK_COUNTER = $60";
name=" "+name;
name = name.Replace(" COUNTER ", " COUNT ");

主要想法是你必须用某种符号来标记你要替换的单词,而你不想替换的其他单词不是

答案 2 :(得分:0)

我认为你不能比RegExp更快地实现那个字符串替换(我说的是开发时间)

        string input = @"COUNTER = $40 CLOCK_COUNTER = $60";
        string pattern = @"\bCOUNTER\b";
        string replacement = "COUNT";
        var regex = new Regex(pattern,RegexOptions.Compiled);
        string result = regex.Replace(input, replacement);

如果您打算重用

,添加RegexOptions.Compiled可以加快速度

------------------- UPDATE --------------------------- -

我记得这篇文章可能符合您的需求:

http://www.codeproject.com/KB/string/fastestcscaseinsstringrep.aspx