You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中普通引号转智能引号:正则表达式实现方案咨询

智能引号替换方案:正则实现与效率对比

一、正则表达式实现方案

根据你提供的转换规则(仅替换短语/句子开头/结尾的引号,单词中间的引号保留),可以分两步用正则完成替换,逻辑和原循环代码一致:

C# 代码实现

using System.Text.RegularExpressions;

public string ConvertToSmartQuotes(string richText)
{
    // 第一步:替换开头的左智能引号
    string leftReplaced = Regex.Replace(richText, @"(^|\s)(\p{P}*)(['"])", m => 
    {
        // 保留前缀(空格+标点),替换引号为左智能引号
        string prefix = m.Groups[1].Value + m.Groups[2].Value;
        char originalQuote = m.Groups[3].Value[0];
        char smartQuote = originalQuote == '\'' ? '‘' : '“';
        return prefix + smartQuote;
    });

    // 第二步:替换结尾的右智能引号
    string result = Regex.Replace(leftReplaced, @"(['"])(\p{P}*)(\s|$)", m => 
    {
        // 替换引号为右智能引号,保留后缀(标点+空格/结尾)
        char originalQuote = m.Groups[1].Value[0];
        char smartQuote = originalQuote == '\'' ? '’' : '”';
        string suffix = m.Groups[2].Value + m.Groups[3].Value;
        return smartQuote + suffix;
    });

    return result;
}

正则说明

  • 左引号匹配规则:(^|\s)(\p{P}*)(['"])
    匹配字符串开头或空格后的任意数量标点,再匹配原引号,确保处于“短语开头序列”中的引号被替换为左智能引号
  • 右引号匹配规则:(['"])(\p{P}*)(\s|$)
    匹配原引号后接任意数量标点,再匹配空格或字符串结尾,确保处于“短语结尾序列”中的引号被替换为右智能引号

二、循环方案 vs 正则方案效率对比

循环方案优势

你的原循环方案(基于StringBuilder)在大文本量场景下效率更高,原因如下:

  1. 时间复杂度与常数因子:循环是线性遍历两次(O(n)时间复杂度),且StringBuilder的字符修改是直接内存操作,几乎无额外开销;正则表达式需要解析正则规则、执行匹配逻辑,即使是简单正则,常数因子也远高于循环。
  2. 内存开销:正则替换会生成多个中间字符串(每次Replace都会创建新字符串),而StringBuilder是在原内存缓冲区修改,内存占用更低。

正则方案优势

正则方案代码更简洁、可读性更强,维护成本低;如果你的游戏文本单段长度不超过几MB,性能差异几乎可以忽略,此时正则方案的开发效率优势更明显。

三、原循环代码优化建议

你的原循环代码已经很高效,可做微小优化:合并两次遍历为一次,提前记录所有需要替换的位置,减少遍历次数:

public string ConvertToSmartQuotesOptimized(string richText)
{
    StringBuilder builder = new StringBuilder(richText);
    int length = builder.Length;
    // 记录左引号替换位置
    bool isLeftQuoteState = true;
    // 记录右引号替换位置(先标记,最后统一替换)
    List<int> rightQuotePositions = new List<int>();
    char[] chars = builder.ToString().ToCharArray();

    // 第一次遍历:标记左引号和待替换的右引号位置
    for (int i = 0; i < length; i++)
    {
        if (isLeftQuoteState)
        {
            if (chars[i] == '\'')
            {
                chars[i] = '‘';
            }
            else if (chars[i] == '\"')
            {
                chars[i] = '“';
            }
            else if (!char.IsPunctuation(chars[i]))
            {
                isLeftQuoteState = false;
            }
        }
        else if (chars[i] == ' ')
        {
            isLeftQuoteState = true;
        }

        // 反向逻辑:标记右引号位置
        bool isRightQuoteState = false;
        int j = length - 1 - i;
        if (j >= 0)
        {
            if (j == length - 1)
            {
                isRightQuoteState = true;
            }
            else if (chars[j + 1] == ' ')
            {
                isRightQuoteState = true;
            }
            else if (char.IsPunctuation(chars[j + 1]))
            {
                // 继承前一个位置的状态
                isRightQuoteState = rightQuotePositions.Contains(j + 1);
            }

            if (isRightQuoteState && (chars[j] == '\'' || chars[j] == '\"'))
            {
                rightQuotePositions.Add(j);
            }
        }
    }

    // 替换右引号
    foreach (int pos in rightQuotePositions)
    {
        if (chars[pos] == '\'')
        {
            chars[pos] = '’';
        }
        else if (chars[pos] == '\"')
        {
            chars[pos] = '”';
        }
    }

    return new string(chars);
}

注:此优化仅适合极端大文本场景,普通场景下原循环代码的可读性更好,无需修改。

内容的提问来源于stack exchange,提问作者Riley Sampson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 20:54:50