C# 将直接引号替换为印刷字体的引号:“;“我的文本”;至„;我的文本“;

C# 将直接引号替换为印刷字体的引号:“;“我的文本”;至„;我的文本“;,c#,.net,string,C#,.net,String,我想在任何地方自动将“我的文本”更改为“我的文本”,因为这是用德语书写的正确方式。引号可以在文本中的任何地方 有没有一种简单的方法来实现这一点? 解决方案应该检查第一个字符,最后一个字符,比如“this”,或者(检查“this”) 我目前的做法是: public static string FixGermanQuotationMarks(string input) { string output = input; if (output[0] == '"') output = "„

我想在任何地方自动将“我的文本”更改为“我的文本”,因为这是用德语书写的正确方式。引号可以在文本中的任何地方

有没有一种简单的方法来实现这一点?

解决方案应该检查第一个字符,最后一个字符,比如“this”,或者(检查“this”)

我目前的做法是:

public static string FixGermanQuotationMarks(string input)
{
    string output = input;
    if (output[0] == '"') output = "„" + output.Substring(1, output.Length - 1);

    if (output.EndsWith("\"")) output = output.Substring(0, output.Length-1) + '“';

    output = output
        .Replace(" \"", " „")
        .Replace("(\"", "(„")
        .Replace("<\"", "<„")

        .Replace("\".", "“.")
        .Replace("\")", "“)")
        .Replace("\"<", "“<")
        .Replace("\" ", "“ ");

    return output;
}
公共静态字符串FixGermanQuotationMarks(字符串输入)
{
字符串输出=输入;
如果(输出[0]==””)输出=“”+输出子字符串(1,输出长度-1);
如果(output.EndsWith(“\”)output=output.Substring(0,output.Length-1)+'”;
输出=输出
.替换(“\”,“\”)
.替换(“(\”,“(”)

.Replace(“您可以在string类上编写一个扩展方法来执行此操作:

编辑基于良好的反馈,在扩展方法中使用了
StringBuilder
,以获得更好的性能

public static class StringExtensions
{
    /// <summary>
    /// Replaces every odd straight quote with '„' and every even straight quote with '“'.
    /// </summary>
    /// <param name="source">The string acting as the source for replacements.</param>
    /// <returns>A string with replacements made.</returns>
    public static string ReplaceStraightQuotes(this string source)
    {
        if (source == null) return null;

        var result = new StringBuilder(source);

        var lastIndex = source.IndexOf('"');
        int count = 0;

        while (lastIndex > -1)
        {
            char replaceQuote = (count++ % 2 == 0) ? '„' : '“';
            result.Replace('"', replaceQuote, lastIndex, 1);
            lastIndex = source.IndexOf('"', lastIndex + 1);
        }

        return result.ToString();
    }
}
输出:

result=“他说:”你好,你看起来很可爱。”

result.ReplaceStraightQuotes()= 他说,“你好,你看起来很可爱。”


您可以在string类上编写扩展方法来执行此操作:

编辑基于良好的反馈,在扩展方法中使用了
StringBuilder
,以获得更好的性能

public static class StringExtensions
{
    /// <summary>
    /// Replaces every odd straight quote with '„' and every even straight quote with '“'.
    /// </summary>
    /// <param name="source">The string acting as the source for replacements.</param>
    /// <returns>A string with replacements made.</returns>
    public static string ReplaceStraightQuotes(this string source)
    {
        if (source == null) return null;

        var result = new StringBuilder(source);

        var lastIndex = source.IndexOf('"');
        int count = 0;

        while (lastIndex > -1)
        {
            char replaceQuote = (count++ % 2 == 0) ? '„' : '“';
            result.Replace('"', replaceQuote, lastIndex, 1);
            lastIndex = source.IndexOf('"', lastIndex + 1);
        }

        return result.ToString();
    }
}
输出:

result=“他说:”你好,你看起来很可爱。”

result.ReplaceStraightQuotes()= 他说,“你好,你看起来很可爱。”


我不知道这是否正是您想要的,但以下是我将采用的正则表达式解决方案:

    public static string FixGermanQuotationMarks(string input)
    {
        var pattern = @"""([^""]*)""";
        return Regex.Replace(input, pattern, @"„$1“");
    }
它可能会与必须转义的引号混淆,因此只要想象一下,如果不是转义引号,实际的模式会更像这样:
“([^”]*)”
。好的,让我们来分析一下:

  • 这与您的期初“常规”报价相匹配

  • 这是为了捕获被引号包围的内容。如果您不知道这意味着什么,您将在一分钟内看到

  • [^”]
    这匹配所有非引号的内容(字母、数字、空格等)
    ^
    是创建正则表达式时的求反运算符,因此
    ^
    表示
    *除*
    以外的所有内容。

  • *
    这意味着您可以拥有零个或多个上一项,在本例中,上一项是除引号字符以外的任何字符。这是为了确保捕获引号之间的字母数量

  • 我们关闭了捕获组

  • 这与结束报价匹配

  • 现在,我所说的捕获组是什么意思?它只是意味着,在匹配的情况下,当替换原始文本中匹配的内容时,我们实际上可以重用部分匹配。在我们的情况下,我们感兴趣的是两个引号之间的内容,这就是我们捕获它的原因。我们可以参考我们拥有的内容通过使用
    $1
    捕获,它指的是第一个(在我们的例子中是唯一的)捕获组。然后,我们只需将捕获的文本放在德文引号之间,并使用生成的字符串替换整个匹配项。正如我之前提到的,当查看我发布的代码以查看如此多的引号时,可能会感到困惑,但必须使用它们转义字符串文字

    在此之后,您只需要像这样调用该方法:

    var input = @"""Chili Pasilla"" ist mein Lieblings-Chili.";
    var germanified = FixGermanQuotationMarks(input);
    

    希望这能澄清regex方法。

    我不知道这是否正是您想要的,但下面是我将采用的regex解决方案:

        public static string FixGermanQuotationMarks(string input)
        {
            var pattern = @"""([^""]*)""";
            return Regex.Replace(input, pattern, @"„$1“");
        }
    
    它可能会与必须转义的引号混淆,因此只要想象一下,如果不是转义引号,实际的模式会更像这样:
    “([^”]*)”
    。好的,让我们来分析一下:

    • 这与您的期初“常规”报价相匹配

    • 这是为了捕获被引号包围的内容。如果您不知道这意味着什么,您将在一分钟内看到

    • [^”]
      这匹配所有非引号的内容(字母、数字、空格等)
      ^
      是创建正则表达式时的求反运算符,因此
      ^
      表示
      *除*
      以外的所有内容。

    • *
      这意味着您可以拥有零个或多个上一项,在本例中,上一项是除引号字符以外的任何字符。这是为了确保捕获引号之间的字母数量

    • 我们关闭了捕获组

    • 这与结束报价匹配

    现在,我所说的捕获组是什么意思?它只是意味着,在匹配的情况下,当替换原始文本中匹配的内容时,我们实际上可以重用部分匹配。在我们的情况下,我们感兴趣的是两个引号之间的内容,这就是我们捕获它的原因。我们可以参考我们拥有的内容通过使用
    $1
    捕获,它指的是第一个(在我们的例子中是唯一的)捕获组。然后,我们只需将捕获的文本放在德文引号之间,并使用生成的字符串替换整个匹配项。正如我之前提到的,当查看我发布的代码以查看如此多的引号时,可能会感到困惑,但必须使用它们转义字符串文字

    在此之后,您只需要像这样调用该方法:

    var input = @"""Chili Pasilla"" ist mein Lieblings-Chili.";
    var germanified = FixGermanQuotationMarks(input);
    

    希望这能澄清正则表达式的方法。

    我对正则表达式不是很坚定,但我希望有办法解决它。到目前为止,你有没有尝试过什么?如果有,你能和我们分享一下吗?你说的“自动无处不在”是什么意思在一个文本文件中?在一个应用程序中?在任何地方写的每一段文本中?都没有源代码