una ultimos recortar quitar parte obtener los extraer ejemplos caracteres caracter cadena buscar c# word-wrap textwrapping

ultimos - string split c#



Word envuelve una cadena en varias lĂ­neas (8)

Estoy tratando de encapsular una cadena en varias líneas. Cada línea tendrá un ancho definido.

Por ejemplo, obtendría este resultado si envuelvo la palabra en un área de 120 píxeles de ancho.

Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Sed augue
velit, tempor non vulputate sit amet,
dictum vitae lacus. En vitae ante
justo, ut accumsan sem. Donec
pulvinar, nisi nec sagittis consequat,
sem orci luctus velit, sed elementum
ligula ante nec neque. Pellentesque
habitante morbi tristique senectus et
netus et malesuada fames ac turpis
egestas. Etiam erat est, pellentesque
eget tincidunt ut, egestas en ante.
Nulla vitae vulputate velit. Proin en
congue neque. Cras rutrum sodales
sapien, ut convallis erat auctor vel.
Duis ultricies pharetra dui, sagittis
varius mauris tristique a. Nam ut
neque id risus tempor hendrerit.
Maecenas ut lacus nunc. Nulla
fermentum ornare rhoncus. Nulla
gravida vestibulum odio, vel commodo
magna condimentum quis. Quisque
sollicitudin blandit mi, no varius
libero lobortis eu. Vestibulum eu
turpis massa, id tincidunt orci.
Curabitur pellentesque urna no risus
adipiscing facilisis. Mauris vel
Acusan Purus. Proin quis enim nec
sem tempor vestibulum ac vitae augue.


¡Gracias! Tomo el método de la respuesta as-cii con algunos cambios, para usarlo en los formularios de Windows. Usar TextRenderer.MeasureText en lugar de FormattedText :

static List<string> WrapText(string text, double pixels, Font font) { string[] originalLines = text.Split(new string[] { " " }, StringSplitOptions.None); List<string> wrappedLines = new List<string>(); StringBuilder actualLine = new StringBuilder(); double actualWidth = 0; foreach (var item in originalLines) { int w = TextRenderer.MeasureText(item + " ", font).Width; actualWidth += w; if (actualWidth > pixels) { wrappedLines.Add(actualLine.ToString()); actualLine.Clear(); actualWidth = w; } actualLine.Append(item + " "); } if(actualLine.Length > 0) wrappedLines.Add(actualLine.ToString()); return wrappedLines; }

Y un pequeño comentario: la línea actualLine.Append (item + ""); debe colocarse después de comprobar el ancho, ya que si el valor actual es Ancho> píxeles, esta palabra debe estar en la siguiente línea.


Aquí hay una versión que se me ocurrió para mi juego XNA ...

(Tenga en cuenta que es un fragmento, no una definición de clase adecuada. ¡Disfrútelo!)

using System; using System.Text; using Microsoft.Xna.Framework.Graphics; public static float StringWidth(SpriteFont font, string text) { return font.MeasureString(text).X; } public static string WrapText(SpriteFont font, string text, float lineWidth) { const string space = " "; string[] words = text.Split(new string[] { space }, StringSplitOptions.None); float spaceWidth = StringWidth(font, space), spaceLeft = lineWidth, wordWidth; StringBuilder result = new StringBuilder(); foreach (string word in words) { wordWidth = StringWidth(font, word); if (wordWidth + spaceWidth > spaceLeft) { result.AppendLine(); spaceLeft = lineWidth - wordWidth; } else { spaceLeft -= (wordWidth + spaceWidth); } result.Append(word + space); } return result.ToString(); }


El siguiente código, tomado de este blogpost , ayudará a hacer su trabajo.

Puedes usarlo de esta manera:

string wordWrappedText = WordWrap( <yourtext>, 120 );

Tenga en cuenta que el código no es mío, solo estoy informando aquí la función principal para su producto.

protected const string _newline = "/r/n"; public static string WordWrap( string the_string, int width ) { int pos, next; StringBuilder sb = new StringBuilder(); // Lucidity check if ( width < 1 ) return the_string; // Parse each line of text for ( pos = 0; pos < the_string.Length; pos = next ) { // Find end of line int eol = the_string.IndexOf( _newline, pos ); if ( eol == -1 ) next = eol = the_string.Length; else next = eol + _newline.Length; // Copy this line of text, breaking into smaller lines as needed if ( eol > pos ) { do { int len = eol - pos; if ( len > width ) len = BreakLine( the_string, pos, width ); sb.Append( the_string, pos, len ); sb.Append( _newline ); // Trim whitespace following break pos += len; while ( pos < eol && Char.IsWhiteSpace( the_string[pos] ) ) pos++; } while ( eol > pos ); } else sb.Append( _newline ); // Empty line } return sb.ToString(); } /// <summary> /// Locates position to break the given line so as to avoid /// breaking words. /// </summary> /// <param name="text">String that contains line of text</param> /// <param name="pos">Index where line of text starts</param> /// <param name="max">Maximum line length</param> /// <returns>The modified line length</returns> public static int BreakLine(string text, int pos, int max) { // Find last whitespace in line int i = max - 1; while (i >= 0 && !Char.IsWhiteSpace(text[pos + i])) i--; if (i < 0) return max; // No whitespace found; break at maximum length // Find start of whitespace while (i >= 0 && Char.IsWhiteSpace(text[pos + i])) i--; // Return length of text before whitespace return i + 1; }


Me gustaría envolver el texto para dibujarlo después en mi imagen. Intenté la respuesta de @ as-cii, pero no funcionó en mi caso como se esperaba. Siempre se extiende el ancho dado de mi línea (tal vez porque lo uso en combinación con un objeto Graphics para dibujar el texto en mi imagen). Además, su respuesta (y las relacionadas) solo funcionan para> .Net 4 frameworks. En Framework .Net 3.5 no hay función Clear () para objetos StringBuilder . Así que aquí hay una versión editada:

public static List<string> WrapText(string text, double pixels, string fontFamily, float emSize) { string[] originalWords = text.Split(new string[] { " " }, StringSplitOptions.None); List<string> wrappedLines = new List<string>(); StringBuilder actualLine = new StringBuilder(); double actualWidth = 0; foreach (string word in originalWords) { string wordWithSpace = word + " "; FormattedText formattedWord = new FormattedText(wordWithSpace, CultureInfo.CurrentCulture, System.Windows.FlowDirection.LeftToRight, new Typeface(fontFamily), emSize, System.Windows.Media.Brushes.Black); actualLine.Append(wordWithSpace); actualWidth += formattedWord.Width; if (actualWidth > pixels) { actualLine.Remove(actualLine.Length - wordWithSpace.Length, wordWithSpace.Length); wrappedLines.Add(actualLine.ToString()); actualLine = new StringBuilder(); actualLine.Append(wordWithSpace); actualWidth = 0; actualWidth += formattedWord.Width; } } if (actualLine.Length > 0) wrappedLines.Add(actualLine.ToString()); return wrappedLines; }

Como estoy trabajando con un objeto Graphics, probé la solución @Thorins. Esto funcionó mucho mejor para mí, ya que envuelve mi texto correctamente. Pero hice algunos cambios para que pueda darle al método los parámetros requeridos. También hubo un error: la última línea no se agregó a la lista, cuando no se alcanzó la condición del bloque if en for-loop. Entonces debes agregar esta línea después. El código editado se ve así:

public static List<string> WrapTextWithGraphics(Graphics g, string original, int width, Font font) { List<string> wrappedLines = new List<string>(); string currentLine = string.Empty; for (int i = 0; i < original.Length; i++) { char currentChar = original[i]; currentLine += currentChar; if (g.MeasureString(currentLine, font).Width > width) { // exceeded length, back up to last space int moveback = 0; while (currentChar != '' '') { moveback++; i--; currentChar = original[i]; } string lineToAdd = currentLine.Substring(0, currentLine.Length - moveback); wrappedLines.Add(lineToAdd); currentLine = string.Empty; } } if (currentLine.Length > 0) wrappedLines.Add(currentLine); return wrappedLines; }


Para Winforms:

List<string> WrapText(string text, int maxWidthInPixels, Font font) { string[] originalLines = text.Split(new string[] { " " }, StringSplitOptions.None); List<string> wrappedLines = new List<string>(); StringBuilder actualLine = new StringBuilder(); int actualWidth = 0; foreach (var item in originalLines) { Size szText = TextRenderer.MeasureText(item, font); actualLine.Append(item + " "); actualWidth += szText.Width; if (actualWidth > maxWidthInPixels) { wrappedLines.Add(actualLine.ToString()); actualLine.Clear(); actualWidth = 0; } } if (actualLine.Length > 0) wrappedLines.Add(actualLine.ToString()); return wrappedLines; }


Puede obtener el ancho (aproximado) de una cadena de la clase System.Drawing.Graphics utilizando el método MeasureString (). Si necesita un ancho muy preciso, creo que debe usar el método MeasureCharacterRanges (). Aquí hay un código de muestra que usa el método MeasureString () para hacer más o menos lo que solicitó:

using System; using System.Collections.Generic; // for List<> using System.Drawing; // for Graphics and Font private List<string> GetWordwrapped(string original) { List<string> wordwrapped = new List<string>(); Graphics graphics = Graphics.FromHwnd(this.Handle); Font font = new Font("Arial", 10); string currentLine = string.Empty; for (int i = 0; i < original.Length; i++) { char currentChar = original[i]; currentLine += currentChar; if (graphics.MeasureString(currentLine, font).Width > 120) { // exceeded length, back up to last space int moveback = 0; while (currentChar != '' '') { moveback++; i--; currentChar = original[i]; } string lineToAdd = currentLine.Substring(0, currentLine.Length - moveback); wordwrapped.Add(lineToAdd); currentLine = string.Empty; } } return wordwrapped; }


public static string GetTextWithNewLines(string value = "", int charactersToWrapAt = 35, int maxLength = 250) { if (string.IsNullOrWhiteSpace(value)) return ""; value = value.Replace(" ", " "); var words = value.Split('' ''); var sb = new StringBuilder(); var currString = new StringBuilder(); foreach (var word in words) { if (currString.Length + word.Length + 1 < charactersToWrapAt) // The + 1 accounts for spaces { sb.AppendFormat(" {0}", word); currString.AppendFormat(" {0}", word); } else { currString.Clear(); sb.AppendFormat("{0}{1}", Environment.NewLine, word); currString.AppendFormat(" {0}", word); } } if (sb.Length > maxLength) { return sb.ToString().Substring(0, maxLength) + " ..."; } return sb.ToString().TrimStart().TrimEnd(); }


static void Main(string[] args) { List<string> lines = WrapText("Add some text", 300, "Calibri", 11); foreach (var item in lines) { Console.WriteLine(item); } Console.ReadLine(); } static List<string> WrapText(string text, double pixels, string fontFamily, float emSize) { string[] originalLines = text.Split(new string[] { " " }, StringSplitOptions.None); List<string> wrappedLines = new List<string>(); StringBuilder actualLine = new StringBuilder(); double actualWidth = 0; foreach (var item in originalLines) { FormattedText formatted = new FormattedText(item, CultureInfo.CurrentCulture, System.Windows.FlowDirection.LeftToRight, new Typeface(fontFamily), emSize, Brushes.Black); actualLine.Append(item + " "); actualWidth += formatted.Width; if (actualWidth > pixels) { wrappedLines.Add(actualLine.ToString()); actualLine.Clear(); actualWidth = 0; } } if(actualLine.Length > 0) wrappedLines.Add(actualLine.ToString()); return wrappedLines; }

Agregue bibliotecas WindowsBase y PresentationCore .