代码之家  ›  专栏  ›  技术社区  ›  LiamB

.NET方法将字符串转换为句子大小写

  •  24
  • LiamB  · 技术社区  · 14 年前

    我正在寻找一个函数来将大写的文本字符串转换为sentencecase。我能找到的所有例子都将文本转换为标题库。

    一般意义上的句子格 描述资本化的方式 在句子中使用。句子 案例还描述了标准 英语句子的大写, 即句子的第一个字母 资本化,其余为 小写(除非要求 因特定原因资本化, 例如专有名词、首字母缩写等)。

    有人能给我指出SentienceCase脚本或函数的方向吗?

    8 回复  |  直到 6 年前
        1
  •  32
  •   LBushkin    14 年前

    .NET中没有内置的任何东西——但是,这是正则表达式处理实际可能工作良好的情况之一。我将首先将整个字符串转换为小写,然后作为第一个近似值,您可以使用regex查找 [a-z]\.\s+(.) 及使用 ToUpper() 将捕获的组转换为大写。这个 RegEx 类有一个重载 Replace() 接受 MatchEvaluator 委托,它允许您定义如何替换匹配的值。

    下面是一个代码示例:

    var sourcestring = "THIS IS A GROUP. OF CAPITALIZED. LETTERS.";
    // start by converting entire string to lower case
    var lowerCase = sourcestring.ToLower();
    // matches the first sentence of a string, as well as subsequent sentences
    var r = new Regex(@"(^[a-z])|\.\s+(.)", RegexOptions.ExplicitCapture);
    // MatchEvaluator delegate defines replacement of setence starts to uppercase
    var result = r.Replace(lowerCase, s => s.Value.ToUpper());
    
    // result is: "This is a group. Of uncapitalized. Letters."
    

    这可以通过多种不同的方式加以改进,以更好地匹配更广泛的各种句型(不仅仅是以字母+句点结尾的句型)。

        2
  •  7
  •   Ed B    14 年前

    这对我有用。

    /// <summary>
    /// Converts a string to sentence case.
    /// </summary>
    /// <param name="input">The string to convert.</param>
    /// <returns>A string</returns>
    public static string SentenceCase(string input)
    {
        if (input.Length < 1)
            return input;
    
        string sentence = input.ToLower();
        return sentence[0].ToString().ToUpper() +
           sentence.Substring(1);
    }
    
        3
  •  3
  •   StayOnTarget Charlie Flowers    6 年前

    有一个内置的 ToTitleCase() 未来将扩展到支持多种文化的功能。

    来自msdn的示例:

    using System;
    using System.Globalization;
    
    public class Example
    {
       public static void Main()
       {
          string[] values = { "a tale of two cities", "gROWL to the rescue",
                              "inside the US government", "sports and MLB baseball",
                              "The Return of Sherlock Holmes", "UNICEF and children"};
    
          TextInfo ti = CultureInfo.CurrentCulture.TextInfo;
          foreach (var value in values)
             Console.WriteLine("{0} --> {1}", value, ti.ToTitleCase(value));
       }
    }
    // The example displays the following output:
    //    a tale of two cities --> A Tale Of Two Cities
    //    gROWL to the rescue --> Growl To The Rescue
    //    inside the US government --> Inside The US Government
    //    sports and MLB baseball --> Sports And MLB Baseball
    //    The Return of Sherlock Holmes --> The Return Of Sherlock Holmes
    //    UNICEF and children --> UNICEF And Children
    

    虽然它通常是有用的,但它有一些重要的局限性:

    通常,标题大小写将单词的第一个字符转换为 大写,其余字符变为小写。然而,这 方法当前没有提供适当的大小写来转换 完全是大写的,例如缩写词。下表显示 方法呈现多个字符串的方式。

    …… ToTitleCase 方法提供任意套管行为 这在语言上不一定是正确的。从语言上讲 正确的解决方案需要附加规则,当前 算法有点简单和快速。我们保留 这个API将来会变慢。

    来源: http://msdn.microsoft.com/en-us/library/system.globalization.textinfo.totitlecase.aspx

        4
  •  2
  •   devio    14 年前

    我发现了这个 sample on MSDN .

        5
  •  2
  •   Jay    14 年前

    如果您的输入字符串不是一个句子,而是许多句子,这将成为一个非常困难的问题。

    正则表达式将被证明是一个非常宝贵的工具,但是(1)你必须非常了解它们才能有效,(2)它们可能不能完全靠自己来完成这项工作。

    考虑这个句子

    “谁在1号,”史密斯先生——他没有笑——回答说。

    这个句子不是以字母开头的,它有一个数字、各种标点、一个适当的名字和一个 . 在中间。

    复杂程度很高,这是一句话。

    在使用regex时,最重要的事情之一就是“了解你的数据”。如果你知道你将要处理的句子类型的宽度,你的任务将更易于管理。

    在任何情况下,在您对结果满意之前,您都必须玩弄您的实现。我建议用一些示例输入编写一些自动化测试——在您进行实现时,您可以定期运行这些测试,以查看您接近的位置以及您仍然缺少标记的位置。

        6
  •  2
  •   Matthew M.    10 年前

    如果您想将包含除句点之外的标点符号的字符串作为大小写的句子:

    string input = "THIS IS YELLING! WHY ARE WE YELLING? BECAUSE WE CAN. THAT IS ALL.";
    var sentenceRegex = new Regex(@"(^[a-z])|[?!.:,;]\s+(.)", RegexOptions.ExplicitCapture);
    input = sentenceRegex.Replace(input.ToLower(), s => s.Value.ToUpper());
    
        7
  •  1
  •   CrazyTim    13 年前

    这就是我使用的(vb.net)。它工作在 情况,包括:

    • 多句话
    • 以空格开头和结尾的句子
    • 以a-z以外的字符开头的句子。例如,它的作用是:“如果你想要100美元,那就问我吧。”

      <Extension()>
      Public Function ToSentanceCase(ByVal s As String) As String
          ' Written by Jason. Inspired from: http://www.access-programmers.co.uk/forums/showthread.php?t=147680
      
          Dim SplitSentence() As String = s.Split(".")
      
          For i = 0 To SplitSentence.Count - 1
              Dim st = SplitSentence(i)
      
              If st.Trim = "" Or st.Trim.Count = 1 Then Continue For ' ignore empty sentences or sentences with only 1 character.
      
              ' skip past characters that are not A-Z, 0-9 (ASCII) at start of sentence.
              Dim y As Integer = 1
              Do Until y > st.Count
                  If (Asc(Mid(st, y, 1)) >= 65 And Asc(Mid(st, y, 1)) <= 90) Or _
                        (Asc(Mid(st, y, 1)) >= 97 And Asc(Mid(st, y, 1)) <= 122) Or _
                       (Asc(Mid(st, y, 1)) >= 48 And Asc(Mid(st, y, 1)) <= 57) Then
                      GoTo Process
                  Else
                      Dim w = Asc(Mid(st, y, 1))
                      y += 1
                  End If
              Loop
              Continue For
      
      Process:
              Dim sStart As String = ""
              If y > 1 Then sStart = Left(st, 0 + (y - 1))
      
              Dim sMid As String = UCase(st(y - 1)) ' capitalise the first non-space character in sentence.
      
              Dim sEnd As String = Mid(st, y + 1, st.Length)
      
              SplitSentence(i) = sStart & sMid & sEnd
      
          Next
      
          ' rejoin sentances back together:
          Dim concat As String = ""
          For Each st As String In SplitSentence
              concat &= st & "."
          Next
      
          concat = concat.TrimEnd(1)
      
          Return concat
      
      End Function
      

    但是对于专有名词和首字母缩略词…在英语中经常会出现标点符号不那么简单的情况。例如,这个脚本不会检测到省略号(“…”)或缩写(例如:“琼斯先生住在木兰大道上”。在克里斯家附近)。

    要完全解决这个问题,您需要为该语言生成一个包含所有可能缩写/标点符号的词典,并使词典保持最新!考虑到这一点后,大多数人会乐于妥协,否则只需使用Microsoft Word。

        8
  •  -1
  •   EluciusFTW Kabindra Prasad Sarma    8 年前
    public string GetSentenceCase(string ReqdString) {
        string StrInSentCase = "";
        for (int j = 0; j < ReqdString.Length; j++) {
            if (j == 0) {
               StrInSentCase = ReqdString.ToString().Substring(j, 1).ToUpper();
            }
            else {
                StrInSentCase = StrInSentCase + ReqdString.ToString().Substring(j, 1).ToLower();
            }
        }
        return StrInSentCase.ToString();
    }