Используйте string.Replace, чтобы соответствовать целым словам - PullRequest
2 голосов
/ 22 декабря 2011

Я использую NET 2.0 и WinForms.

В настоящее время мне нужен код для замены строки другой в данном тексте, но в тексте он должен искать только целые слова. Я имею в виду:

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

Он должен заменить только первый экземпляр COUNTER на COUNT, потому что это целое слово. Однако, похоже, string.Replace не учитывает всего слова.

Пожалуйста, не рекомендуйте регулярное выражение. Я уже попробовал это, и это слишком медленно для моих нужд. Мне нужно что-то очень быстрое и эффективное. Как я мог сделать это?

Ответы [ 3 ]

7 голосов
/ 22 декабря 2011
string input = @"COUNTER = $40
CLOCK_COUNTER = $60";

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

\b отмечает границы слов.


Единственной альтернативой Regex является разработка собственного алгоритма! Найдите слово «СЧЕТЧИК» и проверьте, не является ли предыдущий и следующий символ символом слова.


EDIT

Вот мое решение в качестве метода расширения:

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;
    }
}
0 голосов
/ 22 декабря 2011

Я думаю, что вы не можете добиться замены этой строки быстрее (я говорю о времени разработки), чем с помощью 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

0 голосов
/ 22 декабря 2011

Небольшой обходной путь:

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

Основная идея, что вы должны пометить слово, которое вы собираетесь заменить, какими-то символами, которые другие слова, которые вы не хотите заменить, не имеют

...