繁体   English   中英

使用string.Replace匹配整个单词

[英]Use string.Replace to match whole words

我正在使用NET 2.0和WinForms。

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

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

它仅应将COUNTER的第一个实例替换为COUNT ,因为这是整个单词。 但是,它似乎是string.Replace并没有考虑整个单词。

请不要推荐正则表达式。 我已经尝试过了,它太慢了,无法满足我的需求。 我需要快速高效的工具。 我怎么能做到这一点?

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

小解决方法:

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

主要思想是,您必须用某种符号标记要替换的单词,而这些符号是您不想替换的其他单词没有的

我认为您无法实现比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

暂无
暂无

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

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