.NET метод для преобразования строки в предложение - PullRequest
25 голосов
/ 29 июня 2010

Я ищу функцию для преобразования строки текста в UpperCase в SentenceCase. Все примеры, которые я могу найти, превращают текст в TitleCase.

Дело о приговоре в общем смысле описывает способ, которым капитализация используется в предложении. Предложение случай также описывает стандарт капитализация английского предложения, то есть первая буква предложения с большой буквы, с остальным строчные буквы (если не требуется капитализация по определенной причине, например имена собственные, сокращения и т. д.).

Может кто-нибудь указать мне направление сценария или функции для SentenceCase?

Ответы [ 8 ]

32 голосов
/ 29 июня 2010

Нет ничего встроенного в .NET - однако, это один из тех случаев, когда обработка регулярных выражений действительно может работать хорошо. Я бы начал с преобразования всей строки в нижний регистр, а затем, в первом приближении, вы можете использовать регулярное выражение, чтобы найти все последовательности, такие как [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."

Это может быть уточнено несколькими различными способами, чтобы лучше соответствовать более широкому разнообразию шаблонов предложений (не только тех, которые заканчиваются буквой + точка).

7 голосов
/ 29 июня 2010

Это работает для меня.

/// <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);
}
5 голосов
/ 04 апреля 2013

Существует встроенная функция 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

2 голосов
/ 16 октября 2014

Если вы хотите заключить в регистр строку, содержащую пунктуацию, отличную от точек:

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());
2 голосов
/ 29 июня 2010

Если ваша входная строка не предложение, а много предложений, это становится очень сложной проблемой.

Регулярные выражения окажутся неоценимым инструментом, но (1) вам придется их хорошо знать, чтобы быть эффективными, и (2) они могут не справиться с работой самостоятельно.

Считайте это предложение

«Кто на первом месте», - ответил мистер Смит, который не смеялся.

Это предложение начинается не с буквы, оно состоит из цифры, различных знаков препинания, собственного имени и . в середине.

Сложности огромны, и это одно предложение.

Одна из самых важных вещей при использовании RegEx - это «знать свои данные». Если вы знаете широту типов предложений, с которыми вы будете иметь дело, ваша задача будет более управляемой.

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

2 голосов
/ 29 июня 2010

Я нашел этот образец на MSDN .

1 голос
/ 04 мая 2012

Это то, что я использую (VB.NET). Работает в большинстве ситуаций, в том числе:

  • несколько предложений
  • предложения, начинающиеся и заканчивающиеся пробелами
  • предложения, начинающиеся с символов, отличных от A-Z. Например, он будет работать для: «Если вы хотите 100,00 $, просто спросите меня».

    <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.

0 голосов
/ 14 сентября 2016
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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...