2010-06-29 12 views
20

Estoy buscando una función para convertir una cadena de texto que está en UpperCase a SentenceCase. Todos los ejemplos que puedo encontrar convierten el texto en TitleCase.Método .NET para convertir una cadena en una oración

caso de la oración en un sentido general describe la forma en que la capitalización se utiliza dentro de una oración. Sentencia caso también se describe la norma capitalización de una frase Inglés, es decir, la primera letra de la oración se capitaliza, siendo el resto minúsculas (a menos que requiera capitalización por una razón específica, por ejemplo, nombres propios, acrónimos, etc.).

¿Alguien me puede indicar un script o función para SentenceCase?

+0

es la cadena de una frase, o muchas frases? – Jay

+1

http://stackoverflow.com/questions/2135863/formatting-sentences-in-a-string-using-c – SwDevMan81

Respuesta

28

No hay nada integrado en .NET, sin embargo, este es uno de esos casos en los que el procesamiento de expresiones regulares puede funcionar bien. Comenzaría primero por convertir toda la cadena a minúsculas, y luego, como primera aproximación, podría usar expresiones regulares para buscar todas las secuencias como [a-z]\.\s+(.), y usar ToUpper() para convertir el grupo capturado a mayúsculas. La clase RegEx tiene un método Replace() sobrecargado que acepta un delegado MatchEvaluator, que le permite definir cómo reemplazar el valor coincidente.

Aquí está un ejemplo de código de este en el trabajo:

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

Esto podría ser refinado en un número de maneras diferentes para adaptarse mejor a una variedad más amplia de las estructuras de frases (no sólo los que terminan en una carta + periodo) .

+0

Hice un método de extensión de esto y agregué una variable booleana opcional para opcionalmente minúsculas de la cadena antes de alterar el cuerda. Eso ayudaría con cadenas como la que se encuentra en la respuesta de Jay a continuación. Es comprensible que sea algo que rara vez uso, pero podría ser útil en algún momento. – krillgar

4

Esto funciona para mí.

/// <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); 
} 
+1

Si la entrada contiene oraciones múltiples, también necesitará dividir cada oración usando el punto como delimitador. – RvdK

+0

O cualquier otro signo de puntuación válido – SwDevMan81

+2

"punto como delimitador" realmente no lo corta. 'Sr. y la Sra. Smith tiene $ 1,000.00 cada uno; ellos viven en Magnolia Blvd. en la casa azul. – Jay

2

He encontrado este sample on MSDN.

+0

Esto parece una forma muy complicada de convertir una cadena en un caso de oraciones. Creo que este es un problema más adecuado para expresiones regulares, personalmente. – LBushkin

2

Si su cadena de entrada no es una oración, sino muchas oraciones, se convierte en un problema muy difícil.

Las expresiones regulares serán una herramienta invaluable, pero (1) tendrá que conocerlas bastante bien para ser efectiva, y (2) puede que no sean capaces de hacer el trabajo completamente por sí mismas.

considerar esta frase

"¿Quién está en primera," el Sr. Smith - que no se estaba riendo - respondió.

Esta frase no se inicia con una carta, que tiene un dígito, varios puntuacion, un nombre propio, y una . en el medio.

Las complejidades son enormes, y esta es una oración.

Una de las cosas más importantes al usar RegEx es "conocer sus datos". Si conoce la amplitud de tipos de oraciones con las que se enfrentará, su tarea será más manejable.

En cualquier caso, tendrá que jugar con su implementación hasta que esté satisfecho con sus resultados.Sugiero escribir algunas pruebas automatizadas con algunos ejemplos de entrada: a medida que trabaje en su implementación, puede ejecutar las pruebas regularmente para ver dónde se está acercando y dónde aún está faltando la marca.

1

Esto es lo que uso (VB.NET). Funciona en la mayoría de situaciones, incluyendo:

  • múltiples frases
  • frases comenzando y terminando con espacios
  • frases que comienzan con caracteres distintos de A-Z. Por ejemplo, funcionará para: "si quieres $ 100.00, pregúntame".

    <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 
    

Pero en cuanto a los nombres propios y acrónimos, bueno ... no siempre van a haber situaciones en el idioma Inglés, donde puntuacion no es tan simple. Por ejemplo, este script no detectará una elipsis ("...") o abreviaturas (por ejemplo: "El Sr. Jones vivió en Magnolia Blvd. cerca de la casa de Chris").

Para solucionar el problema por completo, deberá generar un diccionario de todas las abreviaturas/signos de puntuación posibles para el idioma y mantener el diccionario actualizado. Después de considerar esto, la mayoría estará contento con un compromiso; de lo contrario, simplemente use Microsoft Word.

2

Si desea a mayúscula una cadena que contiene puntuacion que no sea sólo períodos:

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()); 
-1
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(); 
} 
Cuestiones relacionadas