简体   繁体   English

使用string.Replace匹配整个单词

[英]Use string.Replace to match whole words

I'm using NET 2.0 and WinForms. 我正在使用NET 2.0和WinForms。

Currently, I need a code to replace a string with another one in a given text, but in the text it should only look for whole words. 当前,我需要一个代码来在给定的文本中用另一个字符串替换一个字符串,但是在文本中它应该只查找整个单词。 What I mean is: 我的意思是:

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

It should only replace the first instance of COUNTER with COUNT , because that's whole word. 它仅应将COUNTER的第一个实例替换为COUNT ,因为这是整个单词。 However, it seems string.Replace does not take whole word into consideration. 但是,它似乎是string.Replace并没有考虑整个单词。

Please don't recommend regex. 请不要推荐正则表达式。 I have already tried it, and it's too slow for my needs. 我已经尝试过了,它太慢了,无法满足我的需求。 I need something very fast and efficient. 我需要快速高效的工具。 How could I accomplish this? 我怎么能做到这一点?

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

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

\\b marks word boundries. \\b标记单词边界。


The only alternative to Regex is to develop your own algorithm! Regex的唯一替代方法是开发自己的算法! Search for "COUNTER" and test the previous and following character for not being a word character. 搜索“ COUNTER”,并测试前一个和后一个字符是否不是单词字符。


EDIT : 编辑

Here is my solution as extension method: 这是我作为扩展方法的解决方案:

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;
            }
        }
    }
}

EDIT #2: And here is a solution with StringBuilder. 编辑#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;
    }
}

Small workaround: 小解决方法:

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

Main idea that you have to mark the word you're going to replace with some sort of symbols that other words that you do not want to replace have not 主要思想是,您必须用某种符号标记要替换的单词,而这些符号是您不想替换的其他单词没有的

I think you cannot achieve that string replace any faster (I'm talking about developing time) than by RegExp 我认为您无法实现比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);

Adding RegexOptions.Compiled makes it faster if you intend to reuse 如果要重用,则添加RegexOptions.Compiled可以使其速度更快

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

i remembered about this article that may fit your needs: 我记得这篇文章可能符合您的需求:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM