Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Tipos base
Sistema de tipos comunes
Conversión de tipos en .NET
Tablas de conversión de tipos
Aplicación de formato a tipos
Cadenas con formato numérico estándar
Cadenas con formato numérico personalizado
Cadenas con formato de fecha y hora estándar
Cadenas con formato de fecha y hora personalizado
Cadenas de formato TimeSpan estándar
Cadenas de formato TimeSpan personalizado
Cadenas de formato de enumeración
Formatos compuestos
Efectuar operaciones de formato
Procedimiento para rellenar un número con ceros a la izquierda
Procedimiento para extraer el día de la semana de una fecha concreta
Procedimiento para definir y usar proveedores de formato numérico
personalizado
Procedimiento para valores de fecha y hora de ida y vuelta
Procedimiento para mostrar milisegundos en los valores de fecha y hora
Procedimiento para mostrar fechas en calendarios no gregorianos
Manipulación de cadenas
Procedimientos recomendados para el uso de cadenas
Operaciones básicas de cadenas
Creación de cadenas
Recortado y eliminación de caracteres
Rellenado de cadenas
Comparar cadenas
Cambio de mayúsculas y minúsculas
Uso de la clase StringBuilder
Procedimiento para realizar manipulaciones de cadena básicas
Expresiones regulares en .NET
Lenguaje de expresiones regulares - Referencia rápida
Escapes de carácter
Clases de caracteres
Delimitadores
Construcciones de agrupamiento
Cuantificadores
Construcciones de referencia inversa
Construcciones de alternancia
Sustituciones
Opciones de expresiones regulares
Construcciones misceláneas
Procedimientos recomendados con expresiones regulares
El modelo de objetos de expresión regular
Detalles del comportamiento de expresiones regulares
Retroceso
Compilar y volver a utilizar
Seguridad para subprocesos
Ejemplos de expresiones regulares
Ejemplo: Buscar etiquetas HREF
Ejemplo: Cambiar formatos de fecha
Procedimiento para extraer un protocolo y un número de puerto de una
dirección URL
Procedimiento para quitar caracteres no válidos de una cadena
Cómo comprobar si las cadenas tienen un formato de correo electrónico válido
Codificación de caracteres de .NET
Análisis de cadenas
Análisis de cadenas numéricas
Análisis de cadenas de fecha y hora
Analizar otras cadenas
Trabajar con tipos base en .NET
31/10/2019 • 2 minutes to read • Edit Online
Esta sección describe las operaciones de tipo base .NET, incluidas operaciones comunes, de conversión y formato.
En esta sección
Conversión de tipos en .NET Framework
Se describe cómo convertir de un tipo a otro.
Aplicación de formato a tipos
Se describe cómo dar formato a cadenas mediante los especificadores de formato de cadena.
Manipular cadenas
Se describe cómo manipular y dar formato a cadenas.
Parsing Strings
Se describe cómo convertir cadenas en tipos de .NET Framework.
Secciones relacionadas
Sistema de tipos comunes
Se describen los tipos que usa .NET Framework.
Fechas, horas y zonas horarias
Describe cómo trabajar con zonas horarias y conversiones de la zona horaria en aplicaciones que tienen en cuenta
la zona horaria.
Sistema de tipos comunes
13/01/2020 • 46 minutes to read • Edit Online
Common Type System define cómo se declaran, usan y administran los tipos en Common Language Runtime. Es
también una parte importante de la compatibilidad en tiempo de ejecución con la integración entre lenguajes. El
sistema de tipos común realiza las funciones siguientes:
Establece un marco de trabajo que ayuda a permitir la integración entre lenguajes, la seguridad de tipos y la
ejecución de código de alto rendimiento.
Proporciona un modelo orientado a objetos que admite la implementación completa de muchos lenguajes
de programación.
Define reglas que deben seguir los lenguajes, lo que ayuda a garantizar que los objetos escritos en distintos
lenguajes puedan interactuar unos con otros.
Proporciona una biblioteca que contiene los tipos de datos primitivos (como Boolean, Byte, Char, Int32 y
UInt64) que se emplean en el desarrollo de aplicaciones.
Este tema contiene las siguientes secciones:
Tipos de .NET
Definiciones de tipo
Miembros de tipos
Características de los miembros de tipos
Tipos de .NET
Todos los tipos de .NET son tipos de valor o tipos de referencia.
Los tipos de valor son tipos de datos cuyos objetos se representan mediante el valor real del objeto. Si se asigna
una instancia de un tipo de valor a una variable, esa variable obtiene una copia reciente del valor.
Los tipos de referencia son tipos de datos cuyos objetos se representan mediante una referencia (similar a un
puntero) al valor real del objeto. Si se asigna un tipo de referencia a una variable, esa variable hace referencia (o
apunta) al valor original. No se realiza ninguna copia.
Common Type System en .NET admite las cinco categorías de tipos siguientes:
Clases
Estructuras
Enumeraciones
Interfaces
Delegados
Clases
Una clase es un tipo de referencia que se puede derivar directamente de otra clase y que se deriva implícitamente
de System.Object. La clase define las operaciones que un objeto (que es una instancia de la clase) puede realizar
(métodos, eventos o propiedades) y los datos que el objeto contiene (campos). Aunque una clase suele incluir una
definición y una implementación (a diferencia, por ejemplo, de las interfaces, que solo contienen una definición sin
implementación), puede tener uno o varios miembros sin implementación.
En la tabla siguiente se describen algunas de las características que una clase puede tener. Cada lenguaje
compatible con el motor en tiempo de ejecución proporciona una forma de indicar que una clase o un miembro de
clase tiene una o varias de estas características. En cambio, puede que no estén disponibles todas estas
características en los lenguajes de programación orientados a .NET.
CARACTERÍSTICA DESCRIPCIÓN
exported o not exported Indica si una clase está visible fuera del ensamblado en el que
se define. Esta característica se aplica únicamente a las clases
de nivel superior y no a las clases anidadas.
NOTE
Una clase también puede estar anidada en una estructura o clase primaria. Las clases anidadas tienen también características
de miembro. Para obtener más información, consulte Tipos anidados.
Los miembros de clase que no tienen implementación son miembros abstractos. Una clase que tiene uno o varios
miembros abstractos es abstracta y no se pueden crear nuevas instancias de ella. Algunos lenguajes destinados al
motor en tiempo de ejecución permiten marcar una clase como abstracta incluso aunque no tenga ningún
miembro abstracto. Se puede usar una clase abstracta cuando se desea encapsular un conjunto básico de
funcionalidad que las clases derivadas pueden heredar o invalidar según corresponda. Las clases que no son
abstractas se conocen como clases concretas.
Una clase puede implementar cualquier número de interfaces pero puede heredar solo de una clase base además
de la clase System.Object, de la que todas las clases heredan implícitamente. Todas las clases deben tener al menos
un constructor, que inicializa nuevas instancias de la clase. Si no se define explícitamente un constructor, la mayoría
de los compiladores proporcionarán automáticamente un constructor sin parámetros.
Estructuras
Una estructura es un tipo de valor que se deriva implícitamente de System.ValueType, que a su vez se deriva de
System.Object. Una estructura es muy útil para representar valores cuyos requisitos de memoria son reducidos y
para pasar valores como parámetros por valor a los métodos que tienen parámetros fuertemente tipados. En .NET,
todos los tipos de datos primitivos (Boolean, Byte, Char, DateTime, Decimal, Double, Int16, Int32, Int64, SByte,
Single, UInt16, UInt32 y UInt64) se definen como estructuras.
Al igual que las clases, las estructuras definen datos (los campos de la estructura) y las operaciones que se pueden
realizar con esos datos (los métodos de la estructura). Esto significa que se puede llamar a los métodos en las
estructuras, incluso a los métodos virtuales definidos en las clases System.Object y System.ValueType, y a cualquier
método definido en el propio tipo de valor. Es decir, las estructuras pueden tener campos, propiedades y eventos,
así como métodos estáticos y no estáticos. Se pueden crear instancias de las estructuras, pasarlas como
parámetros, almacenarlas como variables locales o almacenarlas en un campo de otro tipo de valor o tipo de
referencia. Las estructuras también pueden implementar interfaces.
Los tipos de valor también difieren de las clases en varios aspectos. En primer lugar, aunque heredan
implícitamente de System.ValueType, no pueden heredar directamente de ningún tipo. De manera similar, todos los
tipos de valor están sellados, lo que quiere decir que de ellos no se puede derivar ningún otro tipo. Tampoco
necesitan constructores.
Para cada tipo de valor, Common Language Runtime proporciona un tipo correspondiente al que se ha aplicado la
conversión boxing, que es una clase que tiene el mismo estado y comportamiento que el tipo de valor. A una
instancia de un tipo de valor se le aplica la conversión boxing cuando se pasa a un método que acepta un
parámetro de tipo System.Object. Se le aplica la conversión unboxing (es decir, se vuelve a convertir la instancia de
una clase en una instancia de un tipo de valor) cuando se devuelve el control de una llamada a un método que
acepta un tipo de valor como parámetro por referencia. En el caso de algunos lenguajes, se debe usar una sintaxis
especial cuando se necesita el tipo al que se haya aplicado la conversión boxing, mientras que otros emplean el tipo
automáticamente cuando es necesario. Cuando se define un tipo de valor, se definen los dos tipos: al que se ha
aplicado la conversión boxing y al que se ha aplicado la conversión unboxing.
Enumeraciones
Una enumeración (enum) es un tipo de valor que hereda directamente de System.Enum y proporciona nombres
alternativos para los valores de un tipo primitivo subyacente. Un tipo de enumeración tiene un nombre, un tipo
subyacente que debe ser uno de los tipos de enteros con o sin signo integrados (como Byte, Int32 o UInt64) y un
conjunto de campos. Los campos son campos literales estáticos, cada uno de los cuales representa una constante.
El mismo valor se puede asignar a varios campos. Cuando esto sucede, se debe marcar uno de los valores como
valor de enumeración primario para la reflexión y la conversión de cadenas.
Se puede asignar un valor del tipo subyacente a una enumeración y viceversa, y no es necesario que el motor en
tiempo de ejecución realice una conversión. Se puede crear una instancia de una enumeración y llamar a los
métodos de System.Enum, además de llamar a cualquier método definido en el tipo subyacente de la enumeración.
Sin embargo, algunos lenguajes no permiten pasar una enumeración como parámetro cuando se necesita una
instancia del tipo subyacente (o viceversa).
A las enumeraciones se les aplican las restricciones siguientes:
No pueden definir sus propios métodos.
No pueden implementar interfaces.
No pueden definir propiedades ni eventos.
No pueden ser genéricas, a menos que sean genéricas solo porque están anidadas dentro de un tipo
genérico. Es decir, una enumeración no puede tener parámetros de tipo propios.
NOTE
Los tipos anidados (incluidas las enumeraciones) creados con Visual Basic, C# y C++ incluyen los parámetros de tipo
de todos los tipos genéricos envolventes, por lo que son genéricos aunque no tengan parámetros de tipo propios.
Para obtener más información, vea la sección "Tipos anidados" en el tema de referencia del método
Type.MakeGenericType.
El atributo FlagsAttribute indica una clase especial de enumeración denominada campo de bits. El motor en tiempo
de ejecución no distingue entre enumeraciones tradicionales y campos de bits, pero el lenguaje podría hacerlo.
Cuando se hace esta distinción, se pueden utilizar operadores bit a bit en estos campos de bits, para generar
valores sin nombre, pero no en las enumeraciones. Normalmente, las enumeraciones se utilizan para listas de
elementos únicos, como los días de la semana, los nombres de países o regiones, etc. Los campos de bits se
utilizan, en general, para listas de calidades o cantidades que pueden producirse en combinaciones, como
Red And Big And Fast .
En el ejemplo siguiente se muestra cómo utilizar los campos de bits y las enumeraciones tradicionales.
using System;
using System.Collections.Generic;
AvailableIn[SomeRootVegetables.HorseRadish] = Seasons.All;
AvailableIn[SomeRootVegetables.Radish] = Seasons.Spring;
AvailableIn[SomeRootVegetables.Turnip] = Seasons.Spring |
Seasons.Autumn;
AvailableIn(SomeRootVegetables.HorseRadish) = Seasons.All
AvailableIn(SomeRootVegetables.Radish) = Seasons.Spring
AvailableIn(SomeRootVegetables.Turnip) = Seasons.Spring Or _
Seasons.Autumn
Interfaces
Una interfaz define un contrato que especifica una relación de lo que se puede hacer o una relación de lo que se
tiene. Las interfaces se utilizan a menudo para implementar una funcionalidad, como comparar y ordenar
(interfaces IComparable e IComparable<T>), comprobar la igualdad (interfaz IEquatable<T>) o enumerar los
elementos de una colección (interfaces IEnumerable e IEnumerable<T>). Las interfaces pueden tener propiedades,
métodos y eventos, que son todos miembros abstractos; es decir, aunque la interfaz define los miembros y sus
firmas, deja que el tipo encargado de implementar la interfaz defina la funcionalidad de cada miembro de la
interfaz. Esto significa que cualquier clase o estructura que implemente una interfaz debe proporcionar definiciones
de los miembros abstractos declarados en la interfaz. Una interfaz puede necesitar que cualquier clase o estructura
que implemente una interfaz implemente también otras interfaces.
A las interfaces se les aplican las restricciones siguientes:
Una interfaz se puede declarar con cualquier tipo de accesibilidad, pero los miembros de la interfaz deben
tener todos accesibilidad pública.
Las interfaces no pueden definir constructores
Las interfaces no pueden definir campos.
Las interfaces solo pueden definir miembros de instancia. No pueden definir miembros estáticos.
Cada lenguaje debe proporcionar reglas para asignar una implementación a la interfaz que necesita el miembro, ya
que varias interfaces pueden declarar un miembro con la misma firma y esos miembros pueden tener
implementaciones independientes.
Delegados
Los delegados son tipos de referencia con una finalidad similar a la de los punteros a función de C++. Se usan para
los controladores de eventos y las funciones de devolución de llamada en .NET. A diferencia de los punteros a
función, los delegados son seguros, se pueden comprobar y proporcionan seguridad de tipos. Un tipo de delegado
puede representar cualquier método de instancia o método estático que tenga una firma compatible.
Un parámetro de un delegado es compatible con el parámetro correspondiente de un método si el tipo del
parámetro del delegado es más restrictivo que el del método, porque así se garantiza que el argumento que se
pase al delegado también se podrá pasar de forma segura al método.
De forma similar, el tipo de valor devuelto de un delegado es compatible con el tipo de valor devuelto de un
método si el del método es más restrictivo que el del delegado, porque así se garantiza que el tipo de valor
devuelto por el método se puede convertir con seguridad al tipo de valor devuelto del delegado.
Por ejemplo, un delegado que tiene un parámetro de tipo IEnumerable y un tipo de valor devuelto Object puede
representar un método que tiene un parámetro de tipo Object y un valor devuelto de tipo IEnumerable. Para
obtener más información y un código de ejemplo, vea Delegate.CreateDelegate(Type, Object, MethodInfo).
Se dice que un delegado está enlazado al método que representa. Además de estar enlazado al método, un
delegado puede estar enlazado a un objeto. El objeto representa el primer parámetro del método y se pasa al
método cada vez que se invoca el delegado. Si el método es un método de instancia, el objeto enlazado se pasa
como el parámetro this implícito ( Me en Visual Basic); si el método es estático, el objeto se pasa como primer
parámetro formal del método y la firma del delegado debe coincidir con los parámetros restantes. Para obtener
más información y un código de ejemplo, vea System.Delegate.
Todos los delegados heredan de System.MulticastDelegate, que hereda de System.Delegate. Los lenguajes C#,
Visual Basic y C++ no permiten que se herede de estos tipos. En su lugar, proporcionan palabras clave para
declarar los delegados.
Dado que los delegados heredan de MulticastDelegate, un delegado tiene una lista de invocación, que es una lista
de métodos que representa el delegado y que se ejecutan cuando se llama al delegado. Todos los métodos de la
lista reciben los argumentos proporcionados cuando se invoca al delegado.
NOTE
El valor devuelto no se define para los delegados que tienen más de un método en su lista de invocación, aunque el delegado
tenga un tipo de valor devuelto.
En muchos casos, como en el de los métodos de devolución de llamada, un delegado solo representa un método y
las únicas acciones que se deben llevar a cabo son la creación y la invocación del delegado.
Por lo que se refiere a los delegados que representan varios métodos, .NET proporciona métodos de las clases de
delegado Delegate y MulticastDelegate para operaciones tales como agregar un método a una lista de invocación
del delegado (el método Delegate.Combine), quitar un método (el método Delegate.Remove) y obtener la lista de
invocación (el método Delegate.GetInvocationList).
NOTE
No es preciso usar estos métodos para los delegados de controladores de eventos en C#, C++ ni Visual Basic, ya que estos
lenguajes proporcionan sintaxis para agregar y quitar controladores de eventos.
Definiciones de tipos
Una definición de tipo incluye lo siguiente:
Los atributos definidos en el tipo.
La accesibilidad del tipo (visibilidad).
El nombre del tipo.
El tipo base del tipo.
Las interfaces que implementa el tipo.
Las definiciones de todos los miembros del tipo
Atributos
Los atributos proporcionan metadatos adicionales definidos por el usuario . Normalmente, se emplean para
almacenar información adicional sobre un tipo en su ensamblado o para modificar el comportamiento de un
miembro de tipo en tiempo de diseño o en tiempo de ejecución.
Los atributos son clases que heredan de System.Attribute. Los lenguajes que admiten el uso de atributos tienen su
propia sintaxis para aplicar atributos a un elemento del lenguaje. Los atributos se pueden aplicar a casi cualquier
elemento del lenguaje; los elementos específicos a los que se puede aplicar un atributo los define la clase
AttributeUsageAttribute aplicada a esa clase de atributos.
Accesibilidad a tipos
Todos los tipos tienen un modificador que rige su accesibilidad desde otros tipos. En la tabla siguiente se describen
las accesibilidades a tipos que admite el motor en tiempo de ejecución.
ACCESIBILIDAD DESCRIPCIÓN
La accesibilidad de un tipo anidado depende de su dominio de accesibilidad, que viene determinado por la
accesibilidad declarada del miembro y el dominio de accesibilidad del tipo contenedor inmediato. Sin embargo, el
dominio de accesibilidad de un tipo anidado no puede superar al del tipo contenedor.
El dominio de accesibilidad de un miembro anidado M declarado en un tipo T dentro de un programa P se
define de la manera siguiente (teniendo en cuenta que el propio miembro M puede ser un tipo):
Si la accesibilidad declarada de M es public , el dominio de accesibilidad de M es el dominio de
accesibilidad de T .
Si la accesibilidad declarada de M es protected internal , el dominio de accesibilidad de M es la
intersección del dominio de accesibilidad de T con el texto de programa de P y el texto de programa de
cualquier tipo derivado de T declarado fuera de P .
Si la accesibilidad declarada de M es protected , el dominio de accesibilidad de M es la intersección del
dominio de accesibilidad de T con el texto de programa de T y cualquier tipo derivado de T .
Si la accesibilidad declarada de M es internal , el dominio de accesibilidad de M es la intersección del
dominio de accesibilidad de T con el texto de programa de P .
Si la accesibilidad declarada de M es private , el dominio de accesibilidad de M es el texto de programa de
T .
Nombres de tipo
El sistema de tipos común sólo impone dos restricciones en los nombres:
Todos los nombres se codifican como cadenas de caracteres Unicode (de 16 bits).
Los nombres no pueden tener un valor incrustado (de 16 bits) de 0x0000.
Sin embargo, la mayoría de los lenguajes imponen restricciones adicionales sobre los nombres de tipo. Todas las
comparaciones se realizan byte a byte, por lo que distinguen entre mayúsculas y minúsculas y son independientes
de la configuración regional.
Aunque un tipo puede hacer referencia a tipos de otros módulos y ensamblados, es preciso que se defina
íntegramente en un solo módulo de .NET. (Sin embargo, según la compatibilidad del compilador, se puede dividir
en varios archivos de código fuente.) Los nombres de tipo solo tienen que ser únicos dentro de un espacio de
nombres. Para identificar íntegramente un tipo, su nombre debe calificarse con el espacio de nombres que contiene
la implementación del tipo.
Tipos base e interfaces
Un tipo puede heredar valores y comportamientos de otro. El sistema de tipos común no permite que los tipos
hereden de más de un tipo base.
Un tipo puede implementar cualquier número de interfaces. Para implementar una interfaz, un tipo debe
implementar todos los miembros virtuales de la interfaz. Un tipo derivado puede implementar un método virtual,
que se puede invocar estática o dinámicamente.
Miembros de tipos
El motor en tiempo de ejecución permite definir miembros de tipos, que especifican el comportamiento y el estado
de los tipos. Los miembros de tipos incluyen lo siguiente:
Campos
Propiedades
Métodos
Constructores
Eventos
Tipos anidados
Campos
Un campo describe y contiene parte del estado del tipo. Los campos pueden ser de cualquier tipo que admita el
motor en tiempo de ejecución. Normalmente, los campos son de tipo private o protected , por lo que son
accesibles únicamente desde la clase o desde una clase derivada. Si el valor de un campo se puede modificar desde
fuera de su tipo, se suele emplear un descriptor de acceso set de una propiedad. Los campos expuestos
públicamente suelen ser de solo lectura y pueden ser de dos tipos:
Constantes, cuyo valor se asigna en tiempo de diseño. Se trata de miembros estáticos de una clase, aunque
no se definen mediante la palabra clave static ( Shared en Visual Basic).
Variables de solo lectura, cuyos valores se pueden asignar en el constructor de clase.
En el ejemplo siguiente se muestran estos dos usos de los campos de solo lectura.
using System;
Propiedades
Una propiedad identifica un valor o un estado del tipo y define los métodos para obtener o establecer el valor de la
propiedad. Las propiedades pueden ser tipos primitivos, colecciones de tipos primitivos, tipos definidos por el
usuario o colecciones de tipos definidos por el usuario. Las propiedades se usan a menudo para que la interfaz
pública de un tipo se mantenga independiente de la representación real del tipo. De este modo, las propiedades
pueden reflejar valores que no están almacenados directamente en la clase (por ejemplo, cuando una propiedad
devuelve un valor calculado) o realizar la validación antes de que se asignen valores a campos privados. En el
ejemplo siguiente se muestra el último modelo.
using System;
Además de incluir la propiedad propiamente dicha, el Lenguaje Intermedio de Microsoft (MSIL ) de un tipo que
contiene una propiedad de lectura incluye un método get_ propertyname y el lenguaje MSIL de un tipo que
contiene una propiedad de escritura incluye un método set_ propertyname.
Métodos
Un método describe las operaciones que están disponibles en el tipo. La firma de un método especifica los tipos
permitidos de todos sus parámetros y de su valor devuelto.
Aunque la mayoría de los métodos definen el número exacto de los parámetros necesarios para las llamadas a
métodos, algunos admiten un número de parámetros que es variable. El último parámetro declarado de estos
métodos se marca con el atributo ParamArrayAttribute. Normalmente, los compiladores de lenguaje proporcionan
una palabra clave, como params en C# y ParamArray en Visual Basic, que hace que sea innecesario el uso explícito
de ParamArrayAttribute.
Constructores
Un constructor es un tipo de método especial que crea nuevas instancias de una clase o una estructura. Al igual
que cualquier otro método, un constructor puede incluir parámetros; sin embargo, los constructores no tienen
ningún valor devuelto (es decir, devuelven void ).
Si el código fuente de una clase no define explícitamente un constructor, el compilador incluye un constructor sin
parámetros. Sin embargo, si el código fuente de una clase define solo constructores parametrizados, los
compiladores de Visual Basic y C# no generan un constructor sin parámetros.
Si el código fuente de una estructura define constructores, estos deben tener parámetros; una estructura no puede
definir un constructor sin parámetros y los compiladores no generan constructores sin parámetros para las
estructuras u otros tipos de valor. Todos los tipos de valor tienen un constructor sin parámetros implícito. Common
Language Runtime implementa este constructor, que inicializa todos los campos de la estructura en sus valores
predeterminados.
Events
Un evento define un incidente al que se puede responder, así como los métodos para suscribirse a un evento,
anular la suscripción y generar el evento. Los eventos se usan con frecuencia para informar a otros tipos de
cambios de estado. Para más información, vea Eventos.
Tipos anidados
Un tipo anidado es un tipo que es un miembro de algún otro tipo. Los tipos anidados deben estar estrechamente
acoplados a su tipo contenedor y no deben ser útiles como tipos de uso general. Los tipos anidados son útiles
cuando el tipo declarativo utiliza y crea instancias del tipo anidado y el uso de dicho tipo anidado no se expone en
miembros públicos.
Los tipos anidados resultan confusos para algunos desarrolladores y no deben estar públicamente visibles a menos
que haya una razón de peso. En una biblioteca bien diseñada, los desarrolladores rara vez deberían tener que
utilizar tipos anidados para crear instancias de objetos o declarar variables.
family
Accesible desde el mismo tipo que el
miembro y desde tipos derivados que
heredan de él.
ensamblado
Accesible sólo en el ensamblado en que
está definido el tipo.
family y assembly
Accesible sólo desde los tipos que estén
calificados para el acceso de familia y
ensamblado.
family o assembly
Accesible sólo desde los tipos que
califican el acceso de familia o
ensamblado.
public
Accesible desde cualquier tipo.
newslot
Oculta los miembros heredados que
tienen la misma firma.
override
Reemplaza la definición de un método
virtual heredado.
Sobrecarga
Cada miembro de tipo tiene una firma única. Las firmas de método están formadas por el nombre del método y
una lista de parámetros (el orden y los tipos de los argumentos del método). Se pueden definir varios métodos con
el mismo nombre dentro un tipo, siempre y cuando sus firmas sean distintas. Cuando se definen dos o más
métodos con el mismo nombre se dice que el método está sobrecargado. Por ejemplo, en System.Char, se
reemplaza el método IsDigit. Un método toma un argumento de tipo Char. El otro método toma un argumento de
tipo String y un argumento de tipo Int32.
NOTE
El tipo de valor devuelto no se considera parte de la firma de un método. Es decir, no se pueden sobrecargar los métodos si
solo difieren en el tipo de valor devuelto.
Vea también
Explorador de API de .NET
Common Language Runtime
Conversión de tipos en .NET
Conversión de tipos en .NET Framework
25/11/2019 • 42 minutes to read • Edit Online
Cada valor tiene un tipo asociado, que define atributos como la cantidad de espacio asignado al valor, el intervalo
de valores posibles que puede tener y los miembros que ofrece. Muchos valores se pueden expresar como más de
un tipo. Por ejemplo, el valor 4 se puede expresar como un entero o como un valor de punto flotante. La
conversión de tipo crea un valor en un nuevo tipo que es equivalente al valor de un tipo antiguo, pero no conserva
necesariamente la identidad (o valor exacto) del objeto original.
.NET Framework admite automáticamente las conversiones siguientes:
Conversión de una clase derivada a una clase base. Esto significa, por ejemplo, que una instancia de
cualquier clase o estructura se puede convertir en una instancia de tipo Object. Esta conversión no requiere
un operador de conversión.
Conversión de una clase base a la clase derivada original. En C#, esta conversión requiere un operador de
conversión. En Visual Basic, requiere el operador CType si Option Strict está activado.
Conversión de un tipo que implementa una interfaz a un objeto de interfaz que representa esa interfaz. Esta
conversión no requiere un operador de conversión.
Conversión de un objeto de interfaz al tipo original que implementa esa interfaz. En C#, esta conversión
requiere un operador de conversión. En Visual Basic, requiere el operador CType si Option Strict está
activado.
Además de estas conversiones automáticas, .NET Framework proporciona varias características que admiten la
conversión de tipos personalizada. Entre ellas se incluyen las siguientes:
El operador Implicit , que define las conversiones de ampliación disponibles entre los tipos. Para obtener
más información, consulte la sección Conversión implícita con el operador Implicit.
El operador Explicit , que define las conversiones de restricción disponibles entre los tipos. Para obtener
más información, consulte la sección Conversión explícita con el operador Explicit.
La interfaz IConvertible, que define las conversiones en cada uno de los tipos de datos base de .NET
Framework. Para obtener más información, vea Interfaz IConvertible.
La clase Convert, que proporciona un conjunto de métodos que implementan los métodos de la interfaz
IConvertible. Para obtener más información, vea la sección Clase Convert.
La clase TypeConverter, que es una clase base que se puede extender para admitir la conversión de un tipo
concreto en cualquier otro tipo. Para obtener más información, vea Clase TypeConverter.
Por ejemplo, el tipo Decimal admite conversiones implícitas a partir de valores Byte, Char, Int16, Int32, Int64,
SByte, UInt16, UInt32 y UInt64. En el ejemplo siguiente se muestran algunas de estas conversiones implícitas al
asignar valores a una variable Decimal.
decimal decimalValue;
decimalValue = byteValue;
Console.WriteLine("After assigning a {0} value, the Decimal value is {1}.",
byteValue.GetType().Name, decimalValue);
decimalValue = shortValue;
Console.WriteLine("After assigning a {0} value, the Decimal value is {1}.",
shortValue.GetType().Name, decimalValue);
decimalValue = intValue;
Console.WriteLine("After assigning a {0} value, the Decimal value is {1}.",
intValue.GetType().Name, decimalValue);
decimalValue = longValue;
Console.WriteLine("After assigning a {0} value, the Decimal value is {1}.",
longValue.GetType().Name, decimalValue);
decimalValue = ulongValue;
Console.WriteLine("After assigning a {0} value, the Decimal value is {1}.",
longValue.GetType().Name, decimalValue);
// The example displays the following output:
// After assigning a Byte value, the Decimal value is 16.
// After assigning a Int16 value, the Decimal value is -1024.
// After assigning a Int32 value, the Decimal value is -1034000.
// After assigning a Int64 value, the Decimal value is 1152921504606846976.
// After assigning a Int64 value, the Decimal value is 18446744073709551615.
Dim byteValue As Byte = 16
Dim shortValue As Short = -1024
Dim intValue As Integer = -1034000
Dim longValue As Long = CLng(1024^6)
Dim ulongValue As ULong = ULong.MaxValue
decimalValue = byteValue
Console.WriteLine("After assigning a {0} value, the Decimal value is {1}.",
byteValue.GetType().Name, decimalValue)
decimalValue = shortValue
Console.WriteLine("After assigning a {0} value, the Decimal value is {1}.",
shortValue.GetType().Name, decimalValue)
decimalValue = intValue
Console.WriteLine("After assigning a {0} value, the Decimal value is {1}.",
intValue.GetType().Name, decimalValue)
decimalValue = longValue
Console.WriteLine("After assigning a {0} value, the Decimal value is {1}.",
longValue.GetType().Name, decimalValue)
decimalValue = ulongValue
Console.WriteLine("After assigning a {0} value, the Decimal value is {1}.",
longValue.GetType().Name, decimalValue)
' The example displays the following output:
' After assigning a Byte value, the Decimal value is 16.
' After assigning a Int16 value, the Decimal value is -1024.
' After assigning a Int32 value, the Decimal value is -1034000.
' After assigning a Int64 value, the Decimal value is 1152921504606846976.
' After assigning a Int64 value, the Decimal value is 18446744073709551615.
A continuación, el código de cliente puede declarar una variable ByteWithSign y asignarle valores Byte y SByte sin
realizar ninguna conversión explícita ni emplear ningún operador de conversión, como se muestra en el ejemplo
siguiente.
NOTE
La finalidad principal de solicitar un método de conversión o un operador de conversión para las conversiones de restricción
es que el desarrollador sea consciente de la posibilidad de que se pierdan datos o de que se produzca una excepción
OverflowException, para que se pueda administrar en el código. Sin embargo, algunos compiladores pueden ser menos
exigentes con este requisito. Por ejemplo, en Visual Basic, si Option Strict está desactivado (la configuración
predeterminada), el compilador de Visual Basic intenta realizar las conversiones de restricción implícitamente.
Por ejemplo, los tipos de datos UInt32, Int64 y UInt64 tienen intervalos que superan el del tipo de datos Int32,
como se muestra en la tabla siguiente.
Para administrar estas conversiones de restricción, .NET Framework permite que los tipos definan un operador
Explicit . A continuación, los compiladores de lenguaje individuales pueden implementar este operador usando
su propia sintaxis o se puede llamar a un miembro de la clase Convert para realizar la conversión. (Para obtener
más información sobre la clase Convert, vea Clase Convert más adelante en este tema). En el ejemplo siguiente se
muestra el uso de las características de lenguaje para administrar la conversión explícita de estos valores enteros,
que potencialmente están fuera del intervalo, a valores Int32.
long number1 = int.MaxValue + 20L;
uint number2 = int.MaxValue - 1000;
ulong number3 = int.MaxValue;
int intNumber;
try {
intNumber = checked((int) number1);
Console.WriteLine("After assigning a {0} value, the Integer value is {1}.",
number1.GetType().Name, intNumber);
}
catch (OverflowException) {
if (number1 > int.MaxValue)
Console.WriteLine("Conversion failed: {0} exceeds {1}.",
number1, int.MaxValue);
else
Console.WriteLine("Conversion failed: {0} is less than {1}.",
number1, int.MinValue);
}
try {
intNumber = checked((int) number2);
Console.WriteLine("After assigning a {0} value, the Integer value is {1}.",
number2.GetType().Name, intNumber);
}
catch (OverflowException) {
Console.WriteLine("Conversion failed: {0} exceeds {1}.",
number2, int.MaxValue);
}
try {
intNumber = checked((int) number3);
Console.WriteLine("After assigning a {0} value, the Integer value is {1}.",
number3.GetType().Name, intNumber);
}
catch (OverflowException) {
Console.WriteLine("Conversion failed: {0} exceeds {1}.",
number1, int.MaxValue);
}
Try
intNumber = CInt(number1)
Console.WriteLine("After assigning a {0} value, the Integer value is {1}.",
number1.GetType().Name, intNumber)
Catch e As OverflowException
If number1 > Integer.MaxValue Then
Console.WriteLine("Conversion failed: {0} exceeds {1}.",
number1, Integer.MaxValue)
Else
Console.WriteLine("Conversion failed: {0} is less than {1}.\n",
number1, Integer.MinValue)
End If
End Try
Try
intNumber = CInt(number2)
Console.WriteLine("After assigning a {0} value, the Integer value is {1}.",
number2.GetType().Name, intNumber)
Catch e As OverflowException
Console.WriteLine("Conversion failed: {0} exceeds {1}.",
number2, Integer.MaxValue)
End Try
Try
intNumber = CInt(number3)
Console.WriteLine("After assigning a {0} value, the Integer value is {1}.",
number3.GetType().Name, intNumber)
Catch e As OverflowException
Console.WriteLine("Conversion failed: {0} exceeds {1}.",
number1, Integer.MaxValue)
End Try
' The example displays the following output:
' Conversion failed: 2147483667 exceeds 2147483647.
' After assigning a UInt32 value, the Integer value is 2147482647.
' After assigning a UInt64 value, the Integer value is 2147483647.
Las conversiones explícitas pueden producir resultados diferentes en los distintos lenguajes y estos resultados
pueden diferir del valor devuelto por el método Convert correspondiente. Por ejemplo, si el valor Double
12.63251 se convierte en Int32, el método CInt de Visual Basic y el método Convert.ToInt32(Double) de .NET
Framework redondean el valor Double para devolver un valor de 13, pero el operador (int) de C# trunca
Double para devolver un valor de 12. De manera similar, el operador (int) de C# no admite la conversión de
booleano a entero, pero el método CInt de Visual Basic convierte un valor de true en -1. Por otra parte, el
método Convert.ToInt32(Boolean) convierte un valor de true en 1.
La mayoría de los compiladores permiten realizar conversiones explícitas de manera comprobada o no
comprobada. Cuando se realiza una conversión comprobada, se produce una excepción OverflowException si el
valor del tipo que se va a convertir está fuera del intervalo del tipo de destino. Si se realiza una conversión no
comprobada en las mismas condiciones, es posible que la conversión no produzca una excepción, pero no se
podrá determinar con exactitud cuál será el comportamiento y se puede obtener como resultado un valor
incorrecto.
NOTE
En C#, las conversiones comprobadas se pueden realizar usando la palabra clave checked junto con un operador de
conversión o especificando la opción del compilador /checked+ . Por el contrario, las conversiones no comprobadas se
pueden realizar utilizando la palabra clave unchecked junto con el operador de conversión de tipo o especificando la opción
del compilador /checked- . De forma predeterminada, las conversiones explícitas no se comprueban. En Visual Basic, para
realizar conversiones comprobadas, se puede desactivar la casilla Quitar comprobaciones de desbordamiento con
enteros en el cuadro de diálogo Configuración de compilador avanzada del proyecto o especificando la opción de
compilador /removeintchecks- . Por el contrario, para realizar conversiones no comprobadas, se puede activar la casilla
Quitar comprobaciones de desbordamiento con enteros en el cuadro de diálogo Configuración de compilador
avanzada del proyecto o especificando la opción de compilador /removeintchecks+ . De forma predeterminada, las
conversiones explícitas se comprueban.
En el siguiente ejemplo de C# se usan las palabras clave checked y unchecked para mostrar la diferencia de
comportamiento cuando un valor que está fuera del intervalo de Byte se convierte en Byte. La conversión
comprobada produce una excepción, pero la conversión no comprobada asigna Byte.MaxValue a la variable Byte.
try {
newValue = unchecked((byte) largeValue);
Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.",
largeValue.GetType().Name, largeValue,
newValue.GetType().Name, newValue);
}
catch (OverflowException) {
Console.WriteLine("{0} is outside the range of the Byte data type.",
largeValue);
}
try {
newValue = checked((byte) largeValue);
Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.",
largeValue.GetType().Name, largeValue,
newValue.GetType().Name, newValue);
}
catch (OverflowException) {
Console.WriteLine("{0} is outside the range of the Byte data type.",
largeValue);
}
// The example displays the following output:
// Converted the Int32 value 2147483647 to the Byte value 255.
// 2147483647 is outside the range of the Byte data type.
ByteWithSign newValue;
newValue.signValue = (SByte) Math.Sign(value);
newValue.value = (byte) Math.Abs(value);
return newValue;
}
ByteWithSign newValue;
newValue.signValue = 1;
newValue.value = (byte) value;
return newValue;
}
newValue.signValue = CSByte(Math.Sign(value))
newValue.value = CByte(Math.Abs(value))
Return newValue
End Operator
newValue.signValue = 1
newValue.value = CByte(value)
Return newValue
End Operator
A continuación, el código de cliente puede declarar una variable ByteWithSign y asignarle valores de tipo Int32 y
UInt32 si las asignaciones incluyen un operador de conversión o un método de conversión, como se muestra en el
ejemplo siguiente.
ByteWithSign value;
try {
int intValue = -120;
value = (ByteWithSign) intValue;
Console.WriteLine(value);
}
catch (OverflowException e) {
Console.WriteLine(e.Message);
}
try {
uint uintValue = 1024;
value = (ByteWithSign) uintValue;
Console.WriteLine(value);
}
catch (OverflowException e) {
Console.WriteLine(e.Message);
}
// The example displays the following output:
// -120
// '1024' is out of range of the ByteWithSign data type.
Try
Dim intValue As Integer = -120
value = CType(intValue, ByteWithSign)
Console.WriteLine(value)
Catch e As OverflowException
Console.WriteLine(e.Message)
End Try
Try
Dim uintValue As UInteger = 1024
value = CType(uintValue, ByteWithSign)
Console.WriteLine(value)
Catch e As OverflowException
Console.WriteLine(e.Message)
End Try
' The example displays the following output:
' -120
' '1024' is out of range of the ByteWithSign data type.
La interfaz IConvertible
Para admitir la conversión de cualquier tipo en un tipo base de Common Language Runtime, .NET Framework
proporciona la interfaz IConvertible. El tipo que se está implementando debe proporcionar lo siguiente:
Un método que devuelva el objeto TypeCode del tipo que se está implementando.
Métodos para convertir el tipo que se está implementando en cada uno de los tipos base de Common
Language Runtime (Boolean, Byte, DateTime, Decimal, Double, etc.).
Un método de conversión generalizado para convertir una instancia del tipo que se está implementando en
otro tipo concreto. Las conversiones que no se admiten deben iniciar una excepción InvalidCastException.
Cada uno de los tipos base de Common Language Runtime (es decir, Boolean, Byte, Char, DateTime, Decimal,
Double, Int16, Int32, Int64, SByte, Single, String, UInt16, UInt32y UInt64), así como los tipos DBNull y Enum,
implementan la interfaz IConvertible. Sin embargo, se trata de implementaciones de interfaz explícitas; solo se
puede llamar al método de conversión mediante una variable de la interfaz IConvertible, como se muestra en el
ejemplo siguiente. Este ejemplo convierte un valor Int32 en su valor Char equivalente.
El requisito de llamar al método de conversión en su interfaz, en lugar de en el tipo que se está implementando,
hace que las implementaciones de interfaz explícitas resulten relativamente costosas. En su lugar, se recomienda
llamar al miembro adecuado de la clase Convert para convertir entre los tipos base de Common Language
Runtime. Para obtener más información, consulte la próxima sección, Clase Convert.
NOTE
Además de la interfaz IConvertible y la clase Convert proporcionadas por .NET Framework, cada lenguaje puede
proporcionar también maneras de realizar conversiones. Por ejemplo, C# utiliza operadores de conversión, mientras que
Visual Basic utiliza funciones de conversión implementadas por el compilador como CType , CInt y DirectCast .
En su mayor parte, la interfaz IConvertible está diseñada para admitir la conversión entre los tipos base de .NET
Framework. Sin embargo, la interfaz también puede implementarse por un tipo personalizado con el fin de
admitir la conversión de ese tipo a otros tipos personalizados. Para obtener más información, consulte la sección
Conversiones personalizadas con el método ChangeType más adelante en este tema.
Clase Convert
Aunque se puede llamar a la implementación de la interfaz IConvertible de cada tipo base para realizar una
conversión de tipo, llamar a los métodos de la clase System.Convert es la manera recomendada de convertir de un
tipo base en otro de una manera independiente del lenguaje. Además, se puede usar el método
Convert.ChangeType(Object, Type, IFormatProvider) para convertir de un tipo personalizado concreto a otro tipo.
Conversiones entre los tipos base
La clase Convert proporciona una manera independiente del lenguaje de realizar conversiones entre los tipos base
y está disponible para todos los lenguajes cuyo destino es Common Language Runtime. Ofrece un conjunto
completo de métodos tanto para conversiones de ampliación como de restricción e inicia una excepción
InvalidCastException para las conversiones que no se admiten (como la conversión de un valor DateTime a un
valor entero). Las conversiones de restricción se realizan en un contexto comprobado y se inicia una excepción
OverflowException si se produce un error en la conversión.
IMPORTANT
Puesto que la clase Convert incluye métodos para efectuar la conversión directa e inversa de cada tipo base, elimina la
necesidad de llamar a la implementación de interfaz explícita IConvertible de cada tipo base.
En el ejemplo siguiente se muestra el uso de la clase System.Convert para realizar varias conversiones de
restricción y ampliación entre los tipos base de .NET Framework.
// Convert an Int32 value to a Decimal (a widening conversion).
int integralValue = 12534;
decimal decimalValue = Convert.ToDecimal(integralValue);
Console.WriteLine("Converted the {0} value {1} to " +
"the {2} value {3:N2}.",
integralValue.GetType().Name,
integralValue,
decimalValue.GetType().Name,
decimalValue);
// Convert a Byte value to an Int32 value (a widening conversion).
byte byteValue = Byte.MaxValue;
int integralValue2 = Convert.ToInt32(byteValue);
Console.WriteLine("Converted the {0} value {1} to " +
"the {2} value {3:G}.",
byteValue.GetType().Name,
byteValue,
integralValue2.GetType().Name,
integralValue2);
En algunos casos, en especial al efectuar conversiones directas e inversas de valores de punto flotante, una
conversión puede conllevar una pérdida de precisión, aunque no se inicie una excepción OverflowException. En el
ejemplo siguiente se muestra esta pérdida de precisión. En el primer caso, un valor Decimal tiene menos precisión
(menos dígitos significativos) cuando se convierte en el tipo Double. En el segundo caso, un valor Double se
redondea de 42,72 a 43 para completar la conversión.
double doubleValue;
doubleValue = 42.72;
try {
int integerValue = Convert.ToInt32(doubleValue);
Console.WriteLine("{0} converted to {1}.",
doubleValue, integerValue);
}
catch (OverflowException) {
Console.WriteLine("Unable to convert {0} to an integer.",
doubleValue);
}
// The example displays the following output:
// 13956810.96702888123451471211 converted to 13956810.9670289.
// 42.72 converted to 43.
doubleValue = 42.72
Try
Dim integerValue As Integer = Convert.ToInt32(doubleValue)
Console.WriteLine("{0} converted to {1}.",
doubleValue, integerValue)
Catch e As OverflowException
Console.WriteLine("Unable to convert {0} to an integer.",
doubleValue)
End Try
' The example displays the following output:
' 13956810.96702888123451471211 converted to 13956810.9670289.
' 42.72 converted to 43.
Para obtener una tabla en la que se muestra una lista de conversiones de restricción y ampliación admitidas por la
clase Convert, vea Tablas de conversiones de tipos.
Conversiones personalizadas con el método ChangeType
Además de admitir las conversiones en cada uno de los tipos base, la clase Convert se puede usar para convertir
un tipo personalizado en uno o varios tipos predefinidos. El método Convert.ChangeType(Object, Type,
IFormatProvider), que a su vez contiene una llamada al método IConvertible.ToType del parámetro value , realiza
esta conversión. Esto significa que el objeto representado por el parámetro value debe proporcionar una
implementación de la interfaz IConvertible.
NOTE
Dado que los métodos Convert.ChangeType(Object, Type) y Convert.ChangeType(Object, Type, IFormatProvider) utilizan un
objeto Type para especificar el tipo de destino al que se convierte value , se pueden utilizar para realizar una conversión
dinámica a un objeto cuyo tipo se desconoce en tiempo de compilación. Sin embargo, observe que la implementación de
IConvertible de value aún debe admitir esta conversión.
En el ejemplo siguiente se muestra una posible implementación de la interfaz IConvertible que permite convertir
un objeto TemperatureCelsius en un objeto TemperatureFahrenheit y viceversa. En el ejemplo se define una clase
base, Temperature , que implementa la interfaz IConvertible e invalida el método Object.ToString. Cada una de las
clases derivadas TemperatureCelsius y TemperatureFahrenheit invalida los métodos ToType y ToString de la
clase base.
using System;
// IConvertible implementations.
public TypeCode GetTypeCode() {
return TypeCode.Object;
}
En el ejemplo siguiente se muestran varias llamadas a estas implementaciones de IConvertible para convertir los
objetos TemperatureCelsius en objetos TemperatureFahrenheit y viceversa.
TemperatureCelsius tempC1 = new TemperatureCelsius(0);
TemperatureFahrenheit tempF1 = (TemperatureFahrenheit) Convert.ChangeType(tempC1,
typeof(TemperatureFahrenheit), null);
Console.WriteLine("{0} equals {1}.", tempC1, tempF1);
TemperatureCelsius tempC2 = (TemperatureCelsius) Convert.ChangeType(tempC1, typeof(TemperatureCelsius), null);
Console.WriteLine("{0} equals {1}.", tempC1, tempC2);
TemperatureFahrenheit tempF2 = new TemperatureFahrenheit(212);
TemperatureCelsius tempC3 = (TemperatureCelsius) Convert.ChangeType(tempF2, typeof(TemperatureCelsius), null);
Console.WriteLine("{0} equals {1}.", tempF2, tempC3);
TemperatureFahrenheit tempF3 = (TemperatureFahrenheit) Convert.ChangeType(tempF2,
typeof(TemperatureFahrenheit), null);
Console.WriteLine("{0} equals {1}.", tempF2, tempF3);
// The example displays the following output:
// 0°C equals 32°F.
// 0°C equals 0°C.
// 212°F equals 100°C.
// 212°F equals 212°F.
Clase TypeConverter
.NET Framework también permite definir un convertidor de tipos para un tipo personalizado extendiendo la clase
System.ComponentModel.TypeConverter y asociando el convertidor de tipos al tipo mediante un atributo
System.ComponentModel.TypeConverterAttribute. En la tabla siguiente se resaltan las diferencias entre este
enfoque y la implementación de la interfaz IConvertible para un tipo personalizado.
NOTE
Se puede proporcionar compatibilidad en tiempo de diseño para un tipo personalizado sólo si se ha definido un convertidor
de tipos para éste.
Se implementa para un tipo personalizado derivando una Se implementa mediante un tipo personalizado para realizar la
clase independiente de TypeConverter. Esta clase derivada se conversión. Un usuario del tipo invoca un método de
asocia al tipo personalizado aplicando un atributo conversión de IConvertible para el tipo.
TypeConverterAttribute.
CONVERSIÓN MEDIANTE TYPECONVERTER CONVERSIÓN MEDIANTE ICONVERTIBLE
Se puede utilizar en tiempo de diseño y en tiempo de Sólo se puede utilizar en tiempo de ejecución.
ejecución.
Usa la reflexión; por tanto, es más lenta que la conversión No utiliza la reflexión.
mediante IConvertible.
Permite realizar conversiones bidireccionales; es decir, Permite convertir un tipo personalizado en otros tipos de
convertir el tipo personalizado en otros tipos de datos y datos, pero no otros tipos de datos en el tipo personalizado.
convertir otros tipos de datos en el tipo personalizado. Por
ejemplo, un objeto TypeConverter definido para MyType
permite conversiones de MyType a String y de String a
MyType .
Para obtener más información sobre cómo usar convertidores de tipos para realizar conversiones, vea
System.ComponentModel.TypeConverter.
Vea también
System.Convert
IConvertible
Tablas de conversión de tipos
Tablas de conversión de tipos en .NET
04/11/2019 • 3 minutes to read • Edit Online
Una conversión de ampliación se produce cuando se convierte un valor de un tipo a otro tipo que es de igual o
mayor tamaño. Una conversión de restricción se produce cuando se convierte un valor de un tipo a otro tipo que
es de un tamaño menor. En las tablas de este tema se muestran los comportamientos de ambos tipos de
conversiones.
conversiones de ampliación
En la tabla siguiente se describen las conversiones de ampliación que pueden realizarse sin pérdida de
información.
Int64 Decimal
UInt64 Decimal
Single Double
Algunas conversiones de ampliación a Single o Double pueden provocar una pérdida de precisión. En la tabla
siguiente se describen las conversiones de ampliación que a veces se traducen en una pérdida de información.
Int32 Single
UInt32 Single
conversiones de restricción
Una conversión de restricción a Single o Double puede provocar una pérdida de información. Si el tipo de destino
no puede expresar correctamente la magnitud del origen, el tipo resultante se establece en la constante
PositiveInfinity o NegativeInfinity . PositiveInfinity resulta al dividir un número positivo por cero y también
se devuelve cuando el valor de Single o Double supera el valor del campo MaxValue . NegativeInfinity resulta al
dividir un número negativo por cero y también se devuelve cuando el valor de Single o Double cae por debajo del
valor del campo MinValue . Una conversión de Double a Single podría dar lugar a PositiveInfinity o
NegativeInfinity .
Una conversión de restricción también puede traducirse en una pérdida de información para otros tipos de datos.
Pero se inicia OverflowException si el valor de un tipo que se va a convertir está fuera del intervalo especificado
por los campos MaxValue y MinValue del tipo de destino y el tiempo de ejecución comprueba la conversión para
asegurarse de que el valor del tipo de destino no supera su MaxValue o MinValue . Las conversiones que se
realizan con la clase System.Convert siempre se comprueban de esta manera.
En la tabla siguiente se enumeran las conversiones que inician OverflowException con System.Convert o cualquier
conversión comprobada si el valor del tipo que se va a convertir está fuera del intervalo definido del tipo
resultante.
Byte SByte
Vea también
System.Convert
Conversión de tipos en .NET
Tipos de formato en .NET
22/01/2020 • 62 minutes to read • Edit Online
Aplicar formato es el proceso de convertir una instancia de una clase, una estructura o un valor de enumeración
en su representación de cadena, a menudo para que la cadena resultante se pueda mostrar a los usuarios o
deserializar para restaurar el tipo de datos original. Esta conversión puede plantear varios desafíos:
La forma en que se almacenan internamente los valores no refleja necesariamente la manera en que los
usuarios desean verlos. Por ejemplo, un número de teléfono podría almacenarse con el formato
8009999999, que no es fácil de usar. Se debería mostrar en su lugar como 800-999-9999. Consulte la
sección Cadenas de formato personalizado para obtener un ejemplo en el que da formato a un número
de esta forma.
A veces, la conversión de un objeto en su representación de cadena no es intuitiva. Por ejemplo, no está
claro cómo debe aparecer la representación de cadena de un objeto Temperature o un objeto Person.
Para obtener un ejemplo en el que se da formato a un objeto Temperature de varias formas, consulte la
sección Cadenas de formato estándar .
A menudo, los valores requieren un formato dependiente de la referencia cultural. Por ejemplo, en una
aplicación en la que se usan números para reflejar los valores monetarios, las cadenas numéricas deben
incluir el símbolo de divisa, el separador de grupo (que en la mayoría de las referencias culturales es el
separador de miles) y el símbolo decimal correspondientes a la referencia cultural actual. Para ver un
ejemplo, consulte la sección Formato según la referencia cultural con proveedores de formato.
Puede que una aplicación muestre el mismo valor de diferentes maneras. Por ejemplo, es posible que
una aplicación represente un miembro de enumeración mostrando una representación de cadena de su
nombre o mostrando su valor subyacente. Para obtener un ejemplo en el que se da formato a un
miembro de la enumeración DayOfWeek de maneras diferentes, consulte la sección Cadenas de formato
estándar .
NOTE
La aplicación de formato convierte el valor de un tipo en una representación de cadena. El análisis es lo contrario que la
aplicación de formato. Una operación de análisis crea una instancia de un tipo de datos a partir de su representación de
cadena. Para información sobre cómo convertir cadenas en otros tipos de datos, vea Analizar cadenas en .NET.
.NET proporciona compatibilidad de formato enriquecida que permite a los desarrolladores hacer frente a estos
requisitos.
Formato en .NET
El mecanismo básico para aplicar formato es la implementación predeterminada del método Object.ToString,
que se explica en la sección Formato predeterminado mediante el método ToString más adelante en este tema.
Pero .NET proporciona varias formas de modificar y extender su compatibilidad de formato predeterminado.
Entre ellas se incluyen las siguientes:
Invalidar el método Object.ToString para definir una representación de cadena personalizada del valor de
un objeto. Para obtener más información, consulte la sección Invalidación del método ToString más
adelante en este tema.
Definir especificadores de formato que permitan que la representación de cadena del valor de un objeto
adopte varios formatos. Por ejemplo, el especificador de formato "X" en la siguiente instrucción convierte
un entero en la representación de cadena de un valor hexadecimal.
Para obtener más información sobre los especificadores de formato, vea la sección Método ToString y
cadenas de formato .
Usar proveedores de formato para aprovechar las convenciones de formato de una referencia cultural
concreta. Por ejemplo, la instrucción siguiente muestra un valor de divisa usando las convenciones de
formato de la referencia cultural en-US.
Para obtener más información sobre cómo aplicar formato con proveedores de formato, consulte la
sección Proveedores de formato.
Implementar la interfaz IFormattable para admitir tanto la conversión de cadenas con la clase Convert
como formatos compuestos. Para obtener más información, vea la sección Interfaz IFormattable .
Usar formatos compuestos para incrustar la representación de cadena de un valor en una cadena más
larga. Para obtener más información, vea la sección Formatos compuestos .
Implementar ICustomFormatter y IFormatProvider para proporcionar una solución de formato
personalizado completa. Para obtener más información, vea la sección Formato personalizado con
ICustomFormatter .
En las secciones siguientes se examinan estos métodos para convertir un objeto en su representación de
cadena.
Module Example
Public Sub Main()
Dim firstAuto As New Automobile()
Console.WriteLine(firstAuto)
End Sub
End Module
' The example displays the following output:
' Automobile
WARNING
A partir de Windows 8.1, Windows Runtime incluye una interfaz IStringable con un solo método, IStringable.ToString, que
ofrece compatibilidad con el formato predeterminado. Sin embargo, es recomendable que los tipos administrados no
implementen la interfaz IStringable . Para obtener más información, vea la sección "Windows Runtime y la interfaz
IStringable " de la página de referencia Object.ToString.
Puesto que todos los tipos distintos de las interfaces se derivan de Object, esta funcionalidad se proporciona
automáticamente a sus clases o estructuras personalizadas. Si bien, la funcionalidad que ofrece el método
ToString predeterminado es limitada: Aunque identifica el tipo, no proporciona ninguna información sobre una
instancia del tipo. Para proporcionar una representación de cadena de un objeto que proporciona información
sobre ese objeto, debe invalidar el método ToString .
NOTE
Las estructuras heredan de ValueType, que a su vez se deriva de Object. Aunque ValueType invalida Object.ToString, su
implementación es idéntica.
Module Example
Public Sub Main()
Dim currentTemperature As New Temperature(23.6d)
Console.WriteLine("The current temperature is " +
currentTemperature.ToString())
End Sub
End Module
' The example displays the following output:
' The current temperature is 23.6°C.
En .NET, el método ToString de cada tipo de valor primitivo se ha invalidado para que se muestre el valor del
objeto en lugar de su nombre. En la tabla siguiente se muestra la invalidación para cada tipo primitivo. Observe
que la mayoría de los métodos invalidados llaman a otra sobrecarga del método ToString y le pasan el
especificador de formato "G", que define el formato general de su tipo, y un objeto IFormatProvider que
representa la referencia cultural actual.
Byte Llama a
Byte.ToString("G", NumberFormatInfo.CurrentInfo)
para dar formato al valor de tipo Byte correspondiente a la
referencia cultural actual.
DateTime Llama a
DateTime.ToString("G",
DatetimeFormatInfo.CurrentInfo)
para dar formato al valor de fecha y hora correspondiente a
la referencia cultural actual.
Decimal Llama a
Decimal.ToString("G", NumberFormatInfo.CurrentInfo)
para dar formato al valor de tipo Decimal correspondiente a
la referencia cultural actual.
Double Llama a
Double.ToString("G", NumberFormatInfo.CurrentInfo)
para dar formato al valor de tipo Double correspondiente a
la referencia cultural actual.
Int16 Llama a
Int16.ToString("G", NumberFormatInfo.CurrentInfo)
para dar formato al valor de tipo Int16 correspondiente a la
referencia cultural actual.
Int32 Llama a
Int32.ToString("G", NumberFormatInfo.CurrentInfo)
para dar formato al valor de tipo Int32 correspondiente a la
referencia cultural actual.
Int64 Llama a
Int64.ToString("G", NumberFormatInfo.CurrentInfo)
para dar formato al valor de tipo Int64 correspondiente a la
referencia cultural actual.
SByte Llama a
SByte.ToString("G", NumberFormatInfo.CurrentInfo)
para dar formato al valor de tipo SByte correspondiente a la
referencia cultural actual.
Single Llama a
Single.ToString("G", NumberFormatInfo.CurrentInfo)
para dar formato al valor de tipo Single correspondiente a la
referencia cultural actual.
UInt16 Llama a
UInt16.ToString("G", NumberFormatInfo.CurrentInfo)
para dar formato al valor de tipo UInt16 correspondiente a
la referencia cultural actual.
TIPO INVALIDACIÓN DE TOSTRING
UInt32 Llama a
UInt32.ToString("G", NumberFormatInfo.CurrentInfo)
para dar formato al valor de tipo UInt32 correspondiente a
la referencia cultural actual.
UInt64 Llama a
UInt64.ToString("G", NumberFormatInfo.CurrentInfo)
para dar formato al valor de tipo UInt64 correspondiente a
la referencia cultural actual.
Para información sobre las cadenas de formato de enumeración, vea Enumeration Format Strings.
Las cadenas de formato estándar para tipos numéricos normalmente definen una cadena de resultado cuya
apariencia exacta está controlada por uno o más valores de propiedad. Por ejemplo, el especificador de formato
"C" da formato a un número como un valor de divisa. Al llamar al método ToString con el especificador de
formato "C" como único parámetro, se usan los siguientes valores de propiedad del objeto NumberFormatInfo
de la referencia cultural actual para definir la representación de cadena del valor numérico:
La propiedad CurrencySymbol , que especifica el símbolo de divisa de la referencia cultural actual.
La propiedad CurrencyNegativePattern o CurrencyPositivePattern , que devuelve un entero que
determina lo siguiente:
La posición del símbolo de divisa.
Si los valores negativos se indican mediante un signo negativo inicial, un signo negativo final o
paréntesis.
Si aparece un espacio entre el valor numérico y el símbolo de divisa.
La propiedad CurrencyDecimalDigits , que define el número de dígitos fraccionarios en la cadena de
resultado.
La propiedad CurrencyDecimalSeparator , que define el símbolo del separador decimal en la cadena de
resultado.
La propiedad CurrencyGroupSeparator , que define el símbolo del separador de grupo.
La propiedad CurrencyGroupSizes , que define el número de dígitos de cada grupo que hay a la
izquierda del decimal.
La propiedad NegativeSign , que determina el signo negativo usado en la cadena de resultado si no se
emplean paréntesis para indicar valores negativos.
Además, las cadenas de formato numérico pueden incluir un especificador de precisión. El significado de este
especificador depende de la cadena de formato con la que se usa, pero suele indicar el número total de dígitos o
el número de dígitos fraccionarios que deben aparecer en la cadena de resultado. Por ejemplo, en el ejemplo
siguiente se usa la cadena numérica estándar "X4" y un especificador de precisión para crear un valor de cadena
que tiene cuatro dígitos hexadecimales.
Para más información sobre las cadenas de formato numérico estándar, vea Standard Numeric Format Strings.
Las cadenas de formato estándar para valores de fecha y hora son alias de las cadenas de formato
personalizado almacenadas por una propiedad DateTimeFormatInfo determinada. Por ejemplo, al llamar al
método ToString de un valor de fecha y hora con el especificador de formato "D" se muestran la fecha y la
hora usando la cadena de formato personalizado que está almacenada en la propiedad
DateTimeFormatInfo.LongDatePattern de la referencia cultural actual. (Para obtener más información sobre las
cadenas de formato personalizado, vea la próxima sección). En el ejemplo siguiente se ilustra esta relación.
using System;
using System.Globalization;
Module Example
Public Sub Main()
Dim date1 As Date = #6/30/2009#
Console.WriteLine("D Format Specifier: {0:D}", date1)
Dim longPattern As String = CultureInfo.CurrentCulture.DateTimeFormat.LongDatePattern
Console.WriteLine("'{0}' custom format string: {1}", _
longPattern, date1.ToString(longPattern))
End Sub
End Module
' The example displays the following output when run on a system whose
' current culture is en-US:
' D Format Specifier: Tuesday, June 30, 2009
' 'dddd, MMMM dd, yyyy' custom format string: Tuesday, June 30, 2009
Para más información sobre las cadenas de formato de fecha y hora estándar, vea Standard Date and Time
Format Strings.
También se pueden emplear las cadenas de formato estándar para definir la representación de cadena de un
objeto definido por la aplicación generado por el método ToString(String) del objeto. Puede definir los
especificadores de formato estándar concretos que su objeto admite y determinar si distinguen entre
mayúsculas y minúsculas o no. Su implementación del método ToString(String) debe aceptar lo siguiente:
Un especificador de formato "G" que representa un formato personalizado o común del objeto. La
sobrecarga sin parámetros del método ToString del objeto debe llamar a su sobrecarga de
ToString(String) y pasarle la cadena de formato estándar "G".
Compatibilidad con un especificador de formato que sea igual a una referencia nula ( Nothing en Visual
Basic). Un especificador de formato que es igual a una referencia nula debe considerarse equivalente al
especificador de formato "G".
Por ejemplo, una clase Temperature puede almacenar internamente la temperatura en grados centígrados y
usar especificadores de formato para representar el valor del objeto Temperature en grados centígrados, grados
Fahrenheit y grados Kelvin. Esto se muestra en el ejemplo siguiente.
using System;
Muchas cadenas de formato estándar para valores de fecha y hora son alias para cadenas de formato
personalizado definidas por propiedades del objeto DateTimeFormatInfo . Las cadenas de formato
personalizado también ofrecen una gran flexibilidad a la hora de proporcionar formatos definidos por la
aplicación para los valores numéricos o de fecha y hora. Puede definir sus propias cadenas de resultado
personalizadas para los valores numéricos y de fecha y hora si combina varios especificadores de formato
personalizados en una única cadena de formato personalizado. En el ejemplo siguiente se define una cadena de
formato personalizado que muestra el día de la semana entre paréntesis después del nombre de mes, el día y el
año.
En el ejemplo siguiente se define una cadena de formato personalizado que muestra un valor de Int64 como un
número de teléfono de Estados Unidos estándar de siete dígitos con el código de área.
using System;
Module Example
Public Sub Main()
Dim number As Long = 8009999999
Dim fmt As String = "000-000-0000"
Console.WriteLine(number.ToString(fmt))
End Sub
End Module
' The example displays the following output:
Aunque las cadenas de formato estándar pueden satisfacer generalmente la mayoría de las necesidades de
formato para los tipos definidos por la aplicación, también puede definir especificadores de formato
personalizados para dar formato a sus tipos.
Cadenas de formato y tipos de .NET
Todos los tipos numéricos (es decir, los tipos Byte, Decimal, Double, Int16, Int32, Int64, SByte, Single, UInt16,
UInt32, UInt64 y BigInteger), así como DateTime, DateTimeOffset, TimeSpan, Guidy todos los tipos de
enumeración, son compatibles con el formato con cadenas de formato. Para obtener información sobre las
cadenas de formato específicas que admite cada tipo, consulte los temas siguientes:
TITLE DEFINICIÓN
Standard Numeric Format Strings Describe cadenas de formato estándar que crean
representaciones de cadena usadas con frecuencia de valores
numéricos.
Custom Numeric Format Strings Describe cadenas de formato personalizado que crean
formatos específicos de la aplicación para valores numéricos.
Standard Date and Time Format Strings Describe cadenas de formato estándar que crean
representaciones de cadena usadas con frecuencia de valores
DateTime y DateTimeOffset.
Custom Date and Time Format Strings Describe cadenas de formato personalizado que crean
formatos específicos de la aplicación para valores DateTime y
DateTimeOffset.
Cadenas de formato TimeSpan estándar Describe cadenas de formato estándar que crean
representaciones de cadena usadas con frecuencia de
intervalos de tiempo.
Cadenas de formato TimeSpan personalizado Describe cadenas de formato personalizado que crean
formatos específicos de la aplicación para intervalos de
tiempo.
Enumeration Format Strings Describe cadenas de formato estándar que se usan para
crear representaciones de cadena de valores de
enumeración.
Imports System.Globalization
La interfaz IFormatProvider incluye un método, GetFormat(Type), que tiene un único parámetro que especifica
el tipo de objeto que proporciona información de formato. Si el método puede proporcionar un objeto de ese
tipo, lo devuelve. De lo contrario, devuelve una referencia nula ( Nothing en Visual Basic).
IFormatProvider.GetFormat es un método de devolución de llamada. Al llamar a una sobrecarga del método
ToString que incluye un parámetro de IFormatProvider , se llama al método GetFormat de ese objeto
IFormatProvider . El método GetFormat devuelve un objeto que proporciona al método formatType la
información de formato necesaria especificada por su parámetro ToString .
Varios métodos de formato o de conversión de cadenas incluyen un parámetro de tipo IFormatProviderpero, en
muchos casos, se omite el valor del parámetro cuando se llama al método. En la tabla siguiente se muestran
algunos métodos de formato que usan el parámetro y el tipo del objeto Type que pasan al método
IFormatProvider.GetFormat .
String.Format System.ICustomFormatter
StringBuilder.AppendFormat System.ICustomFormatter
NOTE
Los métodos ToString de los tipos numéricos y los tipos de fecha y hora se sobrecargan y solo algunas de las
sobrecargas incluyen un parámetro IFormatProvider . Si un método no tiene un parámetro de tipo IFormatProvider, se
pasa en su lugar el objeto devuelto por la propiedad CultureInfo.CurrentCulture . Por ejemplo, una llamada al método
Int32.ToString() predeterminado resultará finalmente en una llamada similar a esta:
Int32.ToString("G", System.Globalization.CultureInfo.CurrentCulture) .
Imports System.Globalization
Imports System.Threading
Module Example
Public Sub Main()
Dim cultureNames() As String = { "en-US", "fr-FR", "es-MX", "de-DE" }
Dim value As Decimal = 1043.17d
using System;
using System.Globalization;
Imports System.Globalization
Module Example
Public Sub Main()
Dim value As Double = 1043.62957
Dim cultureNames() As String = { "en-US", "en-GB", "ru", "fr" }
Formato que tiene en cuenta las referencias culturales de valores de fecha y hora
De forma predeterminada, el formato de los valores de fecha y hora tiene en cuenta las referencias culturales. Si
no especifica una referencia cultural cuando llama a un método de formato, se utilizan las convenciones de
formato de la referencia cultural del subproceso actual. Esto se muestra en el ejemplo siguiente, que cambia la
referencia cultural del subproceso actual cuatro veces y después llama al método DateTime.ToString(String) . En
cada caso, la cadena resultante refleja las convenciones de formato de la referencia cultural actual. Esto se debe
a que los métodos DateTime.ToString(), DateTime.ToString(String), DateTimeOffset.ToString()y
DateTimeOffset.ToString(String) encapsulan llamadas a los métodos DateTime.ToString(String,
IFormatProvider) y DateTimeOffset.ToString(String, IFormatProvider) .
using System;
using System.Globalization;
using System.Threading;
Module Example
Public Sub Main()
Dim cultureNames() As String = { "en-US", "fr-FR", "es-MX", "de-DE" }
Dim dateToFormat As Date = #5/28/2012 11:30AM#
También se puede dar formato a un valor de fecha y hora para una referencia cultural concreta llamando a una
sobrecarga de DateTime.ToString o DateTimeOffset.ToString que tenga un parámetro provider y pasándole
uno de los elementos siguientes:
Un objeto CultureInfo que representa la referencia cultural cuyas convenciones de formato se van a usar.
Su método CultureInfo.GetFormat devuelve el valor de la propiedad CultureInfo.DateTimeFormat , que
es el objeto DateTimeFormatInfo que proporciona información sobre el formato de una referencia
cultural específica para valores de fecha y hora.
Un objeto DateTimeFormatInfo que define las convenciones de formato de la referencia cultural que se
van a usar. Su método GetFormat devuelve una instancia de sí mismo.
En el siguiente ejemplo se utilizan objetos DateTimeFormatInfo que representan las referencias culturales de
inglés (Estados Unidos) e inglés (Reino Unido), y las referencias culturales neutras de francés y ruso para dar
formato a una fecha.
using System;
using System.Globalization;
Imports System.Globalization
Module Example
Public Sub Main()
Dim dat1 As Date = #5/28/2012 11:30AM#
Dim cultureNames() As String = { "en-US", "en-GB", "ru", "fr" }
Interfaz IFormattable
Normalmente, los tipos que sobrecargan el método ToString con una cadena de formato y un parámetro
IFormatProvider también implementan la interfaz IFormattable . Esta interfaz tiene un solo miembro,
IFormattable.ToString(String, IFormatProvider), que incluye una cadena de formato y un proveedor de formato
como parámetros.
La implementación de la interfaz IFormattable para su clase definida por la aplicación ofrece dos ventajas:
Compatibilidad con la conversión de cadenas por la clase Convert . Las llamadas a los métodos
Convert.ToString(Object) y Convert.ToString(Object, IFormatProvider) llaman automáticamente a su
implementación de IFormattable .
Compatibilidad con formatos compuestos. Si se usa un elemento de formato que incluye una cadena de
formato para dar formato a su tipo personalizado, Common Language Runtime llama automáticamente
a su implementación de IFormattable y le pasa la cadena de formato. Para obtener más información
sobre los formatos compuestos con métodos como String.Format o Console.WriteLine, vea la sección
Formatos compuestos .
En el ejemplo siguiente se define una clase Temperature que implementa la interfaz IFormattable . Admite los
especificadores de formato "C" o "G" para mostrar la temperatura en grados centígrados, el especificador de
formato "F" para mostrar la temperatura en grados Fahrenheit y el especificador de formato "K" para mostrar la
temperatura en grados Kelvin.
using System;
using System.Globalization;
if (provider == null)
provider = NumberFormatInfo.CurrentInfo;
switch (format)
{
// Convert temperature to Fahrenheit and return string.
case "F":
return this.Fahrenheit.ToString("N2", provider) + "°F";
// Convert temperature to Kelvin and return string.
case "K":
return this.Kelvin.ToString("N2", provider) + "K";
// Return temperature in Celsius.
case "C":
case "G":
return this.Celsius.ToString("N2", provider) + "°C";
default:
throw new FormatException(String.Format("The '{0}' format string is not supported.", format));
}
}
}
Imports System.Globalization
En el ejemplo siguiente se crea una instancia de un objeto Temperature . A continuación, llama al método
ToString y usa varias cadenas de formato compuesto para obtener representaciones de cadena diferentes de un
objeto Temperature . Cada una de estas llamadas al método, a su vez, llama a la implementación de
IFormattable de la clase Temperature .
public class Example
{
public static void Main()
{
CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
Temperature temp = new Temperature(22m);
Console.WriteLine(Convert.ToString(temp, new CultureInfo("ja-JP")));
Console.WriteLine("Temperature: {0:K}", temp);
Console.WriteLine("Temperature: {0:F}", temp);
Console.WriteLine(String.Format(new CultureInfo("fr-FR"), "Temperature: {0:F}", temp));
}
}
// The example displays the following output:
// 22.00°C
// Temperature: 295.15K
// Temperature: 71.60°F
// Temperature: 71,60°F
Formatos compuestos
Algunos métodos, como String.Format y StringBuilder.AppendFormat, admiten formatos compuestos. Una
cadena de formato compuesto es un tipo de plantilla que devuelve una sola cadena que incorpora la
representación de cadena de cero, uno o más objetos. Cada objeto se representa en la cadena de formato
compuesto mediante un elemento de formato indizado. El índice del elemento de formato corresponde a la
posición del objeto que representa en la lista de parámetros del método. Los índices son de base cero. Por
ejemplo, en la siguiente llamada al método String.Format , el primer elemento de formato, {0:D} se reemplaza
con la representación de cadena de thatDate ; el segundo elemento de formato, {1} , se reemplaza con la
representación de cadena de item1 y el tercer elemento de formato, {2:C2} , se reemplaza con la
representación de cadena de item1.Value .
Tenga en cuenta que, si están presentes tanto el componente de cadena de alineación como el
componente de cadena de formato, el primero precede al último (por ejemplo, {0,-20:g} ).
Para más información sobre los formatos compuestos, vea Formatos compuestos.
byte[] bytes;
string output = null;
return output.Trim();
}
}
Public Class ByteByByteFormatter : Implements IFormatProvider, ICustomFormatter
Public Function GetFormat(formatType As Type) As Object _
Implements IFormatProvider.GetFormat
If formatType Is GetType(ICustomFormatter) Then
Return Me
Else
Return Nothing
End If
End Function
Return output.Trim()
End Function
End Class
En el ejemplo siguiente se usa la clase ByteByByteFormatter para dar formato a valores enteros. Observe que en
el ejemplo no se llama explícitamente al método ICustomFormatter.Format más de una vez en la segunda
llamada al método String.Format(IFormatProvider, String, Object[]) y que el proveedor NumberFormatInfo
predeterminado se usa en la tercera llamada al método porque el método ByteByByteFormatter.Format no
reconoce la cadena de formato "N0" y devuelve una referencia nula ( Nothing en Visual Basic).
public class Example
{
public static void Main()
{
long value = 3210662321;
byte value1 = 214;
byte value2 = 19;
Temas relacionados
TITLE DEFINICIÓN
Standard Numeric Format Strings Describe cadenas de formato estándar que crean
representaciones de cadena usadas con frecuencia de valores
numéricos.
Custom Numeric Format Strings Describe cadenas de formato personalizado que crean
formatos específicos de la aplicación para valores numéricos.
Standard Date and Time Format Strings Describe cadenas de formato estándar que crean
representaciones de cadena usadas con frecuencia de valores
DateTime .
Custom Date and Time Format Strings Describe cadenas de formato personalizado que crean
formatos específicos de la aplicación para valores DateTime .
Cadenas de formato TimeSpan estándar Describe cadenas de formato estándar que crean
representaciones de cadena usadas con frecuencia de
intervalos de tiempo.
TITLE DEFINICIÓN
Cadenas de formato TimeSpan personalizado Describe cadenas de formato personalizado que crean
formatos específicos de la aplicación para intervalos de
tiempo.
Enumeration Format Strings Describe cadenas de formato estándar que se usan para
crear representaciones de cadena de valores de
enumeración.
Formatos compuestos Describe cómo incrustar uno o más valores con formato en
una cadena. Posteriormente se puede mostrar la cadena en
la consola o escrita en una secuencia.
Efectuar operaciones de formato Muestra los temas en los que se proporcionan instrucciones
paso a paso para realizar operaciones de formato concretas.
Analizar cadenas en .NET Describe cómo inicializar objetos en los valores descritos por
representaciones de cadena de dichos objetos. El análisis es
la operación inversa de la aplicación de formato.
Referencia
System.IFormattable
System.IFormatProvider
System.ICustomFormatter
Cadenas con formato numérico estándar
13/01/2020 • 48 minutes to read • Edit Online
Las cadenas de formato numérico estándar se utilizan para dar formato a tipos numéricos comunes. La forma de
una cadena de formato numérico estándar es Axx , donde:
A es un carácter alfabético único denominado especificador de formato. Cualquier cadena de formato
numérico que contenga más de un carácter alfabético, incluido el espacio en blanco, se interpreta como
una cadena de formato numérico personalizado. Para obtener más información, consulte Cadenas con
formato numérico personalizado.
xx es un entero opcional denominado especificador de precisión. El especificador de precisión está
comprendido entre el 0 y el 99 y afecta al número de dígitos del resultado. Observe que el especificador
de precisión controla el número de dígitos en la representación de cadena de un número. No redondea el
número en sí. Para realizar una operación de redondeo, use el método Math.Ceiling, Math.Floor o
Math.Round.
Cuando el especificador de precisión controla el número de dígitos fraccionarios de la cadena de
resultado, esta refleja un número redondeado al resultado representable más cercano al resultado de
precisión infinita. En el caso de que haya dos resultados representables igualmente cercanos:
En .NET Framework y .NET Core (hasta la versión 2.0) , el runtime selecciona el resultado con el
dígito menos significativo más elevado (es decir, usando MidpointRounding.AwayFromZero).
En .NET Core 2.1 y versiones posteriores, el runtime selecciona el resultado con un dígito menos
significativo par (es decir, usando MidpointRounding.ToEven).
NOTE
El especificador de precisión determina el número de dígitos de la cadena de resultado. Para rellenar una cadena de
resultado con espacios iniciales o finales, use la característica formatos compuestos y defina un componente de
alineación en el elemento de formato.
En la tabla siguiente se describen los especificadores de formato numérico estándar y se muestran los resultados
de ejemplo generados por cada especificador de formato. Consulte la sección Notas para obtener información
adicional sobre cómo usar las cadenas con formato numérico estándar y la sección Ejemplo para ver una
ilustración completa de su uso.
"D" o "d" Decimal Resultado: dígitos enteros 1234 ("D") -> 1234
con signo negativo
opcional. -1234 ("D6") -> -001234
Especificador de precisión:
número mínimo de dígitos.
Especificador de precisión
predeterminado: número
mínimo de dígitos
necesario.
Más información:
Especificador de formato
decimal ("D").
ESPECIFICADOR DE FORMATO NOMBRE DESCRIPCIÓN EJEMPLOS
Más información:
Especificador de formato
exponencial ("E").
"F" o "f" Punto fijo Resultado: dígitos integrales 1234.567 ("F", en-US) ->
y decimales con signo 1234.57
negativo opcional.
1234.567 ("F", de-DE) ->
Compatible con: todos los 1234,57
tipos numéricos.
1234 ("F1", en-US) ->
Especificador de precisión: 1234.0
número de dígitos
decimales. 1234 ("F1", de-DE) ->
1234,0
Especificador de precisión
predeterminado: Definido -1234.56 ("F4", en-US) -> -
por 1234.5600
NumberFormatInfo.Number
DecimalDigits. -1234.56 ("F4", de-DE) -> -
1234,5600
Más información:
Especificador de formato de
punto fijo ("F").
"N" o "n" número Resultado: dígitos integrales 1234.567 ("N", en-US) ->
y decimales, separadores de 1,234.57
grupos y un separador
decimal con signo negativo 1234.567 ("N", ru-RU) -> 1
opcional. 234,57
Más información:
Especificador de formato
numérico ("N").
Especificador de precisión
predeterminado: Definido
por
NumberFormatInfo.Percent
DecimalDigits.
Más información:
Especificador de formato de
porcentaje ("P").
ESPECIFICADOR DE FORMATO NOMBRE DESCRIPCIÓN EJEMPLOS
"R" o "r" Acción de ida y vuelta Resultado: cadena que 123456789.12345678 ("R")
puede aplicar acciones de -> 123456789.12345678
ida y vuelta (round-trip) a
un número idéntico. -1234567890.12345678
("R") -> -
Compatible con: Single, 1234567890.1234567
Double y BigInteger.
Más información:
Especificador de formato de
operación de ida y vuelta
("R").
Más información:
Especificador de formato
hexadecimal ("X").
Una cadena de formato numérico estándar se puede usar para definir el formato de un valor numérico de una
de dos maneras:
Se puede pasar a una sobrecarga del método ToString que tiene un parámetro format . En el ejemplo
siguiente se da formato a un valor numérico como una cadena de divisa en la referencia cultural actual
(en este caso, en-US ).
Decimal value = static_cast<Decimal>(123.456);
Console::WriteLine(value.ToString("C2"));
// Displays $123.46
Opcionalmente, puede facilitar un argumento alignment para especificar el ancho del campo numérico y
si su valor está alineado a izquierda o derecha. En el ejemplo siguiente se alinea a la izquierda un valor de
moneda en un campo de 28 caracteres y se alinea a la derecha un valor de moneda en un campo de 14
caracteres.
Console::WriteLine(value.ToString("C3", CultureInfo::CurrentCulture));
Console::WriteLine(value.ToString("C3",
CultureInfo::CreateSpecificCulture("da-DK")));
// The example displays the following output on a system whose
// current culture is English (United States):
// $12,345.68
// $12,345.679
// kr 12.345,679
Console.WriteLine(value.ToString("C3", CultureInfo.CurrentCulture));
Console.WriteLine(value.ToString("C3",
CultureInfo.CreateSpecificCulture("da-DK")));
// The example displays the following output on a system whose
// current culture is English (United States):
// $12,345.68
// $12,345.679
// 12.345,679 kr
Console.WriteLine(value.ToString("C3", CultureInfo.CurrentCulture))
Console.WriteLine(value.ToString("C3", _
CultureInfo.CreateSpecificCulture("da-DK")))
' The example displays the following output on a system whose
' current culture is English (United States):
' $12,345.68
' $12,345.679
' kr 12.345,679
Volver a la tabla
int value;
value = 12345;
Console::WriteLine(value.ToString("D"));
// Displays 12345
Console::WriteLine(value.ToString("D8"));
// Displays 00012345
value = -12345;
Console::WriteLine(value.ToString("D"));
// Displays -12345
Console::WriteLine(value.ToString("D8"));
// Displays -00012345
int value;
value = 12345;
Console.WriteLine(value.ToString("D"));
// Displays 12345
Console.WriteLine(value.ToString("D8"));
// Displays 00012345
value = -12345;
Console.WriteLine(value.ToString("D"));
// Displays -12345
Console.WriteLine(value.ToString("D8"));
// Displays -00012345
value = 12345
Console.WriteLine(value.ToString("D"))
' Displays 12345
Console.WriteLine(value.ToString("D8"))
' Displays 00012345
value = -12345
Console.WriteLine(value.ToString("D"))
' Displays -12345
Console.WriteLine(value.ToString("D8"))
' Displays -00012345
Volver a la tabla
Console::WriteLine(value.ToString("E10", CultureInfo::InvariantCulture));
// Displays 1.2345678900E+004
Console::WriteLine(value.ToString("e4", CultureInfo::InvariantCulture));
// Displays 1.2346e+004
Console::WriteLine(value.ToString("E",
CultureInfo::CreateSpecificCulture("fr-FR")));
// Displays 1,234568E+004
Console.WriteLine(value.ToString("E10", CultureInfo.InvariantCulture));
// Displays 1.2345678900E+004
Console.WriteLine(value.ToString("e4", CultureInfo.InvariantCulture));
// Displays 1.2346e+004
Console.WriteLine(value.ToString("E",
CultureInfo.CreateSpecificCulture("fr-FR")));
// Displays 1,234568E+004
Dim value As Double = 12345.6789
Console.WriteLine(value.ToString("E", CultureInfo.InvariantCulture))
' Displays 1.234568E+004
Console.WriteLine(value.ToString("E10", CultureInfo.InvariantCulture))
' Displays 1.2345678900E+004
Console.WriteLine(value.ToString("e4", CultureInfo.InvariantCulture))
' Displays 1.2346e+004
Console.WriteLine(value.ToString("E", _
CultureInfo.CreateSpecificCulture("fr-FR")))
' Displays 1,234568E+004
Volver a la tabla
En el ejemplo siguiente se da formato a un valor Double e Int32 con el especificador de formato de punto fijo:
int integerNumber;
integerNumber = 17843;
Console::WriteLine(integerNumber.ToString("F",
CultureInfo::InvariantCulture));
// Displays 17843.00
integerNumber = -29541;
Console::WriteLine(integerNumber.ToString("F3",
CultureInfo::InvariantCulture));
// Displays -29541.000
double doubleNumber;
doubleNumber = 18934.1879;
Console::WriteLine(doubleNumber.ToString("F", CultureInfo::InvariantCulture));
// Displays 18934.19
Console::WriteLine(doubleNumber.ToString("F0", CultureInfo::InvariantCulture));
// Displays 18934
doubleNumber = -1898300.1987;
Console::WriteLine(doubleNumber.ToString("F1", CultureInfo::InvariantCulture));
// Displays -1898300.2
Console::WriteLine(doubleNumber.ToString("F3",
CultureInfo::CreateSpecificCulture("es-ES")));
// Displays -1898300,199
int integerNumber;
integerNumber = 17843;
Console.WriteLine(integerNumber.ToString("F",
CultureInfo.InvariantCulture));
// Displays 17843.00
integerNumber = -29541;
Console.WriteLine(integerNumber.ToString("F3",
CultureInfo.InvariantCulture));
// Displays -29541.000
double doubleNumber;
doubleNumber = 18934.1879;
Console.WriteLine(doubleNumber.ToString("F", CultureInfo.InvariantCulture));
// Displays 18934.19
Console.WriteLine(doubleNumber.ToString("F0", CultureInfo.InvariantCulture));
// Displays 18934
doubleNumber = -1898300.1987;
Console.WriteLine(doubleNumber.ToString("F1", CultureInfo.InvariantCulture));
// Displays -1898300.2
Console.WriteLine(doubleNumber.ToString("F3",
CultureInfo.CreateSpecificCulture("es-ES")));
// Displays -1898300,199
Dim integerNumber As Integer
integerNumber = 17843
Console.WriteLine(integerNumber.ToString("F", CultureInfo.InvariantCulture))
' Displays 17843.00
integerNumber = -29541
Console.WriteLine(integerNumber.ToString("F3", CultureInfo.InvariantCulture))
' Displays -29541.000
Console.WriteLine(doubleNumber.ToString("F0", CultureInfo.InvariantCulture))
' Displays 18934
doubleNumber = -1898300.1987
Console.WriteLine(doubleNumber.ToString("F1", CultureInfo.InvariantCulture))
' Displays -1898300.2
Console.WriteLine(doubleNumber.ToString("F3", _
CultureInfo.CreateSpecificCulture("es-ES")))
' Displays -1898300,199
Volver a la tabla
Int64 19 dígitos
UInt64 20 dígitos
Single 7 dígitos
Double 15 dígitos
Decimal 29 dígitos
La notación de punto fijo se utiliza si el exponente que resultaría de la expresión del número en notación
científica es mayor que -5 y menor que el especificador de precisión, de lo contrario se utiliza la notación
científica. El resultado contiene un separador decimal si es necesario y se omiten los ceros finales después de ese
separador. Si el especificador de precisión está presente y el número de dígitos significativos del resultado
supera la precisión especificada, los dígitos finales sobrantes se quitan mediante redondeo.
Sin embargo, si el número es Decimal y se omite el especificador de precisión, siempre se usa la notación de
punto fijo y se conservan los ceros finales.
Si se usa la notación científica, el exponente del resultado lleva el prefijo "E" si el especificador de formato es "G",
o "e" si el especificador de formato es "g". El exponente contiene un mínimo de dos dígitos. Esto difiere del
formato para la notación científica que genera el especificador de formato exponencial, que incluye un mínimo
de tres dígitos en el exponente.
Tenga en cuenta que, cuando se usa con un valor Double, el especificador de formato "G17" garantiza que el
valor Double original realice un recorrido de ida y vuelta correctamente. Esto se debe a que Double es un
número de punto flotante de doble precisión compatible con IEEE 754-2008 ( binary64 ) que ofrece un máximo
de 17 dígitos de precisión significativos. Se recomienda su uso en lugar del especificador de formato "R", ya que,
en algunos casos, "R" no logra realizar un recorrido de ida y vuelta correcto por los valores de números de punto
flotante de doble precisión. Esto se ilustra en el siguiente ejemplo.
Module Example
Public Sub Main()
Dim original As Double = 0.84551240822557006
Dim rSpecifier = original.ToString("R")
Dim g17Specifier = original.ToString("G17")
Cuando se usa con un valor Single, el especificador de formato "G9" garantiza que el valor Single original realice
un recorrido de ida y vuelta correctamente. Esto se debe a que Single es un número de punto flotante de
precisión sencilla compatible con IEEE 754-2008 ( binary32 ) que ofrece hasta nueve dígitos de precisión
significativos. Por motivos de rendimiento, se recomienda su uso en lugar del especificador de formato "R".
La información de formato del objeto NumberFormatInfo actual afecta a la cadena de resultado. En la tabla
siguiente se enumeran las propiedades de NumberFormatInfo que controlan el formato de la cadena de
resultado.
PROPIEDAD DE NUMBERFORMATINFO DESCRIPCIÓN
En el ejemplo siguiente se da formato a valores de punto flotante ordenados con el especificador de formato
general:
double number;
number = 12345.6789;
Console::WriteLine(number.ToString("G", CultureInfo::InvariantCulture));
// Displays 12345.6789
Console::WriteLine(number.ToString("G",
CultureInfo::CreateSpecificCulture("fr-FR")));
// Displays 12345,6789
Console::WriteLine(number.ToString("G7", CultureInfo::InvariantCulture));
// Displays 12345.68
number = .0000023;
Console::WriteLine(number.ToString("G", CultureInfo::InvariantCulture));
// Displays 2.3E-06
Console::WriteLine(number.ToString("G",
CultureInfo::CreateSpecificCulture("fr-FR")));
// Displays 2,3E-06
number = .0023;
Console::WriteLine(number.ToString("G", CultureInfo::InvariantCulture));
// Displays 0.0023
number = 1234;
Console::WriteLine(number.ToString("G2", CultureInfo::InvariantCulture));
// Displays 1.2E+03
number = Math::PI;
Console::WriteLine(number.ToString("G5", CultureInfo::InvariantCulture));
// Displays 3.1416
double number;
number = 12345.6789;
Console.WriteLine(number.ToString("G", CultureInfo.InvariantCulture));
// Displays 12345.6789
Console.WriteLine(number.ToString("G",
CultureInfo.CreateSpecificCulture("fr-FR")));
// Displays 12345,6789
Console.WriteLine(number.ToString("G7", CultureInfo.InvariantCulture));
// Displays 12345.68
number = .0000023;
Console.WriteLine(number.ToString("G", CultureInfo.InvariantCulture));
// Displays 2.3E-06
Console.WriteLine(number.ToString("G",
CultureInfo.CreateSpecificCulture("fr-FR")));
// Displays 2,3E-06
number = .0023;
Console.WriteLine(number.ToString("G", CultureInfo.InvariantCulture));
// Displays 0.0023
number = 1234;
Console.WriteLine(number.ToString("G2", CultureInfo.InvariantCulture));
// Displays 1.2E+03
number = Math.PI;
Console.WriteLine(number.ToString("G5", CultureInfo.InvariantCulture));
// Displays 3.1416
number = 12345.6789
Console.WriteLine(number.ToString("G", CultureInfo.InvariantCulture))
' Displays 12345.6789
Console.WriteLine(number.ToString("G", _
CultureInfo.CreateSpecificCulture("fr-FR")))
' Displays 12345,6789
Console.WriteLine(number.ToString("G7", CultureInfo.InvariantCulture))
' Displays 12345.68
number = .0000023
Console.WriteLine(number.ToString("G", CultureInfo.InvariantCulture))
' Displays 2.3E-06
Console.WriteLine(number.ToString("G", _
CultureInfo.CreateSpecificCulture("fr-FR")))
' Displays 2,3E-06
number = .0023
Console.WriteLine(number.ToString("G", CultureInfo.InvariantCulture))
' Displays 0.0023
number = 1234
Console.WriteLine(number.ToString("G2", CultureInfo.InvariantCulture))
' Displays 1.2E+03
number = Math.Pi
Console.WriteLine(number.ToString("G5", CultureInfo.InvariantCulture))
' Displays 3.1416
Volver a la tabla
Especificador de formato numérico ("N")
El especificador de formato numérico ("N") convierte un número en una cadena con el formato "-
d,ddd,ddd.ddd…", donde "-" indica el símbolo de número negativo, si es necesario; "d", representa cada dígito (0-
9); "," es el separador de grupo; y "." es el símbolo de punto decimal. El especificador de precisión indica el
número deseado de dígitos después del separador decimal. Si se omite el especificador de precisión, el número
de posiciones decimales está definido por la propiedad NumberFormatInfo.NumberDecimalDigits actual.
La información de formato del objeto NumberFormatInfo actual afecta a la cadena de resultado. En la tabla
siguiente se enumeran las propiedades de NumberFormatInfo que controlan el formato de la cadena de
resultado.
En el ejemplo siguiente se da formato a valores de punto flotante ordenados con el especificador de formato
numérico:
Volver a la tabla
En el ejemplo siguiente se da formato a valores de punto flotante con el especificador de formato de porcentaje:
double number = .2468013;
Console::WriteLine(number.ToString("P", CultureInfo::InvariantCulture));
// Displays 24.68 %
Console::WriteLine(number.ToString("P",
CultureInfo::CreateSpecificCulture("hr-HR")));
// Displays 24,68%
Console::WriteLine(number.ToString("P1", CultureInfo::InvariantCulture));
// Displays 24.7 %
Volver a la tabla
#using <System.Numerics.dll>
void main()
{
BigInteger value = BigInteger::Pow(Int64::MaxValue, 2);
Console::WriteLine(value.ToString("R"));
}
// The example displays the following output:
// 85070591730234615847396907784232501249
using System;
using System.Numerics;
Imports System.Numerics
Module Example
Public Sub Main()
Dim value = BigInteger.Pow(Int64.MaxValue, 2)
Console.WriteLine(value.ToString("R"))
End Sub
End Module
' The example displays the following output:
' 85070591730234615847396907784232501249
IMPORTANT
En algunos casos, los valores Double con el formato de cadena numérica estándar "R" no realizan correctamente la
operación de ida y vuelta si se compilan usando los modificadores /platform:x64 o /platform:anycpu y se ejecutan
en sistemas de 64 bits. Para más información, consulte el siguiente párrafo.
Para solucionar el problema de los valores Double con formato de cadena numérico estándar “R” que no hacen
correctamente el viaje de ida y vuelta si se compilan con conmutadores /platform:x64 o /platform:anycpu y se
ejecutan en sistemas de 64 bits, puede dar formato a los valores Double usando la cadena de formato numérico
estándar “G17”. En el ejemplo siguiente se usa la cadena de formato "R" con un valor Double que no realiza
correctamente la operación de ida y vuelta, y usa también la cadena de formato "G17" para realizar
correctamente la operación de ida y vuelta del valor original:
Console.WriteLine("Attempting to round-trip a Double with 'R':");
double initialValue = 0.6822871999174;
string valueString = initialValue.ToString("R",
CultureInfo.InvariantCulture);
double roundTripped = double.Parse(valueString,
CultureInfo.InvariantCulture);
Console.WriteLine("{0:R} = {1:R}: {2}\n",
initialValue, roundTripped, initialValue.Equals(roundTripped));
Imports System.Globalization
Module Example
Public Sub Main()
Console.WriteLine("Attempting to round-trip a Double with 'R':")
Dim initialValue As Double = 0.6822871999174
Dim valueString As String = initialValue.ToString("R",
CultureInfo.InvariantCulture)
Dim roundTripped As Double = Double.Parse(valueString,
CultureInfo.InvariantCulture)
Console.WriteLine("{0:R} = {1:R}: {2}",
initialValue, roundTripped, initialValue.Equals(roundTripped))
Console.WriteLine()
Volver a la tabla
int value;
value = 0x2045e;
Console::WriteLine(value.ToString("x"));
// Displays 2045e
Console::WriteLine(value.ToString("X"));
// Displays 2045E
Console::WriteLine(value.ToString("X8"));
// Displays 0002045E
value = 123456789;
Console::WriteLine(value.ToString("X"));
// Displays 75BCD15
Console::WriteLine(value.ToString("X2"));
// Displays 75BCD15
int value;
value = 0x2045e;
Console.WriteLine(value.ToString("x"));
// Displays 2045e
Console.WriteLine(value.ToString("X"));
// Displays 2045E
Console.WriteLine(value.ToString("X8"));
// Displays 0002045E
value = 123456789;
Console.WriteLine(value.ToString("X"));
// Displays 75BCD15
Console.WriteLine(value.ToString("X2"));
// Displays 75BCD15
value = &h2045e
Console.WriteLine(value.ToString("x"))
' Displays 2045e
Console.WriteLine(value.ToString("X"))
' Displays 2045E
Console.WriteLine(value.ToString("X8"))
' Displays 0002045E
value = 123456789
Console.WriteLine(value.ToString("X"))
' Displays 75BCD15
Console.WriteLine(value.ToString("X2"))
' Displays 75BCD15
Volver a la tabla
Notas
Configuración del Panel de control
Los valores de configuración del elemento Configuración regional y de idioma del Panel de control influyen
en la cadena de resultado generada por una operación de formato. Esas configuraciones se usan para inicializar
el objeto NumberFormatInfo asociado a la referencia cultural del subproceso actual, que proporciona valores
que se usan para controlar el formato. Los equipos que usan configuraciones diferentes generarán cadenas de
resultado distintas.
Asimismo, si se utiliza el constructor CultureInfo.CultureInfo(String) para crear instancias de un nuevo objeto
CultureInfo que representa la misma referencia cultural que la referencia cultural del sistema actual, cualquier
personalización establecida por el elemento Configuración regional y de idioma del Panel de control se
aplicará al nuevo objeto CultureInfo. Puede usar el constructor CultureInfo.CultureInfo(String, Boolean) para
crear un objeto CultureInfo que no refleje las personalizaciones de un sistema.
Propiedades NumberFormatInfo
El formato se ve influenciado por las propiedades del objeto NumberFormatInfo actual, proporcionado
implícitamente por la referencia cultural del subproceso actual o explícitamente por el parámetro
IFormatProvider del método que invoca el formato. Especifique un objeto NumberFormatInfo o CultureInfo
para dicho parámetro.
NOTE
Para obtener información sobre la personalización de patrones o cadenas que se usan para dar formato a valores
numéricos, vea el tema de la clase NumberFormatInfo.
Ejemplo
NOTE
Algunos de los ejemplos de C# de este artículo se ejecutan en el ejecutor de código en línea y área de juegos de Try.NET.
Haga clic en el botón Ejecutar para ejecutar un ejemplo en una ventana interactiva. Una vez que se ejecuta el código,
puede modificar y ejecutar el código modificado si vuelve a hacer clic en Ejecutar. El código modificado se ejecuta en la
ventana interactiva o, si se produce un error en la compilación, en la ventana interactiva se muestran todos los mensajes
de error del compilador de C#.
En el ejemplo siguiente se da formato a un valor numérico integral y de punto flotante mediante la referencia
cultural en-US y todos los especificadores de formato numérico estándar. En este ejemplo se usan dos tipos
numéricos concretos (Double y Int32), pero se obtendrían resultados similares con cualquiera de los demás
tipos base numéricos (Byte, SByte, Int16, Int32, Int64, UInt16, UInt32, UInt64, BigInteger, Decimal y Single).
// Display string representations of numbers for en-us culture
CultureInfo ci = new CultureInfo("en-us");
Imports System.Globalization
Imports System.Threading
Module NumericFormats
Public Sub Main()
' Display string representations of numbers for en-us culture
Dim ci As New CultureInfo("en-us")
Vea también
NumberFormatInfo
Custom Numeric Format Strings
Aplicación de formato a tipos
Cómo: Rellenar un número con ceros a la izquierda
Formatos compuestos
Ejemplo: Utilidad de formato WinForms de .NET Core (C#)
Ejemplo: Utilidad de formato WinForms de .NET Core (Visual Basic)
Cadenas con formato numérico personalizado
13/01/2020 • 38 minutes to read • Edit Online
Puede crear una cadena de formato numérico personalizado, formada por uno o varios especificadores
numéricos personalizados, para definir cómo debe darse formato a los datos numéricos. Una cadena de formato
numérico personalizado es cualquier cadena que no sea una cadena de formato numérico estándar.
Algunas sobrecargas del método ToString de todos los tipos numéricos admiten las cadenas de formato
numérico personalizado. Por ejemplo, se puede proporcionar una cadena de formato numérico a los métodos
ToString(String) y ToString(String, IFormatProvider) del tipo Int32 . La característica de formato compuesto de
.NET, que utilizan algunos métodos Write y WriteLine de las clases Console y StreamWriter, el método
String.Format y el método StringBuilder.AppendFormat, admite también cadenas de formato numérico
personalizado. La característica interpolación de cadenas admite también cadenas de formato numérico
personalizado.
TIP
Puede descargar la Utilidad de formato, que es una aplicación de .NET Core Windows Forms que permite aplicar
cadenas de formato a valores numéricos o de fecha y hora, y que muestra la cadena de resultado. El código fuente está
disponible para C# y Visual Basic.
En la tabla siguiente se describen los especificadores de formato numérico personalizado y se muestran las
salidas de ejemplo generadas por cada especificador de formato. Vea la sección Notas para obtener información
adicional sobre cómo usar las cadenas de formato numérico personalizado y la sección Ejemplo para ver una
ilustración completa de su uso.
"0" Marcador de posición cero Reemplaza el cero con el 1234.5678 ("00000") ->
dígito correspondiente si 01235
hay alguno presente; de lo
contrario, el cero aparece en 0.45678 ("0.00", en-US) ->
la cadena de resultado. 0.46
Más información:
Especificador personalizado
"#".
"." Separador decimal Determina la ubicación del 0.45678 ("0.00", en-US) ->
separador decimal en la 0.46
cadena de resultado.
0.45678 ("0.00", fr-FR) ->
Más información: El 0,46
especificador personalizado
".".
Más información:
Especificadores
personalizados "E" y "e".
'cadena' Delimitador de cadena Indica que los caracteres 68 ("# ' grados'") -> 68
literal que encierra se deben grados
"string" copiar en la cadena de
resultado sin modificar. 68 ("# ' grados'") -> 68
grados
Más información: Literales
de carácter.
ESPECIFICADOR DE FORMATO NOMBRE DESCRIPCIÓN EJEMPLOS
Otros Todos los demás caracteres El carácter se copia en la 68 ("# °") -> 68 °
cadena de resultado sin
modificar.
En las secciones siguientes se proporciona información detallada sobre cada uno de los especificadores de
formato numérico personalizado.
NOTE
Algunos de los ejemplos de C# de este artículo se ejecutan en el ejecutor de código en línea y área de juegos de Try.NET.
Haga clic en el botón Ejecutar para ejecutar un ejemplo en una ventana interactiva. Una vez que se ejecuta el código,
puede modificar y ejecutar el código modificado si vuelve a hacer clic en Ejecutar. El código modificado se ejecuta en la
ventana interactiva o, si se produce un error en la compilación, en la ventana interactiva se muestran todos los mensajes
de error del compilador de C#.
value = 123;
Console::WriteLine(value.ToString("00000"));
Console::WriteLine(String::Format("{0:00000}", value));
// Displays 00123
value = 1.2;
Console::WriteLine(value.ToString("0.00", CultureInfo::InvariantCulture));
Console::WriteLine(String::Format(CultureInfo::InvariantCulture,
"{0:0.00}", value));
// Displays 1.20
Console::WriteLine(value.ToString("00.00", CultureInfo::InvariantCulture));
Console::WriteLine(String::Format(CultureInfo::InvariantCulture,
"{0:00.00}", value));
// Displays 01.20
value = .56;
Console::WriteLine(value.ToString("0.0", CultureInfo::InvariantCulture));
Console::WriteLine(String::Format(CultureInfo::InvariantCulture,
"{0:0.0}", value));
// Displays 0.6
value = 1234567890;
Console::WriteLine(value.ToString("0,0", CultureInfo::InvariantCulture));
Console::WriteLine(String::Format(CultureInfo::InvariantCulture,
"{0:0,0}", value));
// Displays 1,234,567,890
value = 1234567890.123456;
Console::WriteLine(value.ToString("0,0.0", CultureInfo::InvariantCulture));
Console::WriteLine(String::Format(CultureInfo::InvariantCulture,
"{0:0,0.0}", value));
// Displays 1,234,567,890.1
value = 1234.567890;
Console::WriteLine(value.ToString("0,0.00", CultureInfo::InvariantCulture));
Console::WriteLine(String::Format(CultureInfo::InvariantCulture,
"{0:0,0.00}", value));
// Displays 1,234.57
double value;
value = 123;
Console.WriteLine(value.ToString("00000"));
Console.WriteLine(String.Format("{0:00000}", value));
// Displays 00123
value = 1.2;
Console.WriteLine(value.ToString("0.00", CultureInfo.InvariantCulture));
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:0.00}", value));
// Displays 1.20
Console.WriteLine(value.ToString("00.00", CultureInfo.InvariantCulture));
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:00.00}", value));
// Displays 01.20
value = .56;
Console.WriteLine(value.ToString("0.0", CultureInfo.InvariantCulture));
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:0.0}", value));
// Displays 0.6
value = 1234567890;
Console.WriteLine(value.ToString("0,0", CultureInfo.InvariantCulture));
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:0,0}", value));
// Displays 1,234,567,890
value = 1234567890.123456;
Console.WriteLine(value.ToString("0,0.0", CultureInfo.InvariantCulture));
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:0,0.0}", value));
// Displays 1,234,567,890.1
value = 1234.567890;
Console.WriteLine(value.ToString("0,0.00", CultureInfo.InvariantCulture));
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:0,0.00}", value));
// Displays 1,234.57
Dim value As Double
value = 123
Console.WriteLine(value.ToString("00000"))
Console.WriteLine(String.Format("{0:00000}", value))
' Displays 00123
value = 1.2
Console.Writeline(value.ToString("0.00", CultureInfo.InvariantCulture))
Console.Writeline(String.Format(CultureInfo.InvariantCulture,
"{0:0.00}", value))
' Displays 1.20
Console.WriteLine(value.ToString("00.00", CultureInfo.InvariantCulture))
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:00.00}", value))
' Displays 01.20
Dim daDK As CultureInfo = CultureInfo.CreateSpecificCulture("da-DK")
Console.WriteLine(value.ToString("00.00", daDK))
Console.WriteLine(String.Format(daDK, "{0:00.00}", value))
' Displays 01,20
value = .56
Console.WriteLine(value.ToString("0.0", CultureInfo.InvariantCulture))
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:0.0}", value))
' Displays 0.6
value = 1234567890
Console.WriteLine(value.ToString("0,0", CultureInfo.InvariantCulture))
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:0,0}", value))
' Displays 1,234,567,890
Dim elGR As CultureInfo = CultureInfo.CreateSpecificCulture("el-GR")
Console.WriteLine(value.ToString("0,0", elGR))
Console.WriteLine(String.Format(elGR, "{0:0,0}", value))
' Displays 1.234.567.890
value = 1234567890.123456
Console.WriteLine(value.ToString("0,0.0", CultureInfo.InvariantCulture))
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:0,0.0}", value))
' Displays 1,234,567,890.1
value = 1234.567890
Console.WriteLine(value.ToString("0,0.00", CultureInfo.InvariantCulture))
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:0,0.00}", value))
' Displays 1,234.57
Volver a la tabla
double value;
value = 1.2;
Console::WriteLine(value.ToString("#.##", CultureInfo::InvariantCulture));
Console::WriteLine(String::Format(CultureInfo::InvariantCulture,
"{0:#.##}", value));
// Displays 1.2
value = 123;
Console::WriteLine(value.ToString("#####"));
Console::WriteLine(String::Format("{0:#####}", value));
// Displays 123
value = 123456;
Console::WriteLine(value.ToString("[##-##-##]"));
Console::WriteLine(String::Format("{0:[##-##-##]}", value));
// Displays [12-34-56]
value = 1234567890;
Console::WriteLine(value.ToString("#"));
Console::WriteLine(String::Format("{0:#}", value));
// Displays 1234567890
Console::WriteLine(value.ToString("(###) ###-####"));
Console::WriteLine(String::Format("{0:(###) ###-####}", value));
// Displays (123) 456-7890
double value;
value = 1.2;
Console.WriteLine(value.ToString("#.##", CultureInfo.InvariantCulture));
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:#.##}", value));
// Displays 1.2
value = 123;
Console.WriteLine(value.ToString("#####"));
Console.WriteLine(String.Format("{0:#####}", value));
// Displays 123
value = 123456;
Console.WriteLine(value.ToString("[##-##-##]"));
Console.WriteLine(String.Format("{0:[##-##-##]}", value));
// Displays [12-34-56]
value = 1234567890;
Console.WriteLine(value.ToString("#"));
Console.WriteLine(String.Format("{0:#}", value));
// Displays 1234567890
Console.WriteLine(value.ToString("(###) ###-####"));
Console.WriteLine(String.Format("{0:(###) ###-####}", value));
// Displays (123) 456-7890
Dim value As Double
value = 1.2
Console.WriteLine(value.ToString("#.##", CultureInfo.InvariantCulture))
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:#.##}", value))
' Displays 1.2
value = 123
Console.WriteLine(value.ToString("#####"))
Console.WriteLine(String.Format("{0:#####}", value))
' Displays 123
value = 123456
Console.WriteLine(value.ToString("[##-##-##]"))
Console.WriteLine(String.Format("{0:[##-##-##]}", value))
' Displays [12-34-56]
value = 1234567890
Console.WriteLine(value.ToString("#"))
Console.WriteLine(String.Format("{0:#}", value))
' Displays 1234567890
Console.WriteLine(value.ToString("(###) ###-####"))
Console.WriteLine(String.Format("{0:(###) ###-####}", value))
' Displays (123) 456-7890
Para devolver una cadena de resultado en la que los dígitos que faltan o los ceros iniciales se reemplazan por
espacios, use la característica de formato compuesto y especifique un ancho de campo, como se muestra en el
ejemplo siguiente.
void main()
{
Double value = .324;
Console::WriteLine("The value is: '{0,5:#.###}'", value);
}
// The example displays the following output if the current culture
// is en-US:
// The value is: ' .324'
using System;
Volver a la tabla
double value;
value = 1.2;
Console::WriteLine(value.ToString("0.00", CultureInfo::InvariantCulture));
Console::WriteLine(String::Format(CultureInfo::InvariantCulture,
"{0:0.00}", value));
// Displays 1.20
Console::WriteLine(value.ToString("00.00", CultureInfo::InvariantCulture));
Console::WriteLine(String::Format(CultureInfo::InvariantCulture,
"{0:00.00}", value));
// Displays 01.20
Console::WriteLine(value.ToString("00.00",
CultureInfo::CreateSpecificCulture("da-DK")));
Console::WriteLine(String::Format(CultureInfo::CreateSpecificCulture("da-DK"),
"{0:00.00}", value));
// Displays 01,20
value = .086;
Console::WriteLine(value.ToString("#0.##%", CultureInfo::InvariantCulture));
Console::WriteLine(String::Format(CultureInfo::InvariantCulture,
"{0:#0.##%}", value));
// Displays 8.6%
value = 86000;
Console::WriteLine(value.ToString("0.###E+0", CultureInfo::InvariantCulture));
Console::WriteLine(String::Format(CultureInfo::InvariantCulture,
"{0:0.###E+0}", value));
// Displays 8.6E+4
double value;
value = 1.2;
Console.WriteLine(value.ToString("0.00", CultureInfo.InvariantCulture));
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:0.00}", value));
// Displays 1.20
Console.WriteLine(value.ToString("00.00", CultureInfo.InvariantCulture));
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:00.00}", value));
// Displays 01.20
Console.WriteLine(value.ToString("00.00",
CultureInfo.CreateSpecificCulture("da-DK")));
Console.WriteLine(String.Format(CultureInfo.CreateSpecificCulture("da-DK"),
"{0:00.00}", value));
// Displays 01,20
value = .086;
Console.WriteLine(value.ToString("#0.##%", CultureInfo.InvariantCulture));
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:#0.##%}", value));
// Displays 8.6%
value = 86000;
Console.WriteLine(value.ToString("0.###E+0", CultureInfo.InvariantCulture));
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:0.###E+0}", value));
// Displays 8.6E+4
value = 1.2
Console.Writeline(value.ToString("0.00", CultureInfo.InvariantCulture))
Console.Writeline(String.Format(CultureInfo.InvariantCulture,
"{0:0.00}", value))
' Displays 1.20
Console.WriteLine(value.ToString("00.00", CultureInfo.InvariantCulture))
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:00.00}", value))
' Displays 01.20
Console.WriteLine(value.ToString("00.00", _
CultureInfo.CreateSpecificCulture("da-DK")))
Console.WriteLine(String.Format(CultureInfo.CreateSpecificCulture("da-DK"),
"{0:00.00}", value))
' Displays 01,20
value = .086
Console.WriteLine(value.ToString("#0.##%", CultureInfo.InvariantCulture))
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:#0.##%}", value))
' Displays 8.6%
value = 86000
Console.WriteLine(value.ToString("0.###E+0", CultureInfo.InvariantCulture))
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:0.###E+0}", value))
' Displays 8.6E+4
Volver a la tabla
Especificador personalizado ","
El carácter "," actúa como separador de grupos y como especificador de escala numérica.
Separador de grupos: si se especifican una o varias comas dos marcadores de posición de dígitos (0 o #)
que dan formato a los dígitos enteros de un número, se insertará un carácter separador de grupos entre
cada grupo de números en la parte entera de la salida.
Las propiedades NumberGroupSeparator y NumberGroupSizes del objeto NumberFormatInfo actual
determinan el carácter utilizado como separador de grupos de números y el tamaño de cada grupo de
números. Por ejemplo, si se utiliza la cadena "#,#" y la referencia cultural de todos los idiomas para dar
formato al número 1000, el resultado será "1,000".
Especificador de escala numérica: si se especifican una o varias comas inmediatamente a la izquierda del
signo decimal explícito o implícito, el número al que se va a dar formato se divide por 1000 por cada
coma. Por ejemplo, si se utiliza la cadena "0,," para dar formato al número 100 millones, el resultado será
"100".
Puede usar especificadores de separador de grupos y de escala numérica en la misma cadena de formato. Por
ejemplo, si se utiliza la cadena "#,0,," y la referencia cultural de todos los idiomas para dar formato al número
mil millones, el resultado será "1,000".
En el ejemplo siguiente se muestra el uso de la coma como separador de grupos.
Console::WriteLine(value.ToString("#,##0,,", CultureInfo::InvariantCulture));
Console::WriteLine(String::Format(CultureInfo::InvariantCulture,
"{0:#,##0,,}", value));
// Displays 1,235
Console.WriteLine(value.ToString("#,##0,,", CultureInfo.InvariantCulture));
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:#,##0,,}", value));
// Displays 1,235
Console.WriteLine(value.ToString("#,##0,,", CultureInfo.InvariantCulture))
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:#,##0,,}", value))
' Displays 1,235
Console::WriteLine(value.ToString("#,,,", CultureInfo::InvariantCulture));
Console::WriteLine(String::Format(CultureInfo::InvariantCulture,
"{0:#,,,}", value));
// Displays 1
Console::WriteLine(value.ToString("#,##0,,", CultureInfo::InvariantCulture));
Console::WriteLine(String::Format(CultureInfo::InvariantCulture,
"{0:#,##0,,}", value));
// Displays 1,235
Console.WriteLine(value.ToString("#,,,", CultureInfo.InvariantCulture));
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:#,,,}", value));
// Displays 1
Console.WriteLine(value.ToString("#,##0,,", CultureInfo.InvariantCulture));
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:#,##0,,}", value));
// Displays 1,235
Console.WriteLine(value.ToString("#,,,", CultureInfo.InvariantCulture))
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:#,,,}", value))
' Displays 1
Console.WriteLine(value.ToString("#,##0,,", CultureInfo.InvariantCulture))
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:#,##0,,}", value))
' Displays 1,235
Volver a la tabla
Volver a la tabla
Volver a la tabla
Especificadores personalizados "E" y "e"
Si alguna de las cadenas "E", "E+", "E -", "e", "e+", o "e-" está presente en la cadena de formato y va seguida
inmediatamente de al menos un cero, se da formato al número mediante notación científica con una 'E' o una 'e'
insertadas entre el número y el exponente. El número de ceros que hay a continuación del indicador de notación
científica determina el número mínimo de dígitos para el exponente. Los formatos 'E+' y 'e+' indican que un
signo más o un signo menos debe preceder siempre al exponente. Los formatos 'E', 'E -', 'e' o 'e-' indican que un
carácter de signo debe preceder solo a exponentes negativos.
En el ejemplo siguiente se da formato a varios valores numéricos utilizando los especificadores de notación
científica.
Console::WriteLine(value.ToString("0.###E+000", CultureInfo::InvariantCulture));
Console::WriteLine(String::Format(CultureInfo::InvariantCulture,
"{0:0.###E+000}", value));
// Displays 8.6E+004
Console::WriteLine(value.ToString("0.###E-000", CultureInfo::InvariantCulture));
Console::WriteLine(String::Format(CultureInfo::InvariantCulture,
"{0:0.###E-000}", value));
// Displays 8.6E004
Console.WriteLine(value.ToString("0.###E+000", CultureInfo.InvariantCulture));
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:0.###E+000}", value));
// Displays 8.6E+004
Console.WriteLine(value.ToString("0.###E-000", CultureInfo.InvariantCulture));
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:0.###E-000}", value));
// Displays 8.6E004
Console.WriteLine(value.ToString("0.###E+000", CultureInfo.InvariantCulture))
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:0.###E+000}", value))
' Displays 8.6E+004
Console.WriteLine(value.ToString("0.###E-000", CultureInfo.InvariantCulture))
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0:0.###E-000}", value))
' Displays 8.6E004
Volver a la tabla
NOTE
Algunos compiladores, como los compiladores de C# y C++, también pueden interpretar un único carácter de barra
diagonal inversa como un carácter de escape. Para asegurarse de que una cadena se interpreta correctamente al darle
formato, puede usar el carácter literal de cadena textual (el carácter @) antes de la cadena en C# o puede agregar otro
carácter de barra diagonal inversa delante de cada barra diagonal inversa en C# y C++. En el siguiente ejemplo de C# se
muestran ambos enfoques.
En el ejemplo siguiente se usa el carácter de escape para evitar que la operación de formato interprete los
caracteres "#", "0" y "\" como caracteres de escape o especificadores de formato. En el ejemplo de C# se usa una
barra diagonal inversa adicional para asegurarse de que una barra diagonal inversa se interprete como un
carácter literal.
Volver a la tabla
Los separadores de sección omiten cualquier formato preexistente asociado a un número al dar formato al valor
final. Por ejemplo, los valores negativos se muestran siempre con signo menos cuando se utilizan separadores
de sección. Si se desea que el valor con formato final tenga un signo menos, debe incluir explícitamente el signo
menos como parte del especificador de formato personalizado.
En el ejemplo siguiente se usa el especificador de formato ";" para aplicar un formato diferente a los números
positivos, negativos y cero.
Console::WriteLine(posValue.ToString(fmt2));
Console::WriteLine(String::Format("{0:" + fmt2 + "}", posValue));
// Displays 1234
Console::WriteLine(negValue.ToString(fmt2));
Console::WriteLine(String::Format("{0:" + fmt2 + "}", negValue));
// Displays (1234)
Console::WriteLine(zeroValue.ToString(fmt3));
Console::WriteLine(String::Format("{0:" + fmt3 + "}", zeroValue));
// Displays **Zero**
Console.WriteLine(posValue.ToString(fmt2));
Console.WriteLine(String.Format("{0:" + fmt2 + "}", posValue));
// Displays 1234
Console.WriteLine(negValue.ToString(fmt2));
Console.WriteLine(String.Format("{0:" + fmt2 + "}", negValue));
// Displays (1234)
Console.WriteLine(zeroValue.ToString(fmt3));
Console.WriteLine(String.Format("{0:" + fmt3 + "}", zeroValue));
// Displays **Zero**
Dim posValue As Double = 1234
Dim negValue As Double = -1234
Dim zeroValue As Double = 0
Console.WriteLine(posValue.ToString(fmt2))
Console.WriteLine(String.Format("{0:" + fmt2 + "}", posValue))
' Displays 1234
Console.WriteLine(negValue.ToString(fmt2))
Console.WriteLine(String.Format("{0:" + fmt2 + "}", negValue))
' Displays (1234)
Console.WriteLine(zeroValue.ToString(fmt3))
Console.WriteLine(String.Format("{0:" + fmt3 + "}", zeroValue))
' Displays **Zero**
Volver a la tabla
Literales de carácter
Los especificadores de formato que aparecen en una cadena de formato numérico personalizado siempre se
interpretan como caracteres de formato y no como caracteres literales. Se incluyen los caracteres siguientes:
0
#
%
‰
'
\
.
,
E o e, según su posición en la cadena de formato.
Todos los demás caracteres se interpretan siempre como literales de carácter y, en una operación de formato, se
incluyen en la cadena de resultado sin modificar. En una operación de análisis, deben coincidir exactamente con
los caracteres de la cadena de entrada; la comparación distingue entre mayúsculas y minúsculas.
En el ejemplo siguiente se muestra un uso habitual de las unidades de carácter literal (en este caso, los millares):
double n = 123.8;
Console.WriteLine($"{n:#,##0.0K}");
// The example displays the following output:
// 123.8K
Hay dos formas de indicar que los caracteres se han de interpretar como caracteres literales y no como
caracteres de formato, para que se puedan incluir en una cadena de resultado o analizarse correctamente en una
cadena de entrada:
Mediante el escape de un carácter de formato. Para obtener más información, vea Carácter de escape "\".
Mediante la inclusión de toda la cadena literal entre comillas o apóstrofes.
En el ejemplo siguiente se usan los dos enfoques para incluir caracteres reservados en una cadena de formato
numérico personalizada.
double n = 9.3;
Console.WriteLine($@"{n:##.0\%}");
Console.WriteLine($@"{n:\'##\'}");
Console.WriteLine($@"{n:\\##\\}");
Console.WriteLine();
Console.WriteLine($"{n:##.0'%'}");
Console.WriteLine($@"{n:'\'##'\'}");
// The example displays the following output:
// 9.3%
// '9'
// \9\
//
// 9.3%
// \9\
Notas
Infinitos de punto flotante y NaN
Independientemente de la cadena de formato, si el valor de un tipo de punto flotante Single o Double es infinito
positivo, infinito negativo o NaN (Not a Number, no es un número), la cadena con formato será el valor de la
propiedad PositiveInfinitySymbol, NegativeInfinitySymbolo NaNSymbol respectiva especificada por el objeto
NumberFormatInfo aplicable actualmente.
Configuración del Panel de control
Los valores de configuración del elemento Configuración regional y de idioma del Panel de control influyen
en la cadena de resultado generada por una operación de formato. Estos valores de configuración se utilizan
para inicializar el objeto NumberFormatInfo asociado a la referencia cultural del subproceso actual, y la
referencia cultural del subproceso actual proporciona valores que se utilizan para controlar el formato. Los
equipos que usan configuraciones diferentes generarán cadenas de resultado distintas.
Asimismo, si se usa el constructor CultureInfo.CultureInfo(String) para crear instancias de un nuevo objeto
CultureInfo que representa la misma referencia cultural que la referencia cultural del sistema actual, cualquier
personalización establecida por el elemento Configuración regional y de idioma del Panel de control se
aplicará al nuevo objeto CultureInfo . Puede usar el constructor CultureInfo.CultureInfo(String, Boolean) para
crear un objeto CultureInfo que no refleje las personalizaciones de un sistema.
Cadenas de formato de punto fijo y redondeo
Para las cadenas de formato de punto fijo (es decir, las cadenas de formato que no contienen caracteres de
formato de notación científica), los números se redondean hasta tantos decimales como marcadores de posición
de dígitos haya a la derecha del separador decimal. Si la cadena de formato no contiene ningún separador
decimal, el número se redondea al entero más próximo. Si el número tiene más dígitos que marcadores de
posición de dígitos a la izquierda del separador decimal, los dígitos adicionales se copian en la cadena de
resultado justo antes del primer marcador de posición de dígitos.
Volver a la tabla
Ejemplo
En el siguiente ejemplo se muestran dos cadenas de formato numérico personalizado. En ambos casos, el
marcador de posición de dígitos ( # ) muestra los datos numéricos, y todos los demás caracteres se copian en la
cadena de resultado.
Volver a la tabla
Vea también
System.Globalization.NumberFormatInfo
Aplicación de formato a tipos
Standard Numeric Format Strings
Cómo: Rellenar un número con ceros a la izquierda
Ejemplo: Utilidad de formato WinForms de .NET Core (C#)
Ejemplo: Utilidad de formato WinForms de .NET Core (Visual Basic)
Cadenas con formato de fecha y hora estándar
13/01/2020 • 53 minutes to read • Edit Online
Una cadena de formato de fecha y hora estándar usa un único especificador de formato para definir la
representación de texto de un valor de fecha y hora. Cualquier cadena con formato de fecha y hora que contenga
más de un carácter, incluido un espacio en blanco, se interpreta como una cadena con formato de fecha y hora
personalizado; para obtener más información, consulte Cadenas con formato de fecha y hora personalizado. Una
cadena de formato estándar o personalizado se puede usar de dos maneras:
Para definir la cadena resultante una operación de formato.
Para definir la representación de texto de un valor de fecha y hora que se puede convertir en un valor
DateTime o DateTimeOffset mediante una operación de análisis.
TIP
Puede descargar la Utilidad de formato, que es una aplicación de .NET Core Windows Forms que permite aplicar cadenas
de formato a valores numéricos o de fecha y hora, y que muestra la cadena de resultado. El código fuente está disponible
para C# y Visual Basic.
Las cadenas con formato de fecha y hora estándar se pueden utilizar tanto con valores DateTime como con
valores DateTimeOffset.
NOTE
Algunos de los ejemplos de C# de este artículo se ejecutan en el ejecutor de código en línea y área de juegos de Try.NET.
Haga clic en el botón Ejecutar para ejecutar un ejemplo en una ventana interactiva. Una vez que se ejecuta el código,
puede modificar y ejecutar el código modificado si vuelve a hacer clic en Ejecutar. El código modificado se ejecuta en la
ventana interactiva o, si se produce un error en la compilación, en la ventana interactiva se muestran todos los mensajes de
error del compilador de C#.
La zona horaria local del ejecutor de código en línea de Try.NET y del área de juegos es la hora universal coordinada o UTC.
Esto puede afectar al comportamiento y la salida de ejemplos que ilustran los tipos DateTime, DateTimeOffset y
TimeZoneInfo y sus miembros.
En la tabla siguiente se describen los especificadores de formato de fecha y hora estándar. A menos que se
indique lo contrario, un determinado especificador de formato de fecha y hora estándar genera una
representación de cadena idéntica independientemente de que se use con un valor DateTime o DateTimeOffset.
Consulte la sección Notas para obtener información adicional sobre cómo usar cadenas de formato de fecha y
hora estándar.
2009-06-15T13:45:30
(DateTimeKind.Utc) --> 2009-06-
15T13:45:30.0000000Z
2009-06-15T13:45:30
(DateTimeKind.Unspecified) --> 2009-
06-15T13:45:30.0000000
Valores de DateTimeOffset:
2009-06-15T13:45:30-07:00 -->
2009-06-15T13:45:30.0000000-07:00
"u" Patrón de fecha y hora universal que se Con un valor DateTime de: 2009-06-
puede ordenar. 15T13:45:30 -> 2009-06-15
13:45:30Z
Más información: El especificador de
formato universal que se puede Con un valor DateTimeOffset de: 2009-
ordenar ("u"). 06-15T13:45:30 -> 2009-06-15
20:45:30Z
ESPECIFICADOR DE FORMATO DESCRIPCIÓN EJEMPLOS
Puede pasar un objeto CultureInfo que represente la referencia cultural cuyo formato se va a usar a un
método que tenga un parámetro IFormatProvider. En el ejemplo siguiente se muestra una fecha con el
formato de fecha abreviado de la referencia cultural pt-BR.
// Display using pt-BR culture's short date format
DateTime thisDate = new DateTime(2008, 3, 15);
CultureInfo culture = new CultureInfo("pt-BR");
Console.WriteLine(thisDate.ToString("d", culture)); // Displays 15/3/2008
Puede pasar un objeto DateTimeFormatInfo que proporcione información sobre el formato a un método
que tenga un parámetro IFormatProvider. En el ejemplo siguiente se muestra una fecha con el formato de
fecha abreviado de un objeto DateTimeFormatInfo en la referencia cultural hr-HR.
NOTE
Para obtener información sobre la personalización de patrones o cadenas usadas para dar formato a valores de fecha y
hora, vea el tema sobre la clase NumberFormatInfo.
En algunos casos, la cadena con formato estándar actúa como la abreviatura correspondiente de una cadena con
formato personalizado más larga que es invariable. Hay cuatro cadenas de formato estándar que pertenecen a
esta categoría: "O" (u "o"), "R" (o "r"), "s" y "u". Estas cadenas se corresponden con las cadenas de formato
personalizado definidas en la referencia cultural de todos los idiomas. Generan representaciones de cadena de
valores de fecha y hora que están pensados para que sean idénticos en todas las referencias culturales. En la
tabla siguiente se proporciona información sobre estas cuatro cadenas de formato de fecha y hora estándar.
SE DEFINE EN LA PROPIEDAD
CADENA CON FORMATO ESTÁNDAR DATETIMEFORMATINFO.INVARIANTINFO CADENA CON FORMATO PERSONALIZADO
Las cadenas de formato estándar también se pueden usar en operaciones de análisis con los métodos
DateTime.ParseExact o DateTimeOffset.ParseExact, que necesitan que una cadena de entrada se ajuste
exactamente a un patrón determinado para que la operación de análisis se realice correctamente. Muchas
cadenas de formato estándar se asignan a varias cadenas de formato personalizado, por lo que un valor de fecha
y hora se pueden representar en diversos formatos y la operación de análisis todavía se realizará correctamente.
Puede determinar la cadena o las cadenas con formato personalizado correspondientes a una cadena con
formato estándar llamando al método DateTimeFormatInfo.GetAllDateTimePatterns(Char). En el ejemplo
siguiente se muestran las cadenas con formato personalizado que se asignan a la cadena de formato estándar "d"
(patrón de fecha corta).
using System;
using System.Globalization;
Imports System.Globalization
Module Example
Public Sub Main()
Console.WriteLine("'d' standard format string:")
For Each customString In DateTimeFormatInfo.CurrentInfo.GetAllDateTimePatterns("d"c)
Console.WriteLine(" {0}", customString)
Next
End Sub
End Module
' The example displays the following output:
' 'd' standard format string:
' M/d/yyyy
' M/d/yy
' MM/dd/yy
' MM/dd/yyyy
' yy/MM/dd
' yyyy-MM-dd
' dd-MMM-yy
En las próximas secciones se describen los especificadores de formato estándar para los valores DateTime y
DateTimeOffset.
En el ejemplo siguiente se usa el especificador de formato "d" para mostrar un valor de fecha y hora.
Volver a la tabla
PROPIEDAD. DESCRIPCIÓN
En el ejemplo siguiente se usa el especificador de formato "D" para mostrar un valor de fecha y hora.
DateTime date1 = new DateTime(2008, 4, 10);
Console.WriteLine(date1.ToString("D",
CultureInfo.CreateSpecificCulture("en-US")));
// Displays Thursday, April 10, 2008
Console.WriteLine(date1.ToString("D",
CultureInfo.CreateSpecificCulture("pt-BR")));
// Displays quinta-feira, 10 de abril de 2008
Console.WriteLine(date1.ToString("D",
CultureInfo.CreateSpecificCulture("es-MX")));
// Displays jueves, 10 de abril de 2008
Volver a la tabla
PROPIEDAD. DESCRIPCIÓN
En el ejemplo siguiente se usa el especificador de formato "f" para mostrar un valor de fecha y hora.
Volver a la tabla
PROPIEDAD. DESCRIPCIÓN
En el ejemplo siguiente se usa el especificador de formato "F" para mostrar un valor de fecha y hora.
DateTime date1 = new DateTime(2008, 4, 10, 6, 30, 0);
Console.WriteLine(date1.ToString("F",
CultureInfo.CreateSpecificCulture("en-US")));
// Displays Thursday, April 10, 2008 6:30:00 AM
Console.WriteLine(date1.ToString("F",
CultureInfo.CreateSpecificCulture("fr-FR")));
// Displays jeudi 10 avril 2008 06:30:00
Volver a la tabla
PROPIEDAD. DESCRIPCIÓN
En el ejemplo siguiente se usa el especificador de formato "g" para mostrar un valor de fecha y hora.
DateTime date1 = new DateTime(2008, 4, 10, 6, 30, 0);
Console.WriteLine(date1.ToString("g",
DateTimeFormatInfo.InvariantInfo));
// Displays 04/10/2008 06:30
Console.WriteLine(date1.ToString("g",
CultureInfo.CreateSpecificCulture("en-us")));
// Displays 4/10/2008 6:30 AM
Console.WriteLine(date1.ToString("g",
CultureInfo.CreateSpecificCulture("fr-BE")));
// Displays 10/04/2008 6:30
Volver a la tabla
PROPIEDAD. DESCRIPCIÓN
En el ejemplo siguiente se usa el especificador de formato "G" para mostrar un valor de fecha y hora.
DateTime date1 = new DateTime(2008, 4, 10, 6, 30, 0);
Console.WriteLine(date1.ToString("G",
DateTimeFormatInfo.InvariantInfo));
// Displays 04/10/2008 06:30:00
Console.WriteLine(date1.ToString("G",
CultureInfo.CreateSpecificCulture("en-us")));
// Displays 4/10/2008 6:30:00 AM
Console.WriteLine(date1.ToString("G",
CultureInfo.CreateSpecificCulture("nl-BE")));
// Displays 10/04/2008 6:30:00
Volver a la tabla
PROPIEDAD. DESCRIPCIÓN
En el ejemplo siguiente se usa el especificador de formato "m" para mostrar un valor de fecha y hora.
Module Example
Public Sub Main()
Dim dat As New Date(2009, 6, 15, 13, 45, 30,
DateTimeKind.Unspecified)
Console.WriteLine("{0} ({1}) --> {0:O}", dat, dat.Kind)
En el ejemplo siguiente se usa el especificador de formato "o" para crear una cadena con formato y, a
continuación, se restaura el valor de fecha y hora original llamando a un método Parse de fecha y hora.
// Round-trip DateTime values.
DateTime originalDate, newDate;
string dateString;
// Round-trip a local time.
originalDate = DateTime.SpecifyKind(new DateTime(2008, 4, 10, 6, 30, 0), DateTimeKind.Local);
dateString = originalDate.ToString("o");
newDate = DateTime.Parse(dateString, null, DateTimeStyles.RoundtripKind);
Console.WriteLine("Round-tripped {0} {1} to {2} {3}.", originalDate, originalDate.Kind,
newDate, newDate.Kind);
// Round-trip a UTC time.
originalDate = DateTime.SpecifyKind(new DateTime(2008, 4, 12, 9, 30, 0), DateTimeKind.Utc);
dateString = originalDate.ToString("o");
newDate = DateTime.Parse(dateString, null, DateTimeStyles.RoundtripKind);
Console.WriteLine("Round-tripped {0} {1} to {2} {3}.", originalDate, originalDate.Kind,
newDate, newDate.Kind);
// Round-trip time in an unspecified time zone.
originalDate = DateTime.SpecifyKind(new DateTime(2008, 4, 13, 12, 30, 0), DateTimeKind.Unspecified);
dateString = originalDate.ToString("o");
newDate = DateTime.Parse(dateString, null, DateTimeStyles.RoundtripKind);
Console.WriteLine("Round-tripped {0} {1} to {2} {3}.", originalDate, originalDate.Kind,
newDate, newDate.Kind);
Volver a la tabla
PROPIEDAD. DESCRIPCIÓN
Aunque la norma RFC 1123 expresa una hora según la hora universal coordinada (hora UTC ), la operación de
formato no modifica el valor del objeto DateTime al que se está dando formato. Por consiguiente, debe convertir
el valor DateTime en una hora UTC llamando al método DateTime.ToUniversalTime antes de realizar la
operación de formato. En cambio, los valores DateTimeOffset realizan esta conversión automáticamente; no es
necesario llamar al método DateTimeOffset.ToUniversalTime antes de la operación de formato.
En el ejemplo siguiente se utiliza el especificador de formato "r" para mostrar un DateTime y un
valor DateTimeOffset en un sistema de la zona horaria del Pacífico de EE. UU.
Volver a la tabla
Volver a la tabla
El especificador de formato de hora corta ("t")
El especificador de formato estándar "t" representa una cadena de formato de fecha y hora personalizado que
está definida por la propiedad DateTimeFormatInfo.ShortTimePattern actual. Por ejemplo, la cadena de formato
personalizado para la referencia cultural de todos los idiomas es "HH:mm".
La información de formato de un objeto DateTimeFormatInfo específico afecta a la cadena de resultado. En la
tabla siguiente se enumeran las propiedades del objeto DateTimeFormatInfo que pueden controlar el formato de
la cadena devuelta. El especificador de formato personalizado devuelto por la propiedad
DateTimeFormatInfo.ShortTimePattern de algunas referencias culturales quizás no use todas las propiedades.
PROPIEDAD. DESCRIPCIÓN
En el ejemplo siguiente se usa el especificador de formato "t" para mostrar un valor de fecha y hora.
Volver a la tabla
En el ejemplo siguiente se usa el especificador de formato "T" para mostrar un valor de fecha y hora.
Volver a la tabla
Volver a la tabla
PROPIEDAD. DESCRIPCIÓN
El especificador de formato "U" no es compatible con el tipo DateTimeOffset y provoca una excepción
FormatException si se usa para dar formato a un valor DateTimeOffset.
En el ejemplo siguiente se usa el especificador de formato "U" para mostrar un valor de fecha y hora.
PROPIEDAD. DESCRIPCIÓN
En el ejemplo siguiente se usa el especificador de formato "y" para mostrar un valor de fecha y hora.
Volver a la tabla
Notas
Configuración del Panel de control
Los valores de configuración del elemento Configuración regional y de idioma del Panel de control influyen
en la cadena de resultado generada por una operación de formato. Estas configuraciones se utilizan para
inicializar el objeto DateTimeFormatInfo asociado a la referencia cultural del subproceso actual, que proporciona
valores que se utilizan para controlar el formato. Los equipos que usan configuraciones diferentes generarán
cadenas de resultado distintas.
Asimismo, si se usa el constructor CultureInfo.CultureInfo(String) para crear instancias de un nuevo objeto
CultureInfo que representa la misma referencia cultural que la referencia cultural del sistema actual, cualquier
personalización establecida por el elemento Configuración regional y de idioma del Panel de control se
aplicará al nuevo objeto CultureInfo . Puede usar el constructor CultureInfo.CultureInfo(String, Boolean) para
crear un objeto CultureInfo que no refleje las personalizaciones de un sistema.
Propiedades de DateTimeFormatInfo
El formato se ve influenciado por las propiedades del objeto DateTimeFormatInfo actual, proporcionado
implícitamente por la referencia cultural del subproceso actual o explícitamente por el parámetro
IFormatProvider del método que invoca el formato. En el parámetro IFormatProvider, la aplicación debe
especificar un objeto CultureInfo, que representa una referencia cultural, o un objeto DateTimeFormatInfo, que
representa las convenciones de formato de fecha y hora de una determinada referencia cultural. Muchos de los
especificadores de formato de fecha y hora estándar son alias de patrones de formato definidos en las
propiedades del objeto DateTimeFormatInfo actual. La aplicación puede modificar el resultado generado por
algunos especificadores de formato de fecha y hora estándar al cambiar los patrones de formato de fecha y hora
correspondientes de la propiedad DateTimeFormatInfo apropiada.
Vea también
System.DateTime
System.DateTimeOffset
Aplicación de formato a tipos
Custom Date and Time Format Strings
Ejemplo: Utilidad de formato WinForms de .NET Core (C#)
Ejemplo: Utilidad de formato WinForms de .NET Core (Visual Basic)
Cadenas con formato de fecha y hora personalizado
13/01/2020 • 94 minutes to read • Edit Online
Una cadena con formato de fecha y hora define la representación de texto de un valor DateTime o
DateTimeOffset que es el resultado de una operación de formato. También puede definir la representación de un
valor de fecha y hora que se necesite en una operación de análisis para convertir correctamente la cadena en una
fecha y hora. Una cadena de formato personalizado consta de uno o varios especificadores de formato de fecha
y hora personalizado. Una cadena que no sea una cadena con formato de fecha y hora estándar se interpreta
como una cadena con formato de fecha y hora personalizado.
TIP
Puede descargar la Utilidad de formato, que es una aplicación de .NET Core Windows Forms que permite aplicar cadenas
de formato a valores numéricos o de fecha y hora, y que muestra la cadena de resultado. El código fuente está disponible
para C# y Visual Basic.
Las cadenas con formato de fecha y hora personalizado se pueden utilizar tanto con valores DateTime como con
valores DateTimeOffset.
NOTE
Algunos de los ejemplos de C# de este artículo se ejecutan en el ejecutor de código en línea y área de juegos de Try.NET.
Haga clic en el botón Ejecutar para ejecutar un ejemplo en una ventana interactiva. Una vez que se ejecuta el código,
puede modificar y ejecutar el código modificado si vuelve a hacer clic en Ejecutar. El código modificado se ejecuta en la
ventana interactiva o, si se produce un error en la compilación, en la ventana interactiva se muestran todos los mensajes
de error del compilador de C#.
La zona horaria local del ejecutor de código en línea de Try.NET y del área de juegos es la hora universal coordinada o UTC.
Esto puede afectar al comportamiento y la salida de ejemplos que ilustran los tipos DateTime, DateTimeOffset y
TimeZoneInfo y sus miembros.
En operaciones de formato, las cadenas de formato de fecha y hora personalizado se pueden usar con el método
ToString de una instancia de fecha y hora o con un método que admita formato compuesto. En el ejemplo
siguiente se muestran ambos usos.
En las operaciones de análisis, las cadenas de formato de fecha y hora personalizado se pueden usar con los
métodos DateTime.ParseExact, DateTime.TryParseExact, DateTimeOffset.ParseExact y
DateTimeOffset.TryParseExact. Estos métodos necesitan que una cadena de entrada se ajuste exactamente a un
modelo determinado para que la operación de análisis se realice correctamente. En el ejemplo siguiente se
muestra una llamada al método DateTimeOffset.ParseExact(String, String, IFormatProvider) para analizar una
fecha que debe incluir un día, un mes y un año de dos dígitos.
using System;
using System.Globalization;
Module Example
Public Sub Main()
Dim dateValues() As String = { "30-12-2011", "12-30-2011",
"30-12-11", "12-30-11" }
Dim pattern As String = "MM-dd-yy"
Dim parsedDate As Date
En la tabla siguiente se describen los especificadores de formato de fecha y hora personalizados, y se muestra la
cadena de resultado producida por cada especificador de formato. De forma predeterminada, las cadenas de
resultado reflejan las convenciones de formato de la referencia cultural en-us. Si un especificador de formato
determinado genera una cadena de resultado localizada, el ejemplo también indica la referencia cultural a la que
se aplica dicha cadena. Para más información sobre cómo usar cadenas de formato de fecha y hora
personalizado, vea la sección Notas.
2009-06-15T01:45:30-07:00 --> -
07:00
2009-06-15T08:45:30+00:00 -->
+00:00
2009-06-15T13:45:30 -> 9
2019-06-15T13:45:30 -> 19
2019-06-15T13:45:30 -> 19
En las secciones siguientes se proporciona información adicional sobre cada especificador de formato de fecha y
hora personalizado. A menos que se indique lo contrario, cada especificador genera una representación de
cadena idéntica independientemente de que se use con un valor DateTime o DateTimeOffset.
Console.WriteLine(date1.ToString("d, M",
CultureInfo.InvariantCulture));
// Displays 29, 8
Console.WriteLine(date1.ToString("d MMMM",
CultureInfo.CreateSpecificCulture("en-US")));
// Displays 29 August
Console.WriteLine(date1.ToString("d MMMM",
CultureInfo.CreateSpecificCulture("es-MX")));
// Displays 29 agosto
Console.WriteLine(date1.ToString("d, M", _
CultureInfo.InvariantCulture))
' Displays 29, 8
Console.WriteLine(date1.ToString("d MMMM", _
CultureInfo.CreateSpecificCulture("en-US")))
' Displays 29 August
Console.WriteLine(date1.ToString("d MMMM", _
CultureInfo.CreateSpecificCulture("es-MX")))
' Displays 29 agosto
Volver a la tabla
Console.WriteLine(date1.ToString("dd, MM",
CultureInfo.InvariantCulture));
// 02, 01
Console.WriteLine(date1.ToString("dd, MM", _
CultureInfo.InvariantCulture))
' 02, 01
Volver a la tabla
Console.WriteLine(date1.ToString("ddd d MMM",
CultureInfo.CreateSpecificCulture("en-US")));
// Displays Fri 29 Aug
Console.WriteLine(date1.ToString("ddd d MMM",
CultureInfo.CreateSpecificCulture("fr-FR")));
// Displays ven. 29 août
Console.WriteLine(date1.ToString("ddd d MMM", _
CultureInfo.CreateSpecificCulture("en-US")))
' Displays Fri 29 Aug
Console.WriteLine(date1.ToString("ddd d MMM", _
CultureInfo.CreateSpecificCulture("fr-FR")))
' Displays ven. 29 août
Volver a la tabla
Console.WriteLine(date1.ToString("dddd dd MMMM",
CultureInfo.CreateSpecificCulture("en-US")));
// Displays Friday 29 August
Console.WriteLine(date1.ToString("dddd dd MMMM",
CultureInfo.CreateSpecificCulture("it-IT")));
// Displays venerdì 29 agosto
Console.WriteLine(date1.ToString("dddd dd MMMM", _
CultureInfo.CreateSpecificCulture("en-US")))
' Displays Friday 29 August
Console.WriteLine(date1.ToString("dddd dd MMMM", _
CultureInfo.CreateSpecificCulture("it-IT")))
' Displays venerdì 29 agosto
Volver a la tabla
Console.WriteLine(date1.ToString("hh:mm:ss.f", ci));
// Displays 07:27:15.0
Console.WriteLine(date1.ToString("hh:mm:ss.F", ci));
// Displays 07:27:15
Console.WriteLine(date1.ToString("hh:mm:ss.ff", ci));
// Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.FF", ci));
// Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.fff", ci));
// Displays 07:27:15.018
Console.WriteLine(date1.ToString("hh:mm:ss.FFF", ci));
// Displays 07:27:15.018
Dim date1 As New Date(2008, 8, 29, 19, 27, 15, 018)
Dim ci As CultureInfo = CultureInfo.InvariantCulture
Console.WriteLine(date1.ToString("hh:mm:ss.f", ci))
' Displays 07:27:15.0
Console.WriteLine(date1.ToString("hh:mm:ss.F", ci))
' Displays 07:27:15
Console.WriteLine(date1.ToString("hh:mm:ss.ff", ci))
' Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.FF", ci))
' Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.fff", ci))
' Displays 07:27:15.018
Console.WriteLine(date1.ToString("hh:mm:ss.FFF", ci))
' Displays 07:27:15.018
Volver a la tabla
Console.WriteLine(date1.ToString("hh:mm:ss.f", ci));
// Displays 07:27:15.0
Console.WriteLine(date1.ToString("hh:mm:ss.F", ci));
// Displays 07:27:15
Console.WriteLine(date1.ToString("hh:mm:ss.ff", ci));
// Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.FF", ci));
// Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.fff", ci));
// Displays 07:27:15.018
Console.WriteLine(date1.ToString("hh:mm:ss.FFF", ci));
// Displays 07:27:15.018
Console.WriteLine(date1.ToString("hh:mm:ss.f", ci))
' Displays 07:27:15.0
Console.WriteLine(date1.ToString("hh:mm:ss.F", ci))
' Displays 07:27:15
Console.WriteLine(date1.ToString("hh:mm:ss.ff", ci))
' Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.FF", ci))
' Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.fff", ci))
' Displays 07:27:15.018
Console.WriteLine(date1.ToString("hh:mm:ss.FFF", ci))
' Displays 07:27:15.018
Volver a la tabla
Especificador de formato personalizado "fff"
El especificador de formato personalizado "fff" representa los tres dígitos más significativos de la fracción de
segundos; es decir, representa los milisegundos de un valor de fecha y hora.
En el ejemplo siguiente se incluye el especificador de formato personalizado "fff" en una cadena de formato
personalizado.
Console.WriteLine(date1.ToString("hh:mm:ss.f", ci));
// Displays 07:27:15.0
Console.WriteLine(date1.ToString("hh:mm:ss.F", ci));
// Displays 07:27:15
Console.WriteLine(date1.ToString("hh:mm:ss.ff", ci));
// Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.FF", ci));
// Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.fff", ci));
// Displays 07:27:15.018
Console.WriteLine(date1.ToString("hh:mm:ss.FFF", ci));
// Displays 07:27:15.018
Console.WriteLine(date1.ToString("hh:mm:ss.f", ci))
' Displays 07:27:15.0
Console.WriteLine(date1.ToString("hh:mm:ss.F", ci))
' Displays 07:27:15
Console.WriteLine(date1.ToString("hh:mm:ss.ff", ci))
' Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.FF", ci))
' Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.fff", ci))
' Displays 07:27:15.018
Console.WriteLine(date1.ToString("hh:mm:ss.FFF", ci))
' Displays 07:27:15.018
Volver a la tabla
Console.WriteLine(date1.ToString("hh:mm:ss.f", ci));
// Displays 07:27:15.0
Console.WriteLine(date1.ToString("hh:mm:ss.F", ci));
// Displays 07:27:15
Console.WriteLine(date1.ToString("hh:mm:ss.ff", ci));
// Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.FF", ci));
// Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.fff", ci));
// Displays 07:27:15.018
Console.WriteLine(date1.ToString("hh:mm:ss.FFF", ci));
// Displays 07:27:15.018
Console.WriteLine(date1.ToString("hh:mm:ss.f", ci))
' Displays 07:27:15.0
Console.WriteLine(date1.ToString("hh:mm:ss.F", ci))
' Displays 07:27:15
Console.WriteLine(date1.ToString("hh:mm:ss.ff", ci))
' Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.FF", ci))
' Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.fff", ci))
' Displays 07:27:15.018
Console.WriteLine(date1.ToString("hh:mm:ss.FFF", ci))
' Displays 07:27:15.018
Volver a la tabla
Console.WriteLine(date1.ToString("hh:mm:ss.f", ci));
// Displays 07:27:15.0
Console.WriteLine(date1.ToString("hh:mm:ss.F", ci));
// Displays 07:27:15
Console.WriteLine(date1.ToString("hh:mm:ss.ff", ci));
// Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.FF", ci));
// Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.fff", ci));
// Displays 07:27:15.018
Console.WriteLine(date1.ToString("hh:mm:ss.FFF", ci));
// Displays 07:27:15.018
Dim date1 As New Date(2008, 8, 29, 19, 27, 15, 018)
Dim ci As CultureInfo = CultureInfo.InvariantCulture
Console.WriteLine(date1.ToString("hh:mm:ss.f", ci))
' Displays 07:27:15.0
Console.WriteLine(date1.ToString("hh:mm:ss.F", ci))
' Displays 07:27:15
Console.WriteLine(date1.ToString("hh:mm:ss.ff", ci))
' Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.FF", ci))
' Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.fff", ci))
' Displays 07:27:15.018
Console.WriteLine(date1.ToString("hh:mm:ss.FFF", ci))
' Displays 07:27:15.018
Volver a la tabla
Console.WriteLine(date1.ToString("hh:mm:ss.f", ci));
// Displays 07:27:15.0
Console.WriteLine(date1.ToString("hh:mm:ss.F", ci));
// Displays 07:27:15
Console.WriteLine(date1.ToString("hh:mm:ss.ff", ci));
// Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.FF", ci));
// Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.fff", ci));
// Displays 07:27:15.018
Console.WriteLine(date1.ToString("hh:mm:ss.FFF", ci));
// Displays 07:27:15.018
Console.WriteLine(date1.ToString("hh:mm:ss.f", ci))
' Displays 07:27:15.0
Console.WriteLine(date1.ToString("hh:mm:ss.F", ci))
' Displays 07:27:15
Console.WriteLine(date1.ToString("hh:mm:ss.ff", ci))
' Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.FF", ci))
' Displays 07:27:15.01
Console.WriteLine(date1.ToString("hh:mm:ss.fff", ci))
' Displays 07:27:15.018
Console.WriteLine(date1.ToString("hh:mm:ss.FFF", ci))
' Displays 07:27:15.018
Volver a la tabla
Especificador de formato personalizado "FFFF"
El especificador de formato personalizado "FFFF" representa los cuatro dígitos más significativos de la fracción
de segundos; es decir, representa las diezmilésimas de segundo de un valor de fecha y hora. Sin embargo, no se
muestran los ceros finales ni los dígitos de cuatro ceros.
Si bien se puede mostrar el componente correspondiente a las diezmilésimas de segundo de un valor de hora, es
muy posible que ese valor no sea significativo. La precisión de los valores de fecha y hora depende de la
resolución del reloj del sistema. En los sistemas operativos Windows NT 3.5 (y versiones posteriores) y
Windows Vista, la resolución del reloj es aproximadamente de 10 a 15 milisegundos.
Volver a la tabla
Console.WriteLine(date1.ToString("MM/dd/yyyy g",
CultureInfo.InvariantCulture));
// Displays 08/04/0070 A.D.
Console.WriteLine(date1.ToString("MM/dd/yyyy g",
CultureInfo.CreateSpecificCulture("fr-FR")));
// Displays 08/04/0070 ap. J.-C.
Console.WriteLine(date1.ToString("MM/dd/yyyy g", _
CultureInfo.InvariantCulture))
' Displays 08/04/0070 A.D.
Console.WriteLine(date1.ToString("MM/dd/yyyy g", _
CultureInfo.CreateSpecificCulture("fr-FR")))
' Displays 08/04/0070 ap. J.-C.
Volver a la tabla
Volver a la tabla
Volver a la tabla
Volver a la tabla
Console.WriteLine(Date.Now.ToString("%K"))
' Displays -07:00
Console.WriteLine(Date.UtcNow.ToString("%K"))
' Displays Z
Console.WriteLine("'{0}'", _
Date.SpecifyKind(Date.Now, _
DateTimeKind.Unspecified). _
ToString("%K"))
' Displays ''
Console.WriteLine(DateTimeOffset.Now.ToString("%K"))
' Displays -07:00
Console.WriteLine(DateTimeOffset.UtcNow.ToString("%K"))
' Displays +00:00
Console.WriteLine(New DateTimeOffset(2008, 5, 1, 6, 30, 0, _
New TimeSpan(5, 0, 0)). _
ToString("%K"))
' Displays +05:00
Volver a la tabla
Volver a la tabla
DateTime date1;
date1 = new DateTime(2008, 1, 1, 18, 9, 1);
Console.WriteLine(date1.ToString("hh:mm:ss tt",
CultureInfo.InvariantCulture));
// Displays 06:09:01 PM
Console.WriteLine(date1.ToString("hh:mm:ss tt",
CultureInfo.CreateSpecificCulture("hu-HU")));
// Displays 06:09:01 du.
date1 = new DateTime(2008, 1, 1, 18, 9, 1, 500);
Console.WriteLine(date1.ToString("hh:mm:ss.ff tt",
CultureInfo.InvariantCulture));
// Displays 06:09:01.50 PM
Console.WriteLine(date1.ToString("hh:mm:ss.ff tt",
CultureInfo.CreateSpecificCulture("hu-HU")));
// Displays 06:09:01.50 du.
Dim date1 As Date
date1 = #6:09:01PM#
Console.WriteLine(date1.ToString("hh:mm:ss tt", _
CultureInfo.InvariantCulture))
' Displays 06:09:01 PM
Console.WriteLine(date1.ToString("hh:mm:ss tt", _
CultureInfo.CreateSpecificCulture("hu-HU")))
' Displays 06:09:01 du.
date1 = New Date(2008, 1, 1, 18, 9, 1, 500)
Console.WriteLine(date1.ToString("hh:mm:ss.ff tt", _
CultureInfo.InvariantCulture))
' Displays 06:09:01.50 PM
Console.WriteLine(date1.ToString("hh:mm:ss.ff tt", _
CultureInfo.CreateSpecificCulture("hu-HU")))
' Displays 06:09:01.50 du.
Volver a la tabla
Volver a la tabla
Console.WriteLine(date1.ToString("dd, MM",
CultureInfo.InvariantCulture));
// 02, 01
Console.WriteLine(date1.ToString("dd, MM", _
CultureInfo.InvariantCulture))
' 02, 01
Volver a la tabla
Console.WriteLine(date1.ToString("ddd d MMM",
CultureInfo.CreateSpecificCulture("en-US")));
// Displays Fri 29 Aug
Console.WriteLine(date1.ToString("ddd d MMM",
CultureInfo.CreateSpecificCulture("fr-FR")));
// Displays ven. 29 août
Console.WriteLine(date1.ToString("ddd d MMM", _
CultureInfo.CreateSpecificCulture("en-US")))
' Displays Fri 29 Aug
Console.WriteLine(date1.ToString("ddd d MMM", _
CultureInfo.CreateSpecificCulture("fr-FR")))
' Displays ven. 29 août
Volver a la tabla
Console.WriteLine(date1.ToString("dddd dd MMMM",
CultureInfo.CreateSpecificCulture("en-US")));
// Displays Friday 29 August
Console.WriteLine(date1.ToString("dddd dd MMMM",
CultureInfo.CreateSpecificCulture("it-IT")));
// Displays venerdì 29 agosto
Console.WriteLine(date1.ToString("dddd dd MMMM", _
CultureInfo.CreateSpecificCulture("en-US")))
' Displays Friday 29 August
Console.WriteLine(date1.ToString("dddd dd MMMM", _
CultureInfo.CreateSpecificCulture("it-IT")))
' Displays venerdì 29 agosto
Volver a la tabla
DateTime date1;
date1 = new DateTime(2008, 1, 1, 18, 9, 1);
Console.WriteLine(date1.ToString("h:m:s.F t",
CultureInfo.InvariantCulture));
// Displays 6:9:1 P
Console.WriteLine(date1.ToString("h:m:s.F t",
CultureInfo.CreateSpecificCulture("el-GR")));
// Displays 6:9:1 µ
date1 = new DateTime(2008, 1, 1, 18, 9, 1, 500);
Console.WriteLine(date1.ToString("h:m:s.F t",
CultureInfo.InvariantCulture));
// Displays 6:9:1.5 P
Console.WriteLine(date1.ToString("h:m:s.F t",
CultureInfo.CreateSpecificCulture("el-GR")));
// Displays 6:9:1.5 µ
Dim date1 As Date
date1 = #6:09:01PM#
Console.WriteLine(date1.ToString("h:m:s.F t", _
CultureInfo.InvariantCulture))
' Displays 6:9:1 P
Console.WriteLine(date1.ToString("h:m:s.F t", _
CultureInfo.CreateSpecificCulture("el-GR")))
' Displays 6:9:1 µ
date1 = New Date(2008, 1, 1, 18, 9, 1, 500)
Console.WriteLine(date1.ToString("h:m:s.F t", _
CultureInfo.InvariantCulture))
' Displays 6:9:1.5 P
Console.WriteLine(date1.ToString("h:m:s.F t", _
CultureInfo.CreateSpecificCulture("el-GR")))
' Displays 6:9:1.5 µ
Volver a la tabla
DateTime date1;
date1 = new DateTime(2008, 1, 1, 18, 9, 1);
Console.WriteLine(date1.ToString("hh:mm:ss tt",
CultureInfo.InvariantCulture));
// Displays 06:09:01 PM
Console.WriteLine(date1.ToString("hh:mm:ss tt",
CultureInfo.CreateSpecificCulture("hu-HU")));
// Displays 06:09:01 du.
date1 = new DateTime(2008, 1, 1, 18, 9, 1, 500);
Console.WriteLine(date1.ToString("hh:mm:ss.ff tt",
CultureInfo.InvariantCulture));
// Displays 06:09:01.50 PM
Console.WriteLine(date1.ToString("hh:mm:ss.ff tt",
CultureInfo.CreateSpecificCulture("hu-HU")));
// Displays 06:09:01.50 du.
Volver a la tabla
Especificador de formato personalizado "t"
El especificador de formato personalizado "t" representa el primer carácter del designador AM/PM. El
designador adaptado adecuado se recupera de la propiedad DateTimeFormatInfo.AMDesignator o
DateTimeFormatInfo.PMDesignator de la referencia cultural actual o especificada. El designador AM se usa para
todas las horas de 0:00:00 (medianoche) a 11:59:59.999. El designador PM se usa para todas las horas de
12:00:00 (mediodía) a 23:59:59.999.
Si el especificador de formato "t" se usa sin otros especificadores de formato personalizado, se interpretará
como el especificador de formato de fecha y hora estándar "t". Para más información sobre cómo usar un
especificador de formato único, vea Usar especificadores de formato personalizado únicos más adelante en este
artículo.
En el ejemplo siguiente se incluye el especificador de formato personalizado "t" en una cadena de formato
personalizado.
DateTime date1;
date1 = new DateTime(2008, 1, 1, 18, 9, 1);
Console.WriteLine(date1.ToString("h:m:s.F t",
CultureInfo.InvariantCulture));
// Displays 6:9:1 P
Console.WriteLine(date1.ToString("h:m:s.F t",
CultureInfo.CreateSpecificCulture("el-GR")));
// Displays 6:9:1 µ
date1 = new DateTime(2008, 1, 1, 18, 9, 1, 500);
Console.WriteLine(date1.ToString("h:m:s.F t",
CultureInfo.InvariantCulture));
// Displays 6:9:1.5 P
Console.WriteLine(date1.ToString("h:m:s.F t",
CultureInfo.CreateSpecificCulture("el-GR")));
// Displays 6:9:1.5 µ
Volver a la tabla
DateTime date1;
date1 = new DateTime(2008, 1, 1, 18, 9, 1);
Console.WriteLine(date1.ToString("hh:mm:ss tt",
CultureInfo.InvariantCulture));
// Displays 06:09:01 PM
Console.WriteLine(date1.ToString("hh:mm:ss tt",
CultureInfo.CreateSpecificCulture("hu-HU")));
// Displays 06:09:01 du.
date1 = new DateTime(2008, 1, 1, 18, 9, 1, 500);
Console.WriteLine(date1.ToString("hh:mm:ss.ff tt",
CultureInfo.InvariantCulture));
// Displays 06:09:01.50 PM
Console.WriteLine(date1.ToString("hh:mm:ss.ff tt",
CultureInfo.CreateSpecificCulture("hu-HU")));
// Displays 06:09:01.50 du.
Volver a la tabla
Volver a la tabla
cal.TwoDigitYearMax = 2099;
CultureInfo culture = (CultureInfo) CultureInfo.CurrentCulture.Clone();
culture.DateTimeFormat.Calendar = cal;
Thread.CurrentThread.CurrentCulture = culture;
Module Example
Public Sub Main()
Dim fmt As String = "dd-MMM-yy"
Dim value As String = "24-Jan-49"
cal.TwoDigitYearMax = 2099
Dim culture As CultureInfo = CType(CultureInfo.CurrentCulture.Clone(), CultureInfo)
culture.DateTimeFormat.Calendar = cal
Thread.CurrentThread.CurrentCulture = culture
En el ejemplo siguiente se incluye el especificador de formato personalizado "yy" en una cadena de formato
personalizado.
Volver a la tabla
NOTE
Para el calendario budista tailandés, que puede tener años de cinco dígitos, este especificador de formato muestra todos
los dígitos significativos.
En el ejemplo siguiente se incluye el especificador de formato personalizado "yyy" en una cadena de formato
personalizado.
DateTime date1 = new DateTime(1, 12, 1);
DateTime date2 = new DateTime(2010, 1, 1);
Console.WriteLine(date1.ToString("%y"));
// Displays 1
Console.WriteLine(date1.ToString("yy"));
// Displays 01
Console.WriteLine(date1.ToString("yyy"));
// Displays 001
Console.WriteLine(date1.ToString("yyyy"));
// Displays 0001
Console.WriteLine(date1.ToString("yyyyy"));
// Displays 00001
Console.WriteLine(date2.ToString("%y"));
// Displays 10
Console.WriteLine(date2.ToString("yy"));
// Displays 10
Console.WriteLine(date2.ToString("yyy"));
// Displays 2010
Console.WriteLine(date2.ToString("yyyy"));
// Displays 2010
Console.WriteLine(date2.ToString("yyyyy"));
// Displays 02010
Volver a la tabla
NOTE
En el calendario budista tailandés, que puede tener años de cinco dígitos, este especificador de formato muestra un
mínimo de cuatro dígitos.
En el ejemplo siguiente se incluye el especificador de formato personalizado "yyyy" en una cadena de formato
personalizado.
Volver a la tabla
Volver a la tabla
Volver a la tabla
Volver a la tabla
Volver a la tabla
NOTE
Para cambiar el separador de hora en una determinada cadena de fecha y hora, especifique el carácter separador en un
delimitador de cadena literal. Por ejemplo, la cadena de formato personalizado hh'_'dd'_'ss genera una cadena en que
"_" (guion bajo) siempre se utiliza como separador de hora. Para cambiar el separador de hora en todas las fechas de una
referencia cultural, cambie el valor de la propiedad DateTimeFormatInfo.TimeSeparator de la referencia cultural actual, o
cree una instancia de un objeto DateTimeFormatInfo, asigne el carácter a su propiedad TimeSeparator y llame a una
sobrecarga del método de formato que incluya un parámetro IFormatProvider.
Si el especificador de formato ":" se usa sin otros especificadores de formato personalizado, se interpretará como
un especificador de formato de fecha y hora estándar y producirá una excepción FormatException. Para más
información sobre cómo usar un especificador de formato único, vea Usar especificadores de formato
personalizado únicos más adelante en este artículo.
Volver a la tabla
NOTE
Para cambiar el separador de fecha en una determinada cadena de fecha y hora, especifique el carácter separador en un
delimitador de cadena literal. Por ejemplo, la cadena de formato personalizado mm'/'dd'/'yyyy genera una cadena en
que "/" siempre se utiliza como separador de fecha. Para cambiar el separador de fecha en todas las fechas de una
referencia cultural, cambie el valor de la propiedad DateTimeFormatInfo.DateSeparator de la referencia cultural actual, o
cree una instancia de un objeto DateTimeFormatInfo, asigne el carácter a su propiedad DateSeparator y llame a una
sobrecarga del método de formato que incluya un parámetro IFormatProvider.
Si el especificador de formato "/" se usa sin otros especificadores de formato personalizado, se interpretará
como un especificador de formato de fecha y hora estándar y producirá una excepción FormatException. Para
más información sobre cómo usar un especificador de formato único, vea Usar especificadores de formato
personalizado únicos más adelante en este artículo.
Volver a la tabla
Literales de carácter
Los siguientes caracteres de una cadena de formato de fecha y hora personalizado están reservados y siempre
se interpretan como caracteres de formato o, en el caso de ", ', / y \, como caracteres especiales.
F H K M d
f e h m s
m y z % :
/ " ' \
Todos los demás caracteres se interpretan siempre como literales de carácter y, en una operación de formato, se
incluyen en la cadena de resultado sin modificar. En una operación de análisis, deben coincidir exactamente con
los caracteres de la cadena de entrada; la comparación distingue entre mayúsculas y minúsculas.
En el ejemplo siguiente se incluyen los caracteres literales "PST" (para hora estándar del Pacífico) y "PDT" (para
horario de verano del Pacífico) para representar la zona horaria local en una cadena de formato. Tenga en cuenta
que la cadena se incluye en la cadena de resultado y que una cadena que incluye la cadena de zona horaria local
también se analiza correctamente.
using System;
using System.Globalization;
// Parse a string.
String value = "25 Dec 2016 12:00 pm PST";
DateTime newDate;
if (DateTime.TryParseExact(value, formats, null,
DateTimeStyles.None, out newDate))
Console.WriteLine(newDate);
else
Console.WriteLine("Unable to parse '{0}'", value);
}
}
// The example displays the following output:
// 18 Aug 2016 04:50 PM PDT
// 12/25/2016 12:00:00 PM
Imports System.Globalization
Module Example
Public Sub Main()
Dim formats() As String = { "dd MMM yyyy hh:mm tt PST",
"dd MMM yyyy hh:mm tt PDT" }
Dim dat As New Date(2016, 8, 18, 16, 50, 0)
' Display the result string.
Console.WriteLine(dat.ToString(formats(1)))
Hay dos formas de indicar que los caracteres se han de interpretar como caracteres literales y no como
caracteres de reserva, para que se puedan incluir en una cadena de resultado o analizarse correctamente en una
cadena de entrada:
Al incluir un escape con cada carácter reservado. Para obtener más información, consulte Usar el carácter de
escape.
En el ejemplo siguiente se incluyen los caracteres literales "pst" (para hora estándar del Pacífico) para
representar la zona horaria local en una cadena de formato. Como "s" y "t" son cadenas de formato
personalizado, ambos caracteres deben incluir un escape para interpretarse como literales de carácter.
using System;
using System.Globalization;
// Parse a string.
String value = "25 Dec 2016 12:00 pm pst";
DateTime newDate;
if (DateTime.TryParseExact(value, format, null,
DateTimeStyles.None, out newDate))
Console.WriteLine(newDate);
else
Console.WriteLine("Unable to parse '{0}'", value);
}
}
// The example displays the following output:
// 18 Aug 2016 04:50 PM PDT
// 12/25/2016 12:00:00 PM
Imports System.Globalization
Module Example
Public Sub Main()
Dim fmt As String = "dd MMM yyyy hh:mm tt p\s\t"
Dim dat As New Date(2016, 8, 18, 16, 50, 0)
' Display the result string.
Console.WriteLine(dat.ToString(fmt))
Al incluir toda la cadena literal entre comillas o apóstrofes. El siguiente ejemplo es igual al anterior, excepto
que "pst" se incluye entre comillas para indicar que toda la cadena delimitada debe interpretarse como
literales de carácter.
using System;
using System.Globalization;
// Parse a string.
String value = "25 Dec 2016 12:00 pm pst";
DateTime newDate;
if (DateTime.TryParseExact(value, format, null,
DateTimeStyles.None, out newDate))
Console.WriteLine(newDate);
else
Console.WriteLine("Unable to parse '{0}'", value);
}
}
// The example displays the following output:
// 18 Aug 2016 04:50 PM PDT
// 12/25/2016 12:00:00 PM
Imports System.Globalization
Module Example
Public Sub Main()
Dim fmt As String = "dd MMM yyyy hh:mm tt ""pst"""
Dim dat As New Date(2016, 8, 18, 16, 50, 0)
' Display the result string.
Console.WriteLine(dat.ToString(fmt))
Notas
Usar especificadores de formato personalizado únicos
Una cadena con formato de fecha y hora personalizado se compone de dos o más caracteres. Los métodos de
formato de fecha y hora interpretan cualquier cadena de un único carácter como una cadena de formato de
fecha y hora estándar. Si no reconocen el carácter como un especificador de formato válido, producen una
excepción FormatException. Por ejemplo, una cadena de formato que solo se compone del especificador "h" se
interpreta como una cadena de formato de fecha y hora estándar. Sin embargo, en este caso concreto, se
produce una excepción porque no existe ningún especificador de formato de fecha y hora estándar "h".
Para usar cualquiera de los especificadores de formato de fecha y hora personalizado como el único
especificador en una cadena de formato (es decir, usar el especificador de formato personalizado "d", "f", "F", "g",
"h", "H", "K", "m", "M", "s", "t", "y", "z", ":" o "/"), incluya un espacio delante o detrás del especificador, o incluya un
especificador de formato de porcentaje ("%") delante del único especificador de fecha y hora personalizado.
Por ejemplo, " %h" se interpreta como una cadena de formato de fecha y hora personalizado que muestra la
hora representada por el valor de fecha y hora actual. También puede usar la cadena de formato " h" o "h ",
aunque esto incluye un espacio en la cadena de resultado junto con la hora. En el ejemplo siguiente se muestran
estas tres cadenas de formato.
Console.WriteLine("'{0:%h}'", dat1);
Console.WriteLine("'{0: h}'", dat1);
Console.WriteLine("'{0:h }'", dat1);
// The example displays the following output:
// '1'
// ' 1'
// '1 '
Dim dat1 As Date = #6/15/2009 1:45PM#
Console.WriteLine("'{0:%h}'", dat1)
Console.WriteLine("'{0: h}'", dat1)
Console.WriteLine("'{0:h }'", dat1)
' The example displays the following output:
' '1'
' ' 1'
' '1 '
NOTE
Algunos compiladores, como los compiladores de C# y C++, también pueden interpretar un único carácter de barra
diagonal inversa como un carácter de escape. Para asegurarse de que una cadena se interpreta correctamente al darle
formato, puede usar el carácter literal de cadena textual (el carácter @) antes de la cadena en C# o puede agregar otro
carácter de barra diagonal inversa delante de cada barra diagonal inversa en C# y C++. En el siguiente ejemplo de C# se
muestran ambos enfoques.
En el ejemplo siguiente se usa el carácter de escape para evitar que la operación de formato interprete los
caracteres "h" y "m" como especificadores de formato.
DateTime date = new DateTime(2009, 06, 15, 13, 45, 30, 90);
string fmt1 = "h \\h m \\m";
string fmt2 = @"h \h m \m";
Vea también
System.DateTime
System.IFormatProvider
Aplicación de formato a tipos
Standard Date and Time Format Strings
Ejemplo: Utilidad de formato WinForms de .NET Core (C#)
Ejemplo: Utilidad de formato WinForms de .NET Core (Visual Basic)
Cadenas de formato TimeSpan estándar
20/01/2020 • 15 minutes to read • Edit Online
Una cadena de formato estándar TimeSpan usa un único especificador de formato para definir la representación
de texto de un valor TimeSpan resultante de una operación de formato. Cualquier cadena de formato que
contenga más de un carácter, incluido el espacio en blanco, se interpreta como una cadena de formato TimeSpan
personalizado. Para más información, consulte Cadenas de formato TimeSpan personalizadas.
Las representaciones de cadena de los valores TimeSpan se generan mediante llamadas a las sobrecargas del
método TimeSpan.ToString, y también mediante métodos que admiten formatos compuestos, como
String.Format. Para obtener más información, consulte Aplicar formato a tipos y Formatos compuestos. En el
siguiente ejemplo se muestra el uso de cadenas de formato estándar en operaciones de formato.
using System;
Module Example
Public Sub Main()
Dim duration As New TimeSpan(1, 12, 23, 62)
Dim output As String = "Time of Travel: " + duration.ToString("c")
Console.WriteLine(output)
Module Example
Public Sub Main()
Dim value As String = "1.03:14:56.1667"
Dim interval As TimeSpan
Try
interval = TimeSpan.ParseExact(value, "c", Nothing)
Console.WriteLine("Converted '{0}' to {1}", value, interval)
Catch e As FormatException
Console.WriteLine("{0}: Bad Format", value)
Catch e As OverflowException
Console.WriteLine("{0}: Out of Range", value)
End Try
Más información:
Especificador de formato
constante ("c").
"g" Formato corto general Este especificador solo New TimeSpan(1, 3, 16,
genera lo necesario. Tiene en 50, 500)
cuenta la referencia cultural -> 1:3:16:50.5 (en-US)
y su forma es
[-] New TimeSpan(1, 3, 16,
[d':']h':'mm':'ss[.FFFFFFF] 50, 500)
. -> 1:3:16:50,5 (fr-FR)
"G" Formato general largo Este especificador siempre New TimeSpan(18, 30, 0)
genera días y siete dígitos -> 0:18:30:00.0000000 (en-
fraccionarios. Tiene en US)
cuenta la referencia cultural
y su forma es New TimeSpan(18, 30, 0)
[- -> 0:18:30:00,0000000 (fr-
]d':'hh':'mm':'ss.fffffff
FR)
.
Más información:
Especificador de formato
largo general ("G").
ELEMENTO DESCRIPCIÓN
A diferencia de los especificadores de formato de "g" y "G", el especificador de formato "c" no tiene en cuenta la
referencia cultural. Produce la representación de cadena de un valor TimeSpan que es invariable y común a todas
las versiones anteriores de .NET previas a .NET Framework 4. "c" es la cadena de formato TimeSpan
predeterminado; el método TimeSpan.ToString() da formato a un valor de intervalo de tiempo mediante la cadena
de formato "c".
NOTE
TimeSpan también admite las cadenas de formato estándar "t" y "T", cuyo comportamiento es idéntico al de la cadena de
formato estándar "c".
En el ejemplo siguiente se crea una instancia de dos objetos TimeSpan, que se usan para realizar operaciones
aritméticas y se muestra el resultado. En cada caso, se utiliza un formato compuesto para mostrar el valor
TimeSpan mediante el especificador de formato "c".
using System;
ELEMENTO DESCRIPCIÓN
Al igual que el especificador de formato "G", el especificador de formato "g" se localiza. Su separador de
fracciones de segundo se basa en la referencia cultural actual o en la propiedad NumberDecimalSeparator de una
referencia cultural especificada.
En el ejemplo siguiente se crea una instancia de dos objetos TimeSpan, que se usan para realizar operaciones
aritméticas y se muestra el resultado. En cada caso, se utiliza un formato compuesto para mostrar el valor
TimeSpan mediante el especificador de formato "g". Además, se da formato al valor TimeSpan mediante las
convenciones de formato de la referencia cultural del sistema actual (que, en este caso, es inglés - Estados Unidos
o en-US ) y la referencia cultural de Francia de francés (fr-FR ).
using System;
using System.Globalization;
Imports System.Globalization
Module Example
Public Sub Main()
Dim interval1, interval2 As TimeSpan
interval1 = New TimeSpan(7, 45, 16)
interval2 = New TimeSpan(18, 12, 38)
ELEMENTO DESCRIPCIÓN
Al igual que el especificador de formato "G", el especificador de formato "g" se localiza. Su separador de
fracciones de segundo se basa en la referencia cultural actual o en la propiedad NumberDecimalSeparator de una
referencia cultural especificada.
En el ejemplo siguiente se crea una instancia de dos objetos TimeSpan, que se usan para realizar operaciones
aritméticas y se muestra el resultado. En cada caso, se utiliza un formato compuesto para mostrar el valor
TimeSpan mediante el especificador de formato "G". Además, se da formato al valor TimeSpan mediante las
convenciones de formato de la referencia cultural del sistema actual (que, en este caso, es inglés - Estados Unidos
o en-US ) y la referencia cultural de Francia de francés (fr-FR ).
using System;
using System.Globalization;
Imports System.Globalization
Module Example
Public Sub Main()
Dim interval1, interval2 As TimeSpan
interval1 = New TimeSpan(7, 45, 16)
interval2 = New TimeSpan(18, 12, 38)
Vea también
Aplicación de formato a tipos
Cadenas de formato TimeSpan personalizado
Parsing Strings
Cadenas de formato TimeSpan personalizado
20/01/2020 • 63 minutes to read • Edit Online
Una cadena de formato TimeSpan define la representación de cadena de un valor TimeSpan generado por una
operación de formato. Una cadena de formato personalizado consta de uno o varios especificadores de formato
TimeSpan personalizado, además de un número de caracteres literales. Cualquier cadena que no sea una cadena
de formato TimeSpan estándar se interpreta como una cadena de formato TimeSpan personalizado.
IMPORTANT
Los especificadores de formato TimeSpan personalizado no incluyen símbolos de separador de marcadores de posición,
como los símbolos que separan los días de las horas, las horas de los minutos o los segundos de las fracciones de segundo.
Estos símbolos deben incluirse en la cadena de formato personalizado como literales de cadena. Por ejemplo,
"dd\.hh\:mm" define un punto (.) como separador entre los días y las horas, y un signo de dos puntos (:) como separador
entre las horas y los minutos.
Los especificadores de formato TimeSpan personalizado tampoco incluyen un símbolo de signo que permita distinguir entre
los intervalos de tiempo negativos y positivos. Para incluir un símbolo de signo, es necesario construir una cadena de
formato utilizando lógica condicional. En la sección Otros caracteres se incluye un ejemplo.
Las representaciones de cadena de los valores TimeSpan se generan mediante llamadas a las sobrecargas del
método TimeSpan.ToString, y también mediante métodos que admiten formatos compuestos, como
String.Format. Para obtener más información, consulte Aplicar formato a tipos y Formatos compuestos. En el
siguiente ejemplo, se muestra el uso de cadenas de formato personalizado en operaciones de formato.
using System;
using System;
value = "6";
if (TimeSpan.TryParseExact(value, "%d", null, out interval))
Console.WriteLine("{0} --> {1}", value, interval.ToString("c"));
else
Console.WriteLine("Unable to parse '{0}'", value);
value = "16:32.05";
if (TimeSpan.TryParseExact(value, @"mm\:ss\.ff", null, out interval))
Console.WriteLine("{0} --> {1}", value, interval.ToString("c"));
else
Console.WriteLine("Unable to parse '{0}'", value);
value= "12.035";
if (TimeSpan.TryParseExact(value, "ss\\.fff", null, out interval))
Console.WriteLine("{0} --> {1}", value, interval.ToString("c"));
else
Console.WriteLine("Unable to parse '{0}'", value);
}
}
// The example displays the following output:
// 6 --> 6.00:00:00
// 16:32.05 --> 00:16:32.0500000
// 12.035 --> 00:00:12.0350000
Module Example
Public Sub Main()
Dim value As String = Nothing
Dim interval As TimeSpan
value = "6"
If TimeSpan.TryParseExact(value, "%d", Nothing, interval) Then
Console.WriteLine("{0} --> {1}", value, interval.ToString("c"))
Else
Console.WriteLine("Unable to parse '{0}'", value)
End If
value = "16:32.05"
If TimeSpan.TryParseExact(value, "mm\:ss\.ff", Nothing, interval) Then
Console.WriteLine("{0} --> {1}", value, interval.ToString("c"))
Else
Console.WriteLine("Unable to parse '{0}'", value)
End If
value= "12.035"
If TimeSpan.TryParseExact(value, "ss\.fff", Nothing, interval) Then
Console.WriteLine("{0} --> {1}", value, interval.ToString("c"))
Else
Console.WriteLine("Unable to parse '{0}'", value)
End If
End Sub
End Module
' The example displays the following output:
' 6 --> 6.00:00:00
' 16:32.05 --> 00:16:32.0500000
' 12.035 --> 00:00:12.0350000
"d", "%d" Número de días completos de un new TimeSpan(6, 14, 32, 17, 685):
intervalo de tiempo.
%d --> "6"
Más información: Especificador de
formato personalizado "d". d\.hh\:mm --> "6.14:32"
"dd"-"dddddddd" Número de días completos de un new TimeSpan(6, 14, 32, 17, 685):
intervalo de tiempo, que se completa
con tantos ceros iniciales como sean ddd --> "006"
necesarios.
dd\.hh\:mm --> "06.14:32"
Más información: Especificadores de
formato personalizado "dd"-
"dddddddd".
"h", "%h" Número de horas completas de un new TimeSpan(6, 14, 32, 17, 685):
intervalo de tiempo que no se cuentan
como parte de los días. Las horas con %h --> "14"
un solo dígito no se escriben con un
cero a la izquierda. hh\:mm --> "14:32"
Más información: Especificador de
formato personalizado "h".
ESPECIFICADOR DE FORMATO DESCRIPCIÓN EJEMPLO
"hh" Número de horas completas de un new TimeSpan(6, 14, 32, 17, 685):
intervalo de tiempo que no se cuentan
como parte de los días. Las horas con hh --> "14"
un solo dígito se escriben con un cero a
la izquierda. new TimeSpan(6, 8, 32, 17, 685):
"m", "%m" Número de minutos completos de un new TimeSpan(6, 14, 8, 17, 685):
intervalo de tiempo que no se incluyen
como parte de las horas o los días. Los %m --> "8"
minutos con un solo dígito no se
escriben con un cero a la izquierda. h\:m --> "14:8"
Más información: Especificador de
formato personalizado "m".
ss\.FFF : 03.1
ESPECIFICADOR DE FORMATO DESCRIPCIÓN EJEMPLO
ss\.FFFFF : 03.1
ss\.FFFFFF : 03.1
Cualquier otro carácter Cualquier otro carácter sin escape se new TimeSpan(14, 32, 17):
interpreta como especificador de
formato personalizado. hh\:mm\:ss --> "14:32:17"
Volver a la tabla
Volver a la tabla
Especificador de formato personalizado "h"
El especificador de formato personalizado "h" presenta el valor de la propiedad TimeSpan.Hours, que representa
el número de horas completas de un intervalo de tiempo que no se cuentan como parte del componente de días.
Devuelve un valor de cadena de un dígito si el valor de la propiedad TimeSpan.Hours es de 0 a 9; devuelve un
valor de cadena de dos dígitos si el valor de la propiedad TimeSpan.Hours es de 10 a 23.
Si el especificador de formato personalizado "h" se utiliza solo, especifique "%h" de modo que no se interprete
por error como una cadena de formato estándar. Esto se muestra en el ejemplo siguiente.
Normalmente, en las operaciones de análisis, una cadena de entrada que incluye solamente un número se
interpreta como número de días. Se puede utilizar el especificador de formato personalizado "%h"" para que la
cadena numérica se interprete como número de horas. Esto se muestra en el ejemplo siguiente.
Volver a la tabla
Volver a la tabla
Normalmente, en las operaciones de análisis, una cadena de entrada que incluye solamente un número se
interpreta como número de días. Se puede utilizar el especificador de formato personalizado "%m"" para que la
cadena numérica se interprete como número de minutos. Esto se muestra en el ejemplo siguiente.
Volver a la tabla
Volver a la tabla
TimeSpan ts = TimeSpan.FromSeconds(12.465);
Console.WriteLine(ts.ToString("%s"));
// The example displays the following output:
// 12
Normalmente, en las operaciones de análisis, una cadena de entrada que incluye solamente un número se
interpreta como número de días. Se puede utilizar el especificador de formato personalizado "%s"" para que la
cadena numérica se interprete como número de segundos. Esto se muestra en el ejemplo siguiente.
Volver a la tabla
Volver a la tabla
For ctr = 1 To 7
fmt = New String("f"c, ctr)
If fmt.Length = 1 Then fmt = "%" + fmt
Console.WriteLine("{0,10}: {1:" + fmt + "}", fmt, ts)
Next
Console.WriteLine()
For ctr = 1 To 7
fmt = New String("f"c, ctr)
Console.WriteLine("{0,10}: {1:s\." + fmt + "}", "s\." + fmt, ts)
Next
' The example displays the following output:
' %f: 8
' ff: 87
' fff: 876
' ffff: 8765
' fffff: 87654
' ffffff: 876543
' fffffff: 8765432
'
' s\.f: 29.8
' s\.ff: 29.87
' s\.fff: 29.876
' s\.ffff: 29.8765
' s\.fffff: 29.87654
' s\.ffffff: 29.876543
' s\.fffffff: 29.8765432
Volver a la tabla
For ctr = 1 To 7
fmt = New String("f"c, ctr)
If fmt.Length = 1 Then fmt = "%" + fmt
Console.WriteLine("{0,10}: {1:" + fmt + "}", fmt, ts)
Next
Console.WriteLine()
For ctr = 1 To 7
fmt = New String("f"c, ctr)
Console.WriteLine("{0,10}: {1:s\." + fmt + "}", "s\." + fmt, ts)
Next
' The example displays the following output:
' %f: 8
' ff: 87
' fff: 876
' ffff: 8765
' fffff: 87654
' ffffff: 876543
' fffffff: 8765432
'
' s\.f: 29.8
' s\.ff: 29.87
' s\.fff: 29.876
' s\.ffff: 29.8765
' s\.fffff: 29.87654
' s\.ffffff: 29.876543
' s\.fffffff: 29.8765432
Volver a la tabla
For ctr = 1 To 7
fmt = New String("f"c, ctr)
If fmt.Length = 1 Then fmt = "%" + fmt
Console.WriteLine("{0,10}: {1:" + fmt + "}", fmt, ts)
Next
Console.WriteLine()
For ctr = 1 To 7
fmt = New String("f"c, ctr)
Console.WriteLine("{0,10}: {1:s\." + fmt + "}", "s\." + fmt, ts)
Next
' The example displays the following output:
' %f: 8
' ff: 87
' fff: 876
' ffff: 8765
' fffff: 87654
' ffffff: 876543
' fffffff: 8765432
'
' s\.f: 29.8
' s\.ff: 29.87
' s\.fff: 29.876
' s\.ffff: 29.8765
' s\.fffff: 29.87654
' s\.ffffff: 29.876543
' s\.fffffff: 29.8765432
Volver a la tabla
For ctr = 1 To 7
fmt = New String("f"c, ctr)
If fmt.Length = 1 Then fmt = "%" + fmt
Console.WriteLine("{0,10}: {1:" + fmt + "}", fmt, ts)
Next
Console.WriteLine()
For ctr = 1 To 7
fmt = New String("f"c, ctr)
Console.WriteLine("{0,10}: {1:s\." + fmt + "}", "s\." + fmt, ts)
Next
' The example displays the following output:
' %f: 8
' ff: 87
' fff: 876
' ffff: 8765
' fffff: 87654
' ffffff: 876543
' fffffff: 8765432
'
' s\.f: 29.8
' s\.ff: 29.87
' s\.fff: 29.876
' s\.ffff: 29.8765
' s\.fffff: 29.87654
' s\.ffffff: 29.876543
' s\.fffffff: 29.8765432
Volver a la tabla
For ctr = 1 To 7
fmt = New String("f"c, ctr)
If fmt.Length = 1 Then fmt = "%" + fmt
Console.WriteLine("{0,10}: {1:" + fmt + "}", fmt, ts)
Next
Console.WriteLine()
For ctr = 1 To 7
fmt = New String("f"c, ctr)
Console.WriteLine("{0,10}: {1:s\." + fmt + "}", "s\." + fmt, ts)
Next
' The example displays the following output:
' %f: 8
' ff: 87
' fff: 876
' ffff: 8765
' fffff: 87654
' ffffff: 876543
' fffffff: 8765432
'
' s\.f: 29.8
' s\.ff: 29.87
' s\.fff: 29.876
' s\.ffff: 29.8765
' s\.fffff: 29.87654
' s\.ffffff: 29.876543
' s\.fffffff: 29.8765432
Volver a la tabla
For ctr = 1 To 7
fmt = New String("f"c, ctr)
If fmt.Length = 1 Then fmt = "%" + fmt
Console.WriteLine("{0,10}: {1:" + fmt + "}", fmt, ts)
Next
Console.WriteLine()
For ctr = 1 To 7
fmt = New String("f"c, ctr)
Console.WriteLine("{0,10}: {1:s\." + fmt + "}", "s\." + fmt, ts)
Next
' The example displays the following output:
' %f: 8
' ff: 87
' fff: 876
' ffff: 8765
' fffff: 87654
' ffffff: 876543
' fffffff: 8765432
'
' s\.f: 29.8
' s\.ff: 29.87
' s\.fff: 29.876
' s\.ffff: 29.8765
' s\.fffff: 29.87654
' s\.ffffff: 29.876543
' s\.fffffff: 29.8765432
Volver a la tabla
For ctr = 1 To 7
fmt = New String("f"c, ctr)
If fmt.Length = 1 Then fmt = "%" + fmt
Console.WriteLine("{0,10}: {1:" + fmt + "}", fmt, ts)
Next
Console.WriteLine()
For ctr = 1 To 7
fmt = New String("f"c, ctr)
Console.WriteLine("{0,10}: {1:s\." + fmt + "}", "s\." + fmt, ts)
Next
' The example displays the following output:
' %f: 8
' ff: 87
' fff: 876
' ffff: 8765
' fffff: 87654
' ffffff: 876543
' fffffff: 8765432
'
' s\.f: 29.8
' s\.ff: 29.87
' s\.fff: 29.876
' s\.ffff: 29.8765
' s\.fffff: 29.87654
' s\.ffffff: 29.876543
' s\.fffffff: 29.8765432
Volver a la tabla
Console.WriteLine("Formatting:");
TimeSpan ts1 = TimeSpan.Parse("0:0:3.669");
Console.WriteLine("{0} ('%F') --> {0:%F}", ts1);
Console.WriteLine("Parsing:");
string[] inputs = { "0:0:03.", "0:0:03.1", "0:0:03.12" };
string fmt = @"h\:m\:ss\.F";
TimeSpan ts3;
Console.WriteLine("Parsing:")
Dim inputs() As String = { "0:0:03.", "0:0:03.1", "0:0:03.12" }
Dim fmt As String = "h\:m\:ss\.F"
Dim ts3 As TimeSpan
Volver a la tabla
Console.WriteLine("Parsing:");
string[] inputs = { "0:0:03.", "0:0:03.1", "0:0:03.127" };
string fmt = @"h\:m\:ss\.FF";
TimeSpan ts3;
Console.WriteLine("Formatting:")
Dim ts1 As TimeSpan = TimeSpan.Parse("0:0:3.697")
Console.WriteLine("{0} ('FF') --> {0:FF}", ts1)
Console.WriteLine("Parsing:")
Dim inputs() As String = { "0:0:03.", "0:0:03.1", "0:0:03.127" }
Dim fmt As String = "h\:m\:ss\.FF"
Dim ts3 As TimeSpan
Volver a la tabla
Especificador de formato personalizado "FFF"
El especificador de formato personalizado "FFF" (tres caracteres "F") presenta las milésimas de segundo de un
intervalo de tiempo. En una operación de formato, se truncan los dígitos fraccionarios restantes. Si hay ceros
fraccionarios finales, estos no se incluyen en la cadena de resultado. En una operación de análisis que llama al
método TimeSpan.ParseExact o TimeSpan.TryParseExact, la presencia de las décimas, centésimas y milésimas de
segundo es opcional.
En el siguiente ejemplo, se utiliza el especificador de formato personalizado "FFF" para mostrar las milésimas de
segundo de un valor TimeSpan. También se utiliza este especificador de formato personalizado en una operación
de análisis.
Console.WriteLine("Formatting:");
TimeSpan ts1 = TimeSpan.Parse("0:0:3.6974");
Console.WriteLine("{0} ('FFF') --> {0:FFF}", ts1);
Console.WriteLine("Parsing:");
string[] inputs = { "0:0:03.", "0:0:03.12", "0:0:03.1279" };
string fmt = @"h\:m\:ss\.FFF";
TimeSpan ts3;
Console.WriteLine("Parsing:")
Dim inputs() As String = { "0:0:03.", "0:0:03.12", "0:0:03.1279" }
Dim fmt As String = "h\:m\:ss\.FFF"
Dim ts3 As TimeSpan
Volver a la tabla
Console.WriteLine("Parsing:");
string[] inputs = { "0:0:03.", "0:0:03.12", "0:0:03.12795" };
string fmt = @"h\:m\:ss\.FFFF";
TimeSpan ts3;
Console.WriteLine("Formatting:")
Dim ts1 As TimeSpan = TimeSpan.Parse("0:0:3.69749")
Console.WriteLine("{0} ('FFFF') --> {0:FFFF}", ts1)
Console.WriteLine("Parsing:")
Dim inputs() As String = { "0:0:03.", "0:0:03.12", "0:0:03.12795" }
Dim fmt As String = "h\:m\:ss\.FFFF"
Dim ts3 As TimeSpan
Volver a la tabla
Especificador de formato personalizado "FFFFF"
El especificador de formato personalizado "FFFFF" (cinco caracteres "F") presenta las cienmilésimas de segundo
de un intervalo de tiempo. En una operación de formato, se truncan los dígitos fraccionarios restantes. Si hay
ceros fraccionarios finales, estos no se incluyen en la cadena de resultado. En una operación de análisis que llama
al método TimeSpan.ParseExact o TimeSpan.TryParseExact, la presencia de las décimas, centésimas, milésimas,
diezmilésimas y cienmilésimas de segundo es opcional.
En el siguiente ejemplo, se utiliza el especificador de formato personalizado "FFFFF" para mostrar las
cienmilésimas de segundo de un valor TimeSpan. También se utiliza este especificador de formato personalizado
en una operación de análisis.
Console.WriteLine("Formatting:");
TimeSpan ts1 = TimeSpan.Parse("0:0:3.697497");
Console.WriteLine("{0} ('FFFFF') --> {0:FFFFF}", ts1);
Console.WriteLine("Parsing:");
string[] inputs = { "0:0:03.", "0:0:03.12", "0:0:03.127956" };
string fmt = @"h\:m\:ss\.FFFFF";
TimeSpan ts3;
Console.WriteLine("Parsing:")
Dim inputs() As String = { "0:0:03.", "0:0:03.12", "0:0:03.127956" }
Dim fmt As String = "h\:m\:ss\.FFFFF"
Dim ts3 As TimeSpan
Volver a la tabla
Console.WriteLine("Parsing:");
string[] inputs = { "0:0:03.", "0:0:03.12", "0:0:03.1279569" };
string fmt = @"h\:m\:ss\.FFFFFF";
TimeSpan ts3;
Console.WriteLine("Formatting:")
Dim ts1 As TimeSpan = TimeSpan.Parse("0:0:3.6974974")
Console.WriteLine("{0} ('FFFFFF') --> {0:FFFFFF}", ts1)
Console.WriteLine("Parsing:")
Dim inputs() As String = { "0:0:03.", "0:0:03.12", "0:0:03.1279569" }
Dim fmt As String = "h\:m\:ss\.FFFFFF"
Dim ts3 As TimeSpan
Volver a la tabla
Especificador de formato personalizado "FFFFFFF"
El especificador de formato personalizado "FFFFFFF" (siete caracteres "F") presenta las diezmillonésimas de
segundo (o fracciones de paso) de un intervalo de tiempo. Si hay ceros fraccionarios finales, estos no se incluyen
en la cadena de resultado. En una operación de análisis que llama al método TimeSpan.ParseExact or
TimeSpan.TryParseExact, la presencia de los siete dígitos fraccionarios en la cadena de entrada es opcional.
En el siguiente ejemplo, se utiliza el especificador de formato personalizado "FFFFFFF" para mostrar las
fracciones de segundo de un valor TimeSpan. También se utiliza este especificador de formato personalizado en
una operación de análisis.
Console.WriteLine("Formatting:");
TimeSpan ts1 = TimeSpan.Parse("0:0:3.6974974");
Console.WriteLine("{0} ('FFFFFFF') --> {0:FFFFFFF}", ts1);
Console.WriteLine("Parsing:");
string[] inputs = { "0:0:03.", "0:0:03.12", "0:0:03.1279569" };
string fmt = @"h\:m\:ss\.FFFFFFF";
TimeSpan ts3;
Console.WriteLine("Parsing:")
Dim inputs() As String = { "0:0:03.", "0:0:03.12", "0:0:03.1279569" }
Dim fmt As String = "h\:m\:ss\.FFFFFFF"
Dim ts3 As TimeSpan
Volver a la tabla
Otros caracteres
Cualquier otro carácter sin escape de una cadena de formato, incluido el carácter de espacio en blanco, se
interpreta como especificador de formato personalizado. En la mayoría de los casos, la presencia de cualquier
otro carácter sin escape da lugar a una excepción FormatException.
Para incluir un carácter literal en una cadena de formato, se puede proceder de dos formas:
Se puede escribirlo entre comillas sencillas (delimitador de cadena literal).
Se puede anteponer una barra diagonal inversa ("\"), que se interpreta como un carácter de escape. En C#,
esto significa que la cadena de formato debe ser @-quoted o que el carácter literal debe ir precedido de
una barra diagonal inversa adicional.
En algunos casos, puede que sea necesario usar lógica condicional para incluir un carácter literal de escape
en una cadena de formato. En el ejemplo siguiente se usa lógica condicional para incluir un símbolo de
signo para los intervalos de tiempo negativos.
using System;
Console.WriteLine(result.ToString(fmt));
Console.WriteLine("Interval: {0:" + fmt + "}", result);
}
}
// The example displays output like the following:
// -1291.10:54
// Interval: -1291.10:54
Module Example
Public Sub Main()
Dim result As TimeSpan = New DateTime(2010, 01, 01) - Date.Now
Dim fmt As String = If(result < TimeSpan.Zero, "\-", "") + "dd\.hh\:mm"
Console.WriteLine(result.ToString(fmt))
Console.WriteLine("Interval: {0:" + fmt + "}", result)
End Sub
End Module
' The example displays output like the following:
' -1291.10:54
' Interval: -1291.10:54
.NET no define ninguna gramática para los separadores en los intervalos de tiempo. Esto significa que los
separadores entre los días y las horas, las horas y los minutos, los minutos y los segundos, y los segundos y las
fracciones de segundo deben tratarse todos como literales de carácter en una cadena de formato.
En el siguiente ejemplo, se utilizan el carácter de escape y la comilla simple para definir una cadena de formato
personalizado que incluye la palabra "minutes" en la cadena de salida.
Volver a la tabla
Vea también
Aplicación de formato a tipos
Cadenas de formato TimeSpan estándar
Cadenas de formato de enumeración
13/01/2020 • 5 minutes to read • Edit Online
Puede usar el método Enum.ToString para crear un objeto de cadena que represente el valor de cadena, numérico
o hexadecimal del miembro de una enumeración. Este método toma una de las cadenas de formato de
enumeración para especificar el valor que quiere que se devuelva.
En las secciones siguientes se enumeran las cadenas de formato de enumeración y los valores que devuelven.
Estos especificadores de formato no distinguen mayúsculas de minúsculas.
Gog
Si es posible, muestra la entrada de enumeración como valor de cadena y, si no, muestra el valor entero de la
instancia actual. Si la enumeración se define con el conjunto de atributos Flags, los valores de cadena de cada
entrada válida se concatenan, separados por comas. Si no se establece el atributo Flags, se muestra un valor no
válido como entrada numérica. En el siguiente ejemplo se muestra el uso del especificador de formato G.
Fof
Si es posible, muestra la entrada de enumeración como valor de cadena. Si el valor se puede mostrar por
completo como suma de las entradas de la enumeración (aunque el atributo Flags no esté presente), los valores
de cadena de cada entrada válida se concatenan, separados por comas. Si las entradas de enumeración no
pueden determinar completamente el valor, a este se le da formato como valor entero. En el siguiente ejemplo se
muestra el uso del especificador de formato F.
Dod
Muestra la entrada de enumeración como valor entero en la representación más corta posible. En el siguiente
ejemplo se muestra el uso del especificador de formato D.
Console.WriteLine(ConsoleColor.Cyan.ToString("D")); // Displays 11
FileAttributes attributes = FileAttributes.Hidden |
FileAttributes.Archive;
Console.WriteLine(attributes.ToString("D")); // Displays 34
Xox
Muestra la entrada de enumeración como valor hexadecimal. El valor se representa con ceros a la izquierda,
según sea necesario, para garantizar que la cadena de resultados tenga dos caracteres para cada byte en el tipo
numérico que subyace en el tipo de enumeración. En el siguiente ejemplo se muestra el uso del especificador de
formato X. En el ejemplo, el tipo subyacente tanto de ConsoleColor como de FileAttributes es Int32, o un entero
de 32 bits (o 4 bytes), que produce una cadena de resultados de ocho caracteres.
Ejemplo
En el ejemplo siguiente se define una enumeración denominada Colors que consta de tres entradas: Red , Blue
y Green .
Una vez definida la enumeración, se puede declarar una instancia de la siguiente manera.
Vea también
Aplicación de formato a tipos
Formatos compuestos
22/01/2020 • 23 minutes to read • Edit Online
La característica de formato compuesto de .NET toma una lista de objetos y una cadena de formato
compuesto como entrada. Una cadena de formato compuesto está formada por texto fijo combinado con
marcadores de posición indizados, que reciben el nombre de elementos de formato, y que se corresponden
con los objetos de la lista. La operación de formato genera una cadena de resultado compuesta por el texto
fijo original combinado con la representación de cadena de los objetos de la lista.
IMPORTANT
En lugar de usar cadenas de formato compuesto, puede usar cadenas interpoladas si el idioma y la versión de idioma
que está usando son compatibles con ellos. Una cadena interpolada es una cadena que contiene expresiones
interpoladas. Cada expresión interpolada se resuelve con el valor de la expresión y se incluye en la cadena de
resultado cuando se asigna la cadena. Para obtener más información, vea Interpolación de cadenas (Referencia de C#)
y Cadenas interpoladas (referencia de Visual Basic).
El texto fijo es " Name = " y " , hours = ". Los elementos de formato son " {0} ", cuyo índice es 0, que
corresponde al objeto name , y " {1:hh} ", cuyo índice es 1, que corresponde al objeto DateTime.Now .
string primes;
primes = String.Format("Prime numbers less than 10: {0}, {1}, {2}, {3}",
2, 3, 5, 7 );
Console.WriteLine(primes);
// The example displays the following output:
// Prime numbers less than 10: 2, 3, 5, 7
Los elementos de formato múltiple se pueden referir al mismo elemento de la lista de objetos mediante la
especificación del mismo especificador de parámetro. Por ejemplo, se puede dar formato al mismo valor
numérico en formato hexadecimal, científico y de número mediante la especificación de una cadena de
formato compuesto como esta: "0x{0:X} {0:E } {0:N }", como se muestra en el ejemplo siguiente.
Cada elemento de formato puede hacer referencia a cualquier objeto de la lista. Por ejemplo, si existen tres
objetos, se puede dar formato al segundo, primero y tercer objeto mediante la especificación de una cadena
de formato compuesto como esta: "{1} {0} {2}". Un objeto al que no hace referencia ningún elemento de
formato se omite. Se produce una excepción FormatException en tiempo de ejecución si un especificador de
parámetro designa un elemento fuera de los límites de la lista de objetos.
Alignment (Componente )
El componente opcional alignment es un entero con signo que indica el ancho de campo con formato
preferido. Si el valor de alignment es menor que la longitud de la cadena con formato, se omite alignment y
se usa la longitud de la cadena con formato como el ancho de campo. Los datos con formato del campo
están alineados a la derecha si alignment es positivo y a la izquierda si alignment es negativo. Si hace falta
relleno, se utiliza un espacio en blanco. Si se especifica alignment, es necesaria la coma.
El siguiente ejemplo define dos matrices, que contiene los nombres de empleados y otra contiene las horas
que han trabajado en un período de dos semanas. La cadena de formato compuesto alinea a la izquierda los
nombres en un campo de 20 caracteres y alinea a la derecha las horas en un campo de 5 caracteres. Tenga
en cuenta que la cadena de formato estándar "N1" también se usa para dar formato a las horas con un dígito
fraccionario.
using System;
Tipos de fecha y hora (DateTime, DateTimeOffset) Cadenas con formato de fecha y hora estándar
Tipos numéricos (BigInteger, Byte, Decimal, Double, Int16, Cadenas con formato numérico estándar
Int32, Int64, SByte, Single, UInt16, UInt32, UInt64)
Cadenas con formato numérico personalizado
Guid Guid.ToString(String)
TIPO O CATEGORÍA DE TIPO VEA
Llaves de escape
Las llaves de apertura y de cierre se interpretan como el inicio y el final de un elemento de formato. Por lo
tanto, debe utilizar una secuencia de escape para que se muestre una llave de apertura o de cierre literal.
Especifique dos llaves de apertura ("{{") en el texto fijo para que se muestre una llave de apertura ("{"), o dos
llaves de cierre ("}}") para que se muestre una llave de cierre ("}"). Las llaves de un elemento de formato se
interpretan secuencialmente, en el orden en que se encuentran. No se admite la interpretación de llaves
anidadas.
El modo de interpretar las llaves de escape puede dar lugar a resultados inesperados. Tomemos como
ejemplo el elemento de formato "{{{0:D }}}", cuyo propósito es mostrar una llave de apertura, un valor
numérico con formato de número decimal y una llave de cierre; pero que, en la práctica, se interpreta de la
siguiente forma:
1. Las dos primeras llaves de apertura ("{{") son llaves de escape y dan lugar a en una llave de apertura.
2. Los tres caracteres siguientes ("{0:") se interpretan como el inicio de un elemento de formato.
3. El siguiente carácter ("D") se interpretaría como el especificador de formato numérico estándar
decimal, pero las dos llaves de escape siguientes ("}}") dan lugar a una única llave. Como la cadena
resultante ("D }") no es un especificador de formato numérico estándar, se interpreta como una cadena
de formato personalizado que significa que debe mostrarse la cadena literal "D }".
4. La última llave ("}") se interpreta como el final del elemento de formato.
5. Como resultado final, se muestra la cadena literal "{D }". No se muestra el valor numérico al que se
debía dar formato.
Una forma de escribir código e impedir que las llaves de escape y los elementos de formato se
malinterpreten consiste en dar formato a las llaves y elementos de formato por separado. Es decir, en la
primera operación de formato mostrar una llave de apertura literal, en la siguiente operación mostrar el
resultado del elemento de formato y, por último, en la operación final mostrar una llave de cierre literal. En el
ejemplo siguiente se muestra este enfoque.
Orden de procesamiento
Si la llamada al método de formato compuesto incluye un argumento IFormatProvider cuyo valor no es
null , el runtime llama al método IFormatProvider.GetFormat para solicitar una implementación de
ICustomFormatter. Si el método es capaz de devolver una implementación de ICustomFormatter, se
almacena en caché el tiempo que dure la llamada de método de formato compuesto.
Cada valor de la lista de parámetros que se corresponda con un elemento de formato se convierte en una
cadena del siguiente modo:
1. Si el valor al que se va a dar formato es null , se devuelve una cadena vacía String.Empty.
2. Si hay disponible una implementación de ICustomFormatter, el runtime llama al método Format.
Pasa al método el valor formatString del elemento de formato, si hay alguno, o null si no lo hay,
junto con la implementación de IFormatProvider. Si la llamada al método ICustomFormatter.Format
devuelve null , la ejecución avanza al siguiente paso; en caso contrario, se devuelve el resultado de la
llamada a ICustomFormatter.Format.
3. Si el valor implementa la interfaz IFormattable, se llama al método ToString(String, IFormatProvider)
de esta. Se pasa al método el valor formatString, si hubiera uno presente en el elemento de formato, o
null si no lo hubiera. El argumento IFormatProvider se determina de la siguiente forma:
Ejemplos de código
En el ejemplo siguiente se muestra una cadena creada mediante formato compuesto y otra creada mediante
el método ToString de un objeto. Los dos tipos de formato producen resultados equivalentes.
Si tomamos como día actual un jueves del mes de mayo, el valor de ambas cadenas del ejemplo anterior
será Thursday May para la referencia cultural Inglés (Estados Unidos).
Console.WriteLine expone la misma funcionalidad que String.Format. La única diferencia que existe entre
estos dos métodos es que String.Format devuelve el resultado como una cadena, mientras que
Console.WriteLine escribe el resultado en el flujo de salida asociado al objeto Console. En el ejemplo
siguiente se usa el método Console.WriteLine para dar formato al valor de MyInt como un valor de divisa.
En el ejemplo siguiente se muestra el uso de la alineación en la aplicación de formato. Los argumentos a los
que se da formato se colocan entre caracteres verticales (|) para resaltar la alineación resultante.
string myFName = "Fred";
string myLName = "Opals";
int myInt = 100;
string FormatFName = String.Format("First Name = |{0,10}|", myFName);
string FormatLName = String.Format("Last Name = |{0,10}|", myLName);
string FormatPrice = String.Format("Price = |{0,10:C}|", myInt);
Console.WriteLine(FormatFName);
Console.WriteLine(FormatLName);
Console.WriteLine(FormatPrice);
Console.WriteLine();
Vea también
WriteLine
String.Format
Interpolación de cadenas en C#
Cadenas interpoladas (referencia de Visual Basic)
Aplicación de formato a tipos
Cadenas con formato numérico estándar
Cadenas con formato numérico personalizado
Cadenas con formato de fecha y hora estándar
Cadenas con formato de fecha y hora personalizado
Cadenas de formato TimeSpan estándar
Cadenas de formato TimeSpan personalizado
Cadenas de formato de enumeración
Efectuar operaciones de formato
20/01/2020 • 2 minutes to read • Edit Online
En los temas siguientes se proporcionan instrucciones detalladas para realizar operaciones de formato concretas.
Cómo: Rellenar un número con ceros a la izquierda
Cómo: Definir y usar proveedores de formato numérico personalizado
Cómo: Extraer el día de la semana de una fecha concreta.
Cómo: Aplicar acciones de ida y vuelta a valores de fecha y hora
Cómo: Mostrar milisegundos en valores de fecha y hora
Cómo: Mostrar fechas en calendarios no gregorianos
Vea también
Aplicación de formato a tipos
Procedimiento para rellenar un número con ceros a
la izquierda
04/11/2019 • 10 minutes to read • Edit Online
Si quiere agregar ceros a la izquierda de un entero, puede hacerlo mediante la cadena de formato numérico
estándar "D" con un especificador de precisión. Para agregar ceros a la izquierda tanto de enteros como de
números de punto flotante, use una cadena de formato numérico personalizada. En este artículo se explica cómo
usar ambos métodos para rellenar un número con ceros a la izquierda.
4. Agregue el número de ceros a la izquierda que desea incluir en la cadena con formato a la longitud de la
cadena numérica sin rellenar. Al agregar el número de ceros iniciales se define la longitud total de la cadena
rellenada.
5. Llame al método ToString(String) del valor entero y pase la cadena "Dn" para cadenas decimales y "Xn"
para cadenas hexadecimales, donde n representa la longitud total de la cadena rellenada. También puede
usar la cadena de formato "Dn" o "Xn" en un método que admita formato compuesto.
En el ejemplo siguiente se rellena un valor entero con cinco ceros a la izquierda.
int value = 160934;
int decimalLength = value.ToString("D").Length + 5;
int hexLength = value.ToString("X").Length + 5;
Console.WriteLine(value.ToString("D" + decimalLength.ToString()));
Console.WriteLine(value.ToString("X" + hexLength.ToString()));
// The example displays the following output:
// 00000160934
// 00000274A6
if (dblValue.ToString().Contains(decSeparator))
{
int digits = dblValue.ToString().IndexOf(decSeparator);
fmt = new String('0', 5) + new String('#', digits) + ".##";
}
else
{
fmt = new String('0', dblValue.ToString().Length);
}
formatString = "{0,20:" + fmt + "}";
Console.WriteLine(dblValue.ToString(fmt));
Console.WriteLine(formatString, dblValue);
}
// The example displays the following output:
// 000009034521202.93
// 000009034521202.93
// 9034521202
// 9034521202
Dim dblValues() As Double = { 9034521202.93217412, 9034521202 }
For Each dblValue As Double In dblValues
Dim decSeparator As String = System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator
Dim fmt, formatString As String
If dblValue.ToString.Contains(decSeparator) Then
Dim digits As Integer = dblValue.ToString().IndexOf(decSeparator)
fmt = New String("0"c, 5) + New String("#"c, digits) + ".##"
Else
fmt = New String("0"c, dblValue.ToString.Length)
End If
formatString = "{0,20:" + fmt + "}"
Console.WriteLine(dblValue.ToString(fmt))
Console.WriteLine(formatString, dblValue)
Next
' The example displays the following output:
' 000009034521202.93
' 000009034521202.93
' 9034521202
' 9034521202
Vea también
Custom Numeric Format Strings
Standard Numeric Format Strings
Formatos compuestos
Procedimiento para extraer el día de la semana de
una fecha concreta
04/11/2019 • 11 minutes to read • Edit Online
.NET Framework permite determinar fácilmente el número de día de la semana correspondiente a una fecha
concreta, así como mostrar el nombre localizado del día de la semana para una fecha en particular. Las
propiedades DayOfWeek o DayOfWeek proporcionan un valor enumerado que indica el día de la semana
correspondiente a una fecha concreta. Por el contrario, la recuperación del nombre del día de la semana es una
operación de formato que puede realizarse con una llamada a un método de formato como, por ejemplo, un
método ToString de un valor de fecha y hora o un método String.Format. En este tema se muestra cómo realizar
estas operaciones de formato.
Para obtener un número que indique el día de la semana a partir de una fecha específica
1. Cuando trabaje con la representación de cadena de una fecha, conviértala en un valor DateTime o
DateTimeOffset mediante el método estático DateTime.Parse o DateTimeOffset.Parse.
2. Use las propiedades DateTime.DayOfWeek o DateTimeOffset.DayOfWeek para recuperar un valor
DayOfWeek que indique el día de la semana.
3. En caso necesario, convierta (en C# o en Visual Basic) el valor DayOfWeek en un entero.
En el ejemplo siguiente se muestra un entero que representa el día de la semana de una fecha concreta.
using System;
Module Example
Public Sub Main()
Dim dateValue As Date = #6/11/2008#
Console.WriteLine(dateValue.DayOfWeek)
End Sub
End Module
' The example displays the following output:
' 3
Para obtener el nombre abreviado del día de la semana a partir de una fecha específica
1. Cuando trabaje con la representación de cadena de una fecha, conviértala en un valor DateTime o
DateTimeOffset mediante el método estático DateTime.Parse o DateTimeOffset.Parse.
2. Puede obtener el nombre abreviado de un día de la semana de la referencia cultural actual o de una
referencia cultural específica:
a. Para obtener el nombre abreviado del día de la semana de la referencia cultural actual, llame al
método de instancia DateTime.ToString(String) o DateTimeOffset.ToString(String) del valor de fecha
y hora, y pase la cadena "ddd" como parámetro format . En el ejemplo siguiente se muestra la
llamada al método ToString(String).
using System;
Module Example
Public Sub Main()
Dim dateValue As Date = #6/11/2008#
Console.WriteLine(dateValue.ToString("ddd"))
End Sub
End Module
' The example displays the following output:
' Wed
b. Para obtener el nombre abreviado del día de la semana de una referencia cultural específica, llame al
método de instancia DateTime.ToString(String, IFormatProvider) o DateTimeOffset.ToString(String,
IFormatProvider) del valor de fecha y hora. Pase la cadena "ddd" como parámetro format . Pase un
objeto CultureInfo o DateTimeFormatInfo que represente la referencia cultural cuyo nombre del día
de la semana desee recuperar como parámetro provider . En el código siguiente se muestra una
llamada al método ToString(String, IFormatProvider) con un objeto CultureInfo que representa la
referencia cultural fr-FR.
using System;
using System.Globalization;
Module Example
Public Sub Main()
Dim dateValue As Date = #6/11/2008#
Console.WriteLine(dateValue.ToString("ddd",
New CultureInfo("fr-FR")))
End Sub
End Module
' The example displays the following output:
' mer.
Para obtener el nombre completo del día de la semana a partir de una fecha específica
1. Cuando trabaje con la representación de cadena de una fecha, conviértala en un valor DateTime o
DateTimeOffset mediante el método estático DateTime.Parse o DateTimeOffset.Parse.
2. Puede obtener el nombre completo de un día de la semana de la referencia cultural actual o de una
referencia cultural específica:
a. Para obtener el nombre del día de la semana de la referencia cultural actual, llame al método de
instancia DateTime.ToString(String) o DateTimeOffset.ToString(String) del valor de fecha y hora, y
pase la cadena "dddd" como parámetro format . En el ejemplo siguiente se muestra la llamada al
método ToString(String).
using System;
Module Example
Public Sub Main()
Dim dateValue As Date = #6/11/2008#
Console.WriteLine(dateValue.ToString("dddd"))
End Sub
End Module
' The example displays the following output:
' Wednesday
b. Para obtener el nombre del día de la semana de una referencia cultural específica, llame al método
de instancia DateTime.ToString(String, IFormatProvider) o DateTimeOffset.ToString(String,
IFormatProvider) del valor de fecha y hora. Pase la cadena "dddd" como parámetro format . Pase un
objeto CultureInfo o DateTimeFormatInfo que represente la referencia cultural cuyo nombre del día
de la semana desee recuperar como parámetro provider . En el código siguiente se muestra una
llamada al método ToString(String, IFormatProvider) con un objeto CultureInfo que representa la
referencia cultural es-ES.
using System;
using System.Globalization;
Imports System.Globalization
Module Example
Public Sub Main()
Dim dateValue As Date = #6/11/2008#
Console.WriteLine(dateValue.ToString("dddd", _
New CultureInfo("es-ES")))
End Sub
End Module
' The example displays the following output:
' miércoles.
Ejemplo
En el ejemplo se muestran llamadas a las propiedades DateTime.DayOfWeek y DateTimeOffset.DayOfWeek y los
métodos DateTime.ToString y DateTimeOffset.ToString para recuperar el número que representa el día de la
semana, el nombre abreviado del día de la semana y el nombre completo del día de la semana para una fecha en
particular.
using System;
using System.Globalization;
try
{
DateTimeFormatInfo dateTimeFormats;
// Convert date representation to a date value
dateValue = DateTime.Parse(dateString, CultureInfo.InvariantCulture);
dateOffsetValue = new DateTimeOffset(dateValue,
TimeZoneInfo.Local.GetUtcOffset(dateValue));
Module Example
Public Sub Main()
Dim dateString As String = "6/11/2007"
Dim dateValue As Date
Dim dateOffsetValue As DateTimeOffset
Try
Dim dateTimeFormats As DateTimeFormatInfo
' Convert date representation to a date value
dateValue = Date.Parse(dateString, CultureInfo.InvariantCulture)
dateOffsetValue = New DateTimeOffset(dateValue, _
TimeZoneInfo.Local.GetUtcOffset(dateValue))
' Convert date representation to a number indicating the day of week
Console.WriteLine(dateValue.DayOfWeek)
Console.WriteLine(dateOffsetValue.DayOfWeek)
Imports System.Globalization
Imports System.Threading
Module Example
Public Sub Main()
Dim dateValue As Date = #6/11/2008#
También se puede usar el valor devuelto por la propiedad DateTime.DayOfWeek para recuperar el nombre del día
de la semana de una fecha en particular. Para ello, solo se necesita hacer una llamada al método ToString en el
valor DayOfWeek devuelto por la propiedad. Sin embargo, esta técnica no produce el nombre localizado de un día
de la semana para la referencia cultural actual, tal como se muestra en el ejemplo siguiente.
using System;
using System.Globalization;
using System.Threading;
Imports System.Globalization
Imports System.Threading
Module Example
Public Sub Main()
' Change current culture to fr-FR
Dim originalCulture As CultureInfo = Thread.CurrentThread.CurrentCulture
Thread.CurrentThread.CurrentCulture = New CultureInfo("fr-FR")
Vea también
Efectuar operaciones de formato
Standard Date and Time Format Strings
Custom Date and Time Format Strings
Procedimiento para definir y usar proveedores de
formato numérico personalizado
04/11/2019 • 11 minutes to read • Edit Online
.NET Framework ofrece un amplio control sobre la representación de cadena de valores numéricos. Admite las
siguientes características para personalizar el formato de los valores numéricos:
Cadenas con formato numérico estándar, que proporcionan un conjunto predefinido de formatos para
convertir números en su representación de cadena. Se pueden usar con cualquier método de formato
numérico, como Decimal.ToString(String), que tiene un parámetro format . Para obtener detalles, vea
Cadenas con formato numérico estándar.
Cadenas con formato numérico personalizado, que proporcionan un conjunto de símbolos que pueden
combinarse para definir especificadores de formato numérico personalizado. Se pueden usar también con
cualquier método de formato numérico, como Decimal.ToString(String), que tiene un parámetro format .
Para obtener detalles, consulte Cadenas con formato numérico personalizado.
Objetos personalizados CultureInfo o NumberFormatInfo, que definen los símbolos y los modelos de
formato que se usan para mostrar las representaciones de cadena de valores numéricos. Se pueden usar
con cualquier método de formato numérico, como ToString, que tiene un parámetro provider .
Normalmente, el parámetro provider se usa para especificar el formato específico de la referencia cultural.
En algunos casos (por ejemplo, cuando una aplicación debe mostrar un número de cuenta con formato, un número
de identificación o un código postal) estas tres técnicas no resultan apropiadas. .NET Framework también permite
definir un objeto de formato que no es ni un objeto CultureInfo ni NumberFormatInfo para determinar cómo se
aplica formato a un valor numérico. En este tema se proporcionan instrucciones paso a paso para implementar
este tipo de objeto y se ofrece un ejemplo que da formato a números de teléfono.
Para definir un proveedor de formato personalizado
1. Defina una clase que implementa las interfaces IFormatProvider y ICustomFormatter.
2. Implemente el método IFormatProvider.GetFormat. GetFormat es un método de devolución de llamada
que el método de formato (como el método String.Format(IFormatProvider, String, Object[])) invoca para
recuperar el objeto realmente responsable del formato personalizado. Una implementación típica de
GetFormat hace lo siguiente:
a. Determina si el objeto Type pasado como un parámetro de método representa a una interfaz
ICustomFormatter.
b. Si el parámetro representa a la interfaz ICustomFormatter, GetFormat devuelve un objeto que
implementa la interfaz ICustomFormatter, que es responsable de proporcionar el formato
personalizado. Normalmente, el objeto de formato personalizado se devuelve a sí mismo.
c. Si el parámetro no representa la interfaz ICustomFormatter, GetFormat devuelve null .
3. Implemente el método Format. Este método es invocado por el método String.Format(IFormatProvider,
String, Object[]) y es responsable de devolver la representación de cadena de un número. La
implementación del método normalmente implica lo siguiente:
a. Opcionalmente, asegúrese de que el método se haya diseñado para proporcionar servicios de
formato al examinar el parámetro provider . En el caso de los objetos de formato que implementan
IFormatProvider y ICustomFormatter, esto implica probar la igualdad del parámetro provider y el
objeto de formato actual.
b. Determine si el objeto de formato debe admitir especificadores de formato personalizado. (Por
ejemplo, un especificador de formato "N" podría indicar que debe generarse un número de teléfono
de los Estados Unidos en formato NANP, mientras que una "I" podría indicar la salida en el formato
de la recomendación E.123 de ITU -T). Si se usan especificadores de formato, el método debe
controlar el especificador de formato específico. Se pasa al método en el parámetro format . Si no
hay ningún especificador, el valor del parámetro format es String.Empty.
c. Recupere el valor numérico pasado al método como parámetro arg . Realice todas las
manipulaciones necesarias para convertirlo en su representación de cadena.
d. Devuelva la representación de cadena del parámetro arg .
Para usar un objeto de formato numérico personalizado
1. Cree una nueva instancia de la clase de formato personalizado.
2. Llame al método de formato String.Format(IFormatProvider, String, Object[]) y pásele el objeto de formato
personalizado, el especificador de formato (o String.Empty si no se usa ninguno) y el valor numérico al que
se va a dar formato.
Ejemplo
En el ejemplo siguiente se define un proveedor de formato numérico personalizado denominado
TelephoneFormatter que convierte un número que representa un número de teléfono de los Estados Unidos en su
formato NANP o E.123. El método controla dos especificadores de formato, "N" (que genera el formato NANP ) e
"I" (que genera el formato E.123 internacional).
using System;
using System.Globalization;
if (format == "N")
{
if (numericString.Length <= 4)
return numericString;
else if (numericString.Length == 7)
return numericString.Substring(0, 3) + "-" + numericString.Substring(3, 4);
else if (numericString.Length == 10)
return "(" + numericString.Substring(0, 3) + ") " +
numericString.Substring(3, 3) + "-" + numericString.Substring(6);
else
else
throw new FormatException(
string.Format("'{0}' cannot be used to format {1}.",
format, arg.ToString()));
}
else if (format == "I")
{
if (numericString.Length < 10)
throw new FormatException(string.Format("{0} does not have 10 digits.", arg.ToString()));
else
numericString = "+1 " + numericString.Substring(0, 3) + " " + numericString.Substring(3, 3) + " "
+ numericString.Substring(6);
}
else
{
throw new FormatException(string.Format("The {0} format specifier is invalid.", format));
}
return numericString;
}
}
Pero también permite que se produzca la conversión si no hay ningún especificador de formato. En el ejemplo
siguiente se muestra una llamada al método así.
if (arg is IFormattable)
s = ((IFormattable)arg).ToString(format, formatProvider);
else if (arg != null)
s = arg.ToString();
En el caso de este ejemplo, el método que implementa ICustomFormatter.Format está diseñado para que actúe
como un método de devolución de llamada para el método String.Format(IFormatProvider, String, Object[]). Por lo
tanto, examina el parámetro formatProvider para determinar si contiene una referencia al objeto
TelephoneFormatter actual. Pero también se puede llamar al método directamente desde el código. En ese caso,
puede usar el parámetro formatProvider para proporcionar un objeto CultureInfo o NumberFormatInfo que
aporte información de formato específica de la referencia cultural.
Vea también
Efectuar operaciones de formato
Procedimiento para valores de fecha y hora de ida y
vuelta
04/11/2019 • 11 minutes to read • Edit Online
En muchas aplicaciones, un valor de fecha y hora sirve para identificar inequívocamente un único punto en el
tiempo. Este tema muestra cómo guardar y restaurar un valor DateTime, un valor DateTimeOffset y un valor de
fecha y hora con información sobre la zona horaria, de manera que el valor restaurado identifique la misma hora
que el valor guardado.
Para un valor DateTime de ida y vuelta
1. Convierta el valor DateTime en su representación de cadena mediante una llamada al método
DateTime.ToString(String) con el especificador de formato "o".
2. Guarde la representación de cadena del valor DateTime en un archivo o pásela a través de un límite de
proceso, dominio de aplicación o máquina.
3. Recupere la cadena que representa el valor DateTime.
4. Llame al método DateTime.Parse(String, IFormatProvider, DateTimeStyles) y pase
DateTimeStyles.RoundtripKind como el valor del parámetro styles .
En el ejemplo siguiente se muestra cómo usar un valor DateTime de ida y vuelta.
Cuando se usa un valor DateTime de ida y vuelta, esta técnica mantiene correctamente la hora para todas las horas
locales y universales. Por ejemplo, si un valor local DateTime se guarda en un sistema de la zona horaria estándar
del Pacífico de Estados Unidos y se restaura en un sistema de la zona horaria estándar central de Estados Unidos,
la fecha y hora restauradas serán dos horas posteriores a la hora original, lo que refleja la diferencia horaria entre
las dos zonas. Pero esta técnica no es necesariamente precisa para horas no especificadas. Todos los valores
DateTime cuya propiedad Kind es Unspecified se tratan como si fueran horas locales. Si no es el caso, DateTime no
identificará correctamente el punto en el tiempo. La solución alternativa para esta limitación es acoplar
estrechamente un valor de fecha y hora con su zona horaria para la operación de guardado y restauración.
Para un valor DateTimeOffset de ida y vuelta
1. Convierta el valor DateTimeOffset en su representación de cadena mediante una llamada al método
DateTimeOffset.ToString(String) con el especificador de formato "o".
2. Guarde la representación de cadena del valor DateTimeOffset en un archivo o pásela a través de un límite
de proceso, dominio de aplicación o máquina.
3. Recupere la cadena que representa el valor DateTimeOffset.
4. Llame al método DateTimeOffset.Parse(String, IFormatProvider, DateTimeStyles) y pase
DateTimeStyles.RoundtripKind como el valor del parámetro styles .
Esta técnica identifica siempre de forma inequívoca un valor DateTimeOffset como un único punto en el tiempo. El
valor puede convertirse entonces en la hora universal coordinada (UTC ) al llamar al método
DateTimeOffset.ToUniversalTime, o bien puede convertirse en la hora de una zona horaria concreta al llamar a los
métodos DateTimeOffset.ToOffset o TimeZoneInfo.ConvertTime(DateTimeOffset, TimeZoneInfo). La limitación
principal de esta técnica está en que las operaciones aritméticas de fecha y hora, cuando se realizan en un valor
DateTimeOffset que representa la hora en una zona horaria determinada, podrían no generar resultados precisos
para esa zona horaria. Esto se debe a que, cuando se crea una instancia de un valor DateTimeOffset, se desasocia
de su zona horaria. Por lo tanto, ya no se pueden aplicar las reglas de ajuste de esa zona de horaria al realizar
cálculos de fecha y hora. Para evitar este problema, puede definir un tipo personalizado que incluya tanto el valor
de fecha y hora como la zona horaria correspondiente.
Para un valor de fecha y hora de ida y vuelta con su zona horaria
1. Defina una clase o una estructura con dos campos. El primer campo es un objeto DateTime o
DateTimeOffset y el segundo es un objeto TimeZoneInfo. El ejemplo siguiente es una versión sencilla de
ese tipo.
public DateInTimeZone() {}
this.thisDate = date;
this.tz = timeZone;
}
Esta técnica debe reflejar siempre de forma inequívoca el punto correcto de tiempo antes y después de guardar y
restaurar, siempre que la implementación del objeto combinado de fecha y hora y de zona horaria no permita que
el valor de fecha quede fuera de la sincronización con el valor de zona horaria.
Compilar el código
Para estos ejemplos se necesita:
Que los espacios de nombres siguientes se importen con instrucciones using de C# o con instrucciones
Imports de Visual Basic:
Vea también
Efectuar operaciones de formato
Elección entre DateTime, DateTimeOffset, TimeSpan y TimeZoneInfo
Standard Date and Time Format Strings
Procedimiento para mostrar milisegundos en los
valores de fecha y hora
18/12/2019 • 7 minutes to read • Edit Online
Los métodos de formato de fecha y hora predeterminados, como DateTime.ToString(), incluyen las horas, minutos
y segundos de un valor de tiempo, pero excluyen el componente correspondiente a los milisegundos. En este tema
se muestra cómo se incluye un componente de milisegundos de un valor de fecha y hora en cadenas de fecha y
hora con formato.
Para mostrar el componente de milisegundos de un valor DateTime
1. Cuando trabaje con la representación de cadena de una fecha, conviértala en un valor DateTime o
DateTimeOffset mediante el método estático DateTime.Parse(String) o DateTimeOffset.Parse(String).
2. Para extraer la representación de cadena del componente de milisegundos de una hora, llame al método
DateTime.ToString(String) o ToString del valor de fecha y hora y pase el modelo de formato personalizado
fff o FFF en solitario o junto a otros especificadores de formato personalizado como el parámetro
format .
Ejemplo
En el ejemplo se muestra el componente de milisegundos de un valor DateTime y DateTimeOffset en la consola en
su presentación en solitario e incluido en una cadena de fecha y hora más larga.
using System;
using System.Globalization;
using System.Text.RegularExpressions;
try
{
DateTime dateValue = DateTime.Parse(dateString);
DateTimeOffset dateOffsetValue = DateTimeOffset.Parse(dateString);
// Display Millisecond component with modified full date and time pattern.
Console.WriteLine("Modified full date time pattern: {0}",
dateValue.ToString(fullPattern));
Console.WriteLine("Modified full date time pattern: {0}",
dateOffsetValue.ToString(fullPattern));
}
catch (FormatException)
{
Console.WriteLine("Unable to convert {0} to a date.", dateString);
}
}
}
// The example displays the following output if the current culture is en-US:
// Millisecond component only: 126
// Millisecond component only: 126
// Date and Time with Milliseconds: 07/16/2008 08:32:45.126 AM
// Date and Time with Milliseconds: 07/16/2008 08:32:45.126 AM
// Modified full date time pattern: Wednesday, July 16, 2008 8:32:45.126 AM
// Modified full date time pattern: Wednesday, July 16, 2008 8:32:45.126 AM
Imports System.Globalization
Imports System.Text.REgularExpressions
Module MillisecondDisplay
Public Sub Main()
Try
Dim dateValue As Date = Date.Parse(dateString)
Dim dateOffsetValue As DateTimeOffset = DateTimeOffset.Parse(dateString)
' Append millisecond pattern to current culture's full date time pattern
Dim fullPattern As String = DateTimeFormatInfo.CurrentInfo.FullDateTimePattern
fullPattern = Regex.Replace(fullPattern, "(:ss|:s)", "$1.fff")
' Display Millisecond component with modified full date and time pattern.
Console.WriteLine("Modified full date time pattern: {0}", _
dateValue.ToString(fullPattern))
Console.WriteLine("Modified full date time pattern: {0}", _
dateOffsetValue.ToString(fullPattern))
Catch e As FormatException
Console.WriteLine("Unable to convert {0} to a date.", dateString)
End Try
End Sub
End Module
' The example displays the following output if the current culture is en-US:
' Millisecond component only: 126
' Millisecond component only: 126
' Date and Time with Milliseconds: 07/16/2008 08:32:45.126 AM
' Date and Time with Milliseconds: 07/16/2008 08:32:45.126 AM
' Modified full date time pattern: Wednesday, July 16, 2008 8:32:45.126 AM
' Modified full date time pattern: Wednesday, July 16, 2008 8:32:45.126 AM
El modelo de formato fff incluye todos los ceros finales en el valor de milisegundos. El modelo de formato FFF
suprime todos estos ceros. En el siguiente ejemplo se ilustra la diferencia.
NOTE
Es posible mostrar unidades fraccionarias de segundo muy pequeñas, como diezmilésimas o cienmilésimas de segundo. Sin
embargo, estos valores no suelen ser significativos. La precisión de los valores de fecha y hora depende de la resolución del
reloj del sistema. En los sistemas operativos Windows NT 3.5 (y versiones posteriores) y Windows Vista, la resolución del reloj
es aproximadamente de 10 a 15 milisegundos.
Vea también
DateTimeFormatInfo
Custom Date and Time Format Strings
Procedimiento para mostrar fechas en calendarios no
gregorianos
04/11/2019 • 12 minutes to read • Edit Online
Los tipos DateTime y DateTimeOffset usan el calendario gregoriano como calendario predeterminado. Esto
significa que al llamar al método ToString de un valor de fecha y hora se muestra la representación de cadena de
esa fecha y hora en el calendario gregoriano, aunque se creara con otro calendario. Esto se muestra en el ejemplo
siguiente, que usa dos maneras diferentes de crear un valor de fecha y hora con el calendario persa, pero muestra
esos valores de fecha y hora en el calendario gregoriano cuando llama al método ToString. En este ejemplo se
reflejan dos técnicas usadas habitualmente, aunque incorrectas, para mostrar la fecha en un calendario
determinado.
Se pueden usar dos técnicas distintas para mostrar la fecha en un calendario determinado. La primera exige que el
calendario sea el predeterminado de una referencia cultural determinada. La segunda se puede usar con cualquier
calendario.
Para mostrar la fecha del calendario predeterminado de una referencia cultural
1. Cree una instancia de un objeto de calendario derivado de la clase Calendar que representa al calendario
que se va a usar.
2. Cree una instancia de un objeto CultureInfo que representa la referencia cultural cuyo formato se va a usar
para mostrar la fecha.
3. Llame al método Array.Exists para determinar si el objeto de calendario es miembro de la matriz devuelta
por la propiedad CultureInfo.OptionalCalendars. Esto indica que el calendario puede actuar como
calendario predeterminado del objeto CultureInfo. Si no es miembro de la matriz, siga las instrucciones de
la sección "Para mostrar la fecha en cualquier calendario".
4. Asigne el objeto de calendario a la propiedad Calendar del objeto DateTimeFormatInfo devuelto por la
propiedad CultureInfo.DateTimeFormat.
NOTE
La clase CultureInfo también tiene una propiedad Calendar. Pero es de solo lectura y constante; no cambia para
reflejar el nuevo calendario predeterminado asignado a la propiedad DateTimeFormatInfo.Calendar.
5. Llame al método ToString o ToString y pásele el objeto CultureInfo cuyo calendario predeterminado se
modificó en el paso anterior.
Para mostrar la fecha en cualquier calendario
1. Cree una instancia de un objeto de calendario derivado de la clase Calendar que representa al calendario
que se va a usar.
2. Determine qué elementos de fecha y hora deben aparecer en la representación de cadena del valor de fecha
y hora.
3. Para cada elemento de fecha y hora que quiera mostrar, llame al método Get del objeto de calendario... .
Están disponibles los siguientes métodos:
GetYear, para mostrar el año en el calendario adecuado.
GetMonth, para mostrar el mes en el calendario adecuado.
GetDayOfMonth, para mostrar el número del día del mes en el calendario adecuado.
GetHour, para mostrar la hora del día en el calendario adecuado.
GetMinute, para mostrar los minutos de la hora en el calendario adecuado.
GetSecond, para mostrar los segundos del minuto en el calendario adecuado.
GetMilliseconds, para mostrar los milisegundos del segundo en el calendario adecuado.
Ejemplo
En el ejemplo se muestra una fecha con dos calendarios diferentes. Se muestra la fecha después de definir el
calendario Hijri como calendario predeterminado de la referencia cultural ar-JO y se muestra la fecha con el
calendario persa, que no se admite como calendario opcional de la referencia cultural fa-IR.
using System;
using System.Globalization;
Console.WriteLine();
if (this.CalendarExists(culture))
{
Console.WriteLine("Displaying date in supported {0} calendar...",
this.thisCalendar.GetType().Name);
culture.DateTimeFormat.Calendar = this.thisCalendar;
return dateToDisplay.ToString(specifier, culture);
}
else
{
Console.WriteLine("Displaying date in unsupported {0} calendar...",
thisCalendar.GetType().Name);
string separator = targetCulture.DateTimeFormat.DateSeparator;
return thisCalendar.GetYear(dateToDisplay.DateTime).ToString("0000") +
separator +
thisCalendar.GetMonth(dateToDisplay.DateTime).ToString("00") +
separator +
thisCalendar.GetDayOfMonth(dateToDisplay.DateTime).ToString("00");
}
}
}
// The example displays the following output to the console:
// Using the system default culture: 7/3/2008
// Using the ar-JO culture's original default calendar: 03/07/2008
// Using the ar-JO culture with Hijri as the default calendar:
// Displaying date in supported HijriCalendar calendar...
// 1429/06/29
// Displaying date in supported HijriCalendar calendar...
// 1429/06/29
//
// Using the ir-FA culture's default calendar: 7/3/2008
// Displaying date in unsupported PersianCalendar calendar...
// 1387/04/13
// Displaying date in unsupported PersianCalendar calendar...
// 1387/04/13
Imports System.Globalization
Console.WriteLine()
' Display the date using the ir-FA culture's default calendar.
Console.WriteLine("Using the ir-FA culture's default calendar: {0}", _
dateValue1.ToString("d", ic))
' Display a Date value.
Console.WriteLine(persianUtil.DisplayDate(dateValue1, ic))
' Display a DateTimeOffset value.
Console.WriteLine(persianUtil.DisplayDate(dateValue2, ic))
End Sub
End Class
If Me.CalendarExists(culture) Then
Console.WriteLine("Displaying date in supported {0} calendar...", _
thisCalendar.GetType().Name)
culture.DateTimeFormat.Calendar = Me.thisCalendar
Return dateToDisplay.ToString(specifier, culture)
Else
Console.WriteLine("Displaying date in unsupported {0} calendar...", _
thisCalendar.GetType().Name)
Cada objeto CultureInfo puede admitir uno o varios calendarios, que se indican mediante la propiedad
OptionalCalendars. Uno de ellos se designa como calendario predeterminado de la referencia cultural y es
devuelto por la propiedad de solo lectura CultureInfo.Calendar. Otro de los calendarios opcionales se puede
designar como valor predeterminado si se asigna un objeto Calendar que represente ese calendario a la propiedad
DateTimeFormatInfo.Calendar devuelta por la propiedad CultureInfo.DateTimeFormat. Pero algunos calendarios,
como el persa representado por la clase PersianCalendar, no actúan como calendarios opcionales de ninguna
referencia cultural.
En el ejemplo se define una clase de utilidad de calendario reutilizable, CalendarUtility , para controlar muchos de
los detalles de generación de la representación de cadena de una fecha mediante un calendario determinado. La
clase CalendarUtility tiene los siguientes miembros:
Un constructor parametrizado cuyo único parámetro es un objeto Calendar en el que se va a representar
una fecha. Se asigna a un campo privado de la clase.
CalendarExists, un método privado que devuelve un valor booleano que indica si el calendario
representado por el objeto CalendarUtility es compatible con el objeto CultureInfo pasado al método
como parámetro. El método encapsula una llamada al método Array.Exists, al que pasa la matriz
CultureInfo.OptionalCalendars.
HasSameName, un método privado asignado al delegado Predicate<T> que se pasa como parámetro al
método Array.Exists. Cada miembro de la matriz se pasa al método hasta que este devuelve true . El
método determina si el nombre de un calendario opcional es igual que el calendario representado por el
objeto CalendarUtility .
DisplayDate , un método público sobrecargado al que se pasan dos parámetros: un valor DateTime o
DateTimeOffset para expresar en el calendario representado por el objeto CalendarUtility ; y la referencia
cultural cuyas reglas de formato se van a usar. Su comportamiento a la hora de devolver la representación
de cadena de una fecha depende de si la referencia cultural cuyas reglas de formato se van a usar admite el
calendario de destino.
Independientemente del calendario usado para crear un valor DateTime o DateTimeOffset en este ejemplo, ese
valor normalmente se expresa como una fecha gregoriana. Esto se debe a que los tipos DateTime y
DateTimeOffset no conservan ninguna información del calendario. Internamente, se representan como el número
de tics transcurridos desde la medianoche del 1 de enero de 0001. La interpretación de ese número depende del
calendario. En la mayoría de las referencias culturales, el calendario predeterminado es el gregoriano.
Vea también
Efectuar operaciones de formato
Manipular cadenas en .NET
04/11/2019 • 2 minutes to read • Edit Online
.NET proporciona un amplio conjunto de rutinas que permiten crear, comparar y modificar cadenas de forma
eficaz, así como analizar rápidamente grandes cantidades de texto y datos para buscar, quitar y reemplazar
patrones de texto.
En esta sección
Procedimientos recomendados para el uso de cadenas
Se examinan los métodos de ordenación, comparación y uso de mayúsculas y minúsculas de cadenas de .NET y se
proporcionan recomendaciones para seleccionar un método de control de cadenas.
Expresiones regulares de .NET
Se proporciona información sobre expresiones regulares de .NET, incluidos elementos de lenguaje,
comportamiento de expresiones regulares y ejemplos.
Operaciones básicas de cadenas
Se describen las operaciones de cadenas que proporcionan las clases System.String y System.Text.StringBuilder,
incluida la creación de cadenas a partir de matrices de bytes, la comparación de valores de cadena y la
modificación de cadenas existentes.
Secciones relacionadas
Conversión de tipos en .NET
Se explican las técnicas y reglas utilizadas para convertir tipos con .NET.
Aplicación de formato a tipos
Se explica cómo usar la biblioteca de clases base para implementar el formato, cómo dar formato a tipos
numéricos, cómo dar formato a tipos de cadena y cómo dar formato a una referencia cultural concreta.
Parsing Strings
Describe cómo inicializar objetos en los valores descritos por representaciones de cadena de dichos objetos. El
análisis es la operación inversa de la aplicación de formato.
Procedimientos recomendados para el uso de
cadenas en .NET
13/01/2020 • 58 minutes to read • Edit Online
.NET proporciona una gran compatibilidad para desarrollar aplicaciones localizadas y globalizadas, y simplifica la
aplicación de las convenciones de la referencia cultural actual o de una referencia cultural concreta al realizar
operaciones comunes como ordenar y mostrar cadenas. Pero ordenar o comparar cadenas no es siempre una
operación dependiente de la referencia cultural. Por ejemplo, las cadenas usadas internamente por una aplicación
normalmente se deben administrar de forma idéntica en todas las referencias culturales. Cuando los datos de
cadenas independientes de la referencia cultural (como etiquetas XML, etiquetas HTML, nombres de usuario,
rutas de acceso de archivos y nombres de objetos del sistema) se interpretan como si fueran dependientes de la
referencia cultural, el código de aplicación puede estar sujeto a errores imperceptibles, un rendimiento inadecuado
y, en algunos casos, a problemas de seguridad.
En este tema, se examinan los métodos de ordenación, comparación y uso de mayúsculas y minúsculas de
cadenas de .NET, se presentan recomendaciones para seleccionar un método adecuado de control de cadenas y se
proporciona información adicional sobre los métodos de control de cadenas. También se examina cómo se usan
para la presentación y el almacenamiento los datos con formato, como los datos numéricos y los datos de fecha y
hora.
Por ejemplo, el método IndexOf , que devuelve el índice de una subcadena en un objeto String que coincide con
un carácter o una cadena, tiene nueve sobrecargas:
IndexOf(Char), IndexOf(Char, Int32)y IndexOf(Char, Int32, Int32), que de forma predeterminada realizan una
búsqueda ordinal (con distinción entre mayúsculas y minúsculas e independiente de la referencia cultural) de
un carácter de la cadena.
IndexOf(String), IndexOf(String, Int32)y IndexOf(String, Int32, Int32), que de forma predeterminada realizan
una búsqueda con distinción entre mayúsculas y minúsculas y dependiente de la referencia cultural de una
subcadena de la cadena.
IndexOf(String, StringComparison), IndexOf(String, Int32, StringComparison)y IndexOf(String, Int32, Int32,
StringComparison), que incluyen un parámetro de tipo StringComparison que permite especificar el formato
de la comparación.
Se recomienda seleccionar una sobrecarga que no use valores predeterminados, por las razones siguientes:
Algunas sobrecargas con parámetros predeterminados (las que buscan un valor Char en la instancia de la
cadena) realizan una comparación ordinal, mientras que otras (las que buscan una cadena en la instancia de
la cadena) son dependientes de la referencia cultural. Es difícil recordar qué método usa cada valor
predeterminado y resulta fácil confundir las sobrecargas.
La intención del código que usa valores predeterminados para las llamadas al método no está clara. En el
ejemplo siguiente, en el cual se usan valores predeterminados, es difícil saber si el desarrollador pretendía
realizar una comparación ordinal o lingüística de dos cadenas, o si había alguna diferencia al usar
mayúsculas y minúsculas entre protocol y "http" que pudiera hacer que la prueba de igualdad devolviera
el valor false .
En general, se recomienda llamar a un método que no use los valores predeterminados, ya que hace que la
intención del código no sea ambigua. Esto, a su vez, hace el código más legible y más fácil de depurar y mantener.
En el ejemplo siguiente se abordan las cuestiones que se derivan del ejemplo anterior. Indica claramente que se
usa la comparación ordinal y que se omiten las diferencias en cuanto al uso de mayúsculas y minúsculas.
Sin embargo, la evaluación de dos cadenas para comprobar su igualdad o su criterio de ordenación no produce
ningún resultado correcto único; el resultado depende de los criterios empleados para comparar las cadenas. En
especial, las comparaciones de cadenas que son ordinales o que se basan en las convenciones de ordenación y uso
de mayúsculas y minúsculas de la referencia cultural actual o de la referencia cultural invariable (una referencia
cultural válida para la configuración regional basada en el idioma inglés) pueden producir resultados diferentes.
Además, las comparaciones de cadenas mediante las diferentes versiones de .NET o con .NET en distintos
sistemas operativos o versiones de sistema operativo pueden devolver resultados diferentes. Para más
información, vea Las cadenas y el estándar Unicode.
Comparaciones de cadenas que usan la referencia cultural actual
Un criterio implica usar las convenciones de la referencia cultural actual a la hora de comparar cadenas. Las
comparaciones que se basan en la referencia cultural actual usan la referencia cultural o la configuración regional
actual del subproceso. Si el usuario no establece la referencia cultural, se usa como valor predeterminado la
configuración de la ventana Opciones regionales del Panel de control. Siempre debe usar comparaciones
basadas en la referencia cultural actual cuando los datos sean lingüísticamente pertinentes y cuando refleje una
interacción con el usuario dependiente de la referencia cultural.
En cambio, el comportamiento de comparación y uso de mayúsculas y minúsculas de .NET cambia cuando la
referencia cultural cambia. Esto ocurre cuando una aplicación se ejecuta en un equipo que tiene una referencia
cultural diferente que el equipo en el que se desarrolló la aplicación o cuando el subproceso en ejecución cambia
su referencia cultural. Este comportamiento es deliberado, pero sigue resultando no obvio para muchos
desarrolladores. En el ejemplo siguiente, se muestran las diferencias en el criterio de ordenación entre las
referencias culturales de inglés de EE. UU. ("en-US") y sueco ("sv-SE"). Tenga en cuenta que las palabras
"ångström", "Windows" y "Visual Studio" aparecen en distintas posiciones en las matrices de cadenas ordenadas.
using System;
using System.Globalization;
using System.Threading;
Console.WriteLine();
}
}
// The example displays the following output:
// Sorting using the en-US culture:
// able
// Æble
// ångström
// apple
// Visual Studio
// Windows
//
// Sorting using the sv-SE culture:
// able
// Æble
// apple
// Windows
// Visual Studio
// ångström
Imports System.Globalization
Imports System.Threading
Module Example
Public Sub Main()
Dim values() As String = { "able", "ångström", "apple", _
"Æble", "Windows", "Visual Studio" }
Array.Sort(values)
DisplayArray(values)
Las comparaciones sin distinción entre mayúsculas y minúsculas que usan la referencia cultural actual son iguales
que las comparaciones dependientes de la referencia cultural, excepto que omiten el uso de mayúsculas y
minúsculas según indica la referencia cultural actual del subproceso. Este comportamiento también se puede
manifestar en los criterios de ordenación.
Las comparaciones que usan semántica de la referencia cultural actual son el valor predeterminado para los
métodos siguientes:
Sobrecargas deString.Compare que no incluyen un parámetro StringComparison .
Sobrecargas deString.CompareTo .
El método predeterminado String.StartsWith(String) y el método String.StartsWith(String, Boolean,
CultureInfo) con un parámetro null CultureInfo .
El método predeterminado String.EndsWith(String) y el método String.EndsWith(String, Boolean, CultureInfo)
con un parámetro null CultureInfo.
Sobrecargas deString.IndexOf que aceptan String como un parámetro de búsqueda y que no tienen un
parámetro StringComparison .
Sobrecargas deString.LastIndexOf que aceptan String como un parámetro de búsqueda y que no tienen un
parámetro StringComparison .
En cualquier caso, se recomienda llamar a una sobrecarga que tenga un parámetro StringComparison para aclarar
la intención de la llamada al método.
Pueden surgir errores imperceptibles y no tan imperceptibles cuando los datos de cadenas no lingüísticos se
interpretan lingüísticamente, o cuando los datos de cadenas de una referencia cultural determinada se interpretan
usando las convenciones de otra referencia cultural. El ejemplo canónico es el problema con I en turco.
Para casi todos los alfabetos latinos, incluso en inglés de EE. UU., el carácter "i" (\u0069) es la versión en
minúsculas del carácter "I" (\u0049). Esta regla de mayúsculas y minúsculas se convierte rápidamente en el valor
predeterminado para alguien que programe en esa referencia cultural. En cambio, el alfabeto turco ("tr-TR")
incluye un carácter "I con punto" "İ" (\u0130), que es la versión en mayúsculas de "i". El turco también incluye un
carácter "i sin punto" en minúscula, "ı" (\u0131), que en mayúsculas es "I". Este comportamiento también se
produce en la referencia cultural de azerbaiyano ("az").
Por tanto, los supuestos sobre poner en mayúsculas "i" o escribir "I" en minúsculas no son válidas en todas las
referencias culturales. Si usa las sobrecargas predeterminadas para las rutinas de comparación de cadenas,
estarán sujetas a variaciones entre distintas referencias culturales. Si los datos que se van a comparar son no
lingüísticos, el uso de las sobrecargas predeterminadas puede generar resultados no deseables, como ilustra el
siguiente intento de realizar una comparación sin distinción entre mayúsculas y minúsculas de las cadenas "file" y
"FILE".
using System;
using System.Globalization;
using System.Threading;
Module Example
Public Sub Main()
Dim fileUrl = "file"
Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
Console.WriteLine("Culture = {0}", _
Thread.CurrentThread.CurrentCulture.DisplayName)
Console.WriteLine("(file == FILE) = {0}", _
fileUrl.StartsWith("FILE", True, Nothing))
Console.WriteLine()
Esta comparación podría producir problemas importantes si la referencia cultural se usa involuntariamente en
configuraciones que afectan a la seguridad, como en el ejemplo siguiente. Una llamada al método como
IsFileURI("file:") devuelve true si la referencia cultural actual es inglés de EE. U.U., pero false si la referencia
cultural actual es el turco. Así, en los sistemas turcos, alguien podría sortear las medidas de seguridad que
bloquean el acceso a los URI sin distinción entre mayúsculas y minúsculas que comienzan con "FILE":.
En este caso, como "file:" se debe interpretar como un identificador no lingüístico e independiente de la referencia
cultural, el código se debe escribir como se muestra en el ejemplo siguiente:
IMPORTANT
Aunque los métodos de comparación de cadenas hacen caso omiso de los caracteres nulos incrustados, los métodos de
búsqueda de cadenas como String.Contains, String.EndsWith, String.IndexOf, String.LastIndexOfy String.StartsWith sí los
tienen en cuenta.
En el ejemplo siguiente se realiza una comparación dependiente de la referencia cultural de la cadena "Aa" con
una cadena similar que contiene varios caracteres nulos insertados entre "A" y "a", y se muestra cómo las dos
cadenas se consideran iguales:
using System;
Pero las cadenas no se consideran iguales cuando se usa la comparación ordinal, como se muestra en el ejemplo
siguiente:
Las comparaciones ordinales sin distinción entre mayúsculas y minúsculas son el siguiente enfoque más
conservador. Estas comparaciones omiten la mayor parte del uso de mayúsculas y minúsculas; por ejemplo,
"windows" coincide con "Windows". A la hora de tratar con caracteres ASCII, esta directiva es equivalente a
StringComparison.Ordinal, salvo que omite el uso de mayúsculas y minúsculas habitual de ASCII. Por tanto,
cualquier carácter de [A, Z ] (\u0041-\u005A) coincide con el carácter correspondiente de [a, z] (\u0061-\007A). El
uso de mayúsculas y minúsculas fuera del intervalo ASCII emplea las tablas de la referencia cultural de todos los
idiomas. Por tanto, la siguiente comparación:
String.Compare(strA.ToUpperInvariant(), strB.ToUpperInvariant(),
StringComparison.Ordinal);
String.Compare(strA.ToUpperInvariant(), strB.ToUpperInvariant(),
StringComparison.Ordinal)
NOTE
El comportamiento de las cadenas del sistema de archivos, claves del Registro y valores, y variables de entorno se representa
mejor mediante StringComparison.OrdinalIgnoreCase.
A la hora de interpretar nombres de archivo, cookies u otros elementos donde pueda aparecer una combinación
como "å", las comparaciones ordinales siguen ofreciendo el comportamiento más transparente y adecuado.
En conjunto, la referencia cultural de todos los idiomas tiene muy pocas propiedades que la hagan útil para la
comparación. Realiza la comparación de manera lingüísticamente pertinente, lo que le impide garantizar una
equivalencia simbólica completa, pero no es la opción ideal para la presentación en cualquier referencia cultural.
Una de las pocas razones para usar StringComparison.InvariantCulture con el fin de realizar una comparación es
para conservar datos ordenados cuando se desea realizar una presentación idéntica transculturalmente. Por
ejemplo, si un archivo de datos grande que contiene una lista de identificadores ordenados para su presentación
acompaña una aplicación, al agregar datos a esta lista se necesitaría realizar una inserción con ordenación de
estilo invariable.
VALOR DE SYSTEM.STRINGCOMPARISON
Variables de entorno.
this.fname = name;
if (comparer != null)
this.comparer = comparer;
else
this.comparer = StringComparer.OrdinalIgnoreCase;
}
if (! (obj is FileName))
return comparer.Compare(this.fname, obj.ToString());
else
return comparer.Compare(this.fname, ((FileName) obj).Name);
}
}
Public Class FileName : Implements IComparable
Dim fname As String
Dim comparer As StringComparer
Me.fname = name
String.Equals
Interpretación predeterminada: StringComparison.Ordinal.
La clase String le permite comprobar la igualdad llamando a las sobrecargas de método estático o de instancia
Equals , o usando el operador de igualdad estático. Las sobrecargas y el operador usan la comparación ordinal de
forma predeterminada. Sin embargo, todavía sigue siendo recomendable llamar a una sobrecarga que especifique
explícitamente el tipo StringComparison aunque desee realizar una comparación ordinal; esto facilita la búsqueda
de cierta interpretación de la cadena en el código.
String.ToUpper y String.ToLower
Interpretación predeterminada: StringComparison.CurrentCulture.
Debe tener cuidado al usar estos métodos, ya que forzar que una cadena esté en mayúsculas o en minúsculas se
usa a menudo como una pequeña normalización para comparar cadenas independientemente del uso de
mayúsculas y minúsculas. En tal caso, considere la posibilidad de emplear una comparación sin distinción entre
mayúsculas y minúsculas.
También están disponibles los métodos String.ToUpperInvariant y String.ToLowerInvariant . ToUpperInvariant es
la manera estándar de normalizar el uso de mayúsculas y minúsculas. Las comparaciones realizadas mediante
StringComparison.OrdinalIgnoreCase tienen un comportamiento que es la composición de dos llamadas: llamar a
ToUpperInvariant en ambos argumentos de cadena y realizar una comparación mediante
StringComparison.Ordinal.
También hay sobrecargas para convertir a mayúsculas y minúsculas en una referencia cultural concreta, pasando
al método un objeto CultureInfo que representa esa referencia cultural.
Char.ToUpper y Char.ToLower
Interpretación predeterminada: StringComparison.CurrentCulture.
Estos métodos funcionan de manera similar a los métodos String.ToUpper y String.ToLower descritos en la
sección anterior.
String.StartsWith y String.EndsWith
Interpretación predeterminada: StringComparison.CurrentCulture.
De forma predeterminada, estos dos métodos realizan una comparación dependiente de la referencia cultural.
String.IndexOf y String.LastIndexOf
Interpretación predeterminada: StringComparison.CurrentCulture.
No hay coherencia en cómo las sobrecargas predeterminadas de estos métodos realizan las comparaciones. Todos
los métodos String.IndexOf y String.LastIndexOf que incluyen un parámetro Char realizan una comparación
ordinal, pero los métodos String.IndexOf y String.LastIndexOf predeterminados que incluyen un parámetro String
realizan una comparación dependiente de la referencia cultural.
Si llama al método String.IndexOf(String) o String.LastIndexOf(String) y le pasa una cadena para ubicar en la
instancia actual, se recomienda llamar a una sobrecarga que especifique explícitamente el tipo StringComparison .
Las sobrecargas que incluyen un argumento Char no le permiten especificar un tipo StringComparison .
// Incorrect.
string []storedNames;
Array.Sort(names); // Line A.
}
' Incorrect.
Dim storedNames() As String
Aparece una variación recomendada en el ejemplo siguiente, que usa el mismo método de comparación ordinal
(independiente de la referencia cultural) para ordenar y buscar en la matriz. El código cambiado se refleja en las
líneas etiquetadas como Line A y Line B en los dos ejemplos.
// Correct.
string []storedNames;
' Correct.
Dim storedNames() As String
Si estos datos se conservan y mueven entre distintas referencias culturales, y se usa la ordenación para presentar
estos datos al usuario, es mejor usar StringComparison.InvariantCulture, que funciona lingüísticamente para
obtener una mejor salida para el usuario pero no se ve afectado por los cambios en la referencia cultural. En el
ejemplo siguiente se modifican los dos ejemplos anteriores para usar la referencia cultural de todos los idiomas
con el fin de ordenar y buscar en la matriz.
// Correct.
string []storedNames;
' Correct.
Dim storedNames() As String
Para la interpolación de cadenas, en lugar de asignar una cadena interpolada a una instancia String,
asígnela a un elemento FormattableString. Después, se puede llamar al método
FormattableString.ToString() para generar una cadena de resultado que refleje las convenciones de la
referencia cultural actual, o bien puede llamar al método FormattableString.ToString(IFormatProvider) para
generar una cadena de resultado que refleje las convenciones de la referencia cultural especificada.
También se puede pasar la cadena que admite formato al método estático FormattableString.Invariant con
el fin de generar una cadena de resultado que refleje las convenciones de la referencia cultural invariable.
En el ejemplo siguiente se muestra este enfoque. (La salida del ejemplo refleja una referencia cultural actual
de en-US ).
using System;
using System.Globalization;
class Program
{
static void Main()
{
Decimal value = 126.03m;
FormattableString amount = $"The amount is {value:C}";
Console.WriteLine(amount.ToString());
Console.WriteLine(amount.ToString(new CultureInfo("fr-FR")));
Console.WriteLine(FormattableString.Invariant(amount));
}
}
// The example displays the following output:
// The amount is $126.03
// The amount is 126,03 €
// The amount is ¤126.03
Imports System.Globalization
Module Program
Sub Main()
Dim value As Decimal = 126.03
Dim amount As FormattableString = $"The amount is {value:C}"
Console.WriteLine(amount.ToString())
Console.WriteLine(amount.ToString(new CultureInfo("fr-FR")))
Console.WriteLine(FormattableString.Invariant(amount))
End Sub
End Module
' The example displays the following output:
' The amount is $126.03
' The amount is 126,03 €
' The amount is ¤126.03
Puede conservar datos que no son de cadena como datos binarios o como datos con formato. Si decide
guardarlos como datos con formato, debe llamar a una sobrecarga del método de formato que incluya un
parámetro provider y pasarle la propiedad CultureInfo.InvariantCulture . La referencia cultural de todos los
idiomas proporciona un formato coherente para los datos con formato que es independiente de la referencia
cultural y del equipo. En cambio, si se conservan datos a los que se aplica formato con referencias culturales
distintas de la referencia cultural de todos los idiomas, se presentan varias limitaciones:
Es probable que los datos no puedan usarse si se recuperan en un sistema que tiene una referencia cultural
distinta, o si el usuario del sistema actual cambia la referencia cultural actual e intenta recuperar los datos.
Las propiedades de una referencia cultural en un equipo específico pueden diferir de los valores estándar. En
cualquier momento, un usuario puede personalizar la configuración de visualización que depende de la
cultural. Debido a esto, es posible que los datos con formato que se guardan en un sistema no sean legibles
después de que el usuario personalice la configuración de la referencia cultural. Es posible que la portabilidad
de los datos con formato entre equipos sea incluso más limitada.
Las normas internacionales, regionales o nacionales que rigen el formato de los números o las fechas y horas
cambian con el tiempo, y estos cambios se incorporan en las actualizaciones de los sistemas operativos
Windows. Cuando cambian las convenciones de formato, los datos a los que se aplicó formato usando las
convenciones anteriores pueden llegar a ser ilegibles.
En el ejemplo siguiente se muestra la portabilidad limitada que se deriva de usar el formato dependiente de la
referencia cultural para conservar los datos. En el ejemplo se guarda una matriz de valores de fecha y hora en un
archivo. Se les da formato con las convenciones de la referencia cultural Inglés (Estados Unidos). Después de que
la aplicación cambie la referencia cultural del subproceso actual a Francés (Suiza), intenta leer los valores
guardados usando las convenciones de formato de la referencia cultural actual. El intento de leer dos de los
elementos de datos genera una excepción FormatException y la matriz de fechas ahora contiene dos elementos
incorrectos que iguales a MinValue.
using System;
using System.Globalization;
using System.IO;
using System.Text;
using System.Threading;
Module Example
Private filename As String = ".\dates.dat"
06.05.1758 21:26
05.05.1818 07:19
22.04.1870 23:54
08.09.1890 06:47
18.02.1905 15:12
Vea también
Manipular cadenas
Operaciones básicas de cadenas en .NET
25/11/2019 • 2 minutes to read • Edit Online
A menudo, las aplicaciones responden a los usuarios mediante la construcción de mensajes basados en los datos
proporcionados por el usuario. Por ejemplo, no es raro que los sitios web respondan a un usuario que acaba de
iniciar sesión con un saludo especializado que incluye el nombre del usuario. Varios métodos de las clases
System.String y System.Text.StringBuilder le permiten construir cadenas personalizadas de forma dinámica para
mostrarlas en la interfaz de usuario. Estos métodos también le ayudan a realizar una serie de operaciones básicas
de cadenas, como crear cadenas nuevas a partir de matrices de bytes, comparar los valores de cadenas y
modificar cadenas existentes.
En esta sección
Creación de cadenas nuevas
Se describen formas básicas para convertir objetos en cadenas y combinar cadenas.
Recortar y quitar caracteres
Se describe cómo recortar o quitar caracteres de una cadena.
Rellenado de cadenas
Describe cómo insertar caracteres o espacios vacíos en una cadena.
Comparar cadenas
Se describe cómo comparar el contenido de dos o más cadenas.
Cambio de mayúsculas y minúsculas
Se describe cómo cambiar las mayúsculas y minúsculas de los caracteres de una cadena.
Utilizar la clase StringBuilder
Se describe cómo crear y modificar objetos de cadena dinámicos con la clase StringBuilder.
Cómo: para realizar manipulaciones de cadena básicas
Se describe el uso de las operaciones de cadena básicas.
Secciones relacionadas
Conversión de tipos en .NET
Se describe cómo convertir un tipo en otro.
Aplicación de formato a tipos
Se describe cómo dar formato a cadenas mediante los especificadores de formato.
Creación de cadenas en .NET
04/11/2019 • 7 minutes to read • Edit Online
.NET Framework permite crear cadenas mediante asignaciones simples y además sobrecarga un constructor de
clases para admitir la creación de cadenas con una serie de parámetros distintos. .NET Framework también
proporciona varios métodos en la clase System.String que crean nuevos objetos de cadena al combinar varias
cadenas, matrices de cadenas u objetos.
Formato
Puede usar el método String.Format para crear cadenas con formato y concatenar cadenas que representan a
varios objetos. Este método convierte automáticamente cualquier objeto pasado en una cadena. Por ejemplo, si la
aplicación debe mostrar un valor Int32 y un valor DateTime al usuario, puede construir fácilmente una cadena
para representar estos valores con el método Format. Para más información sobre las convenciones de formato
usadas con este método, consulte la sección sobre formatos compuestos.
En el ejemplo siguiente se usa el método Format para crear una cadena que emplea una variable de entero.
int numberOfFleas = 12;
string miscInfo = String.Format("Your dog has {0} fleas. " +
"It is time to get a flea collar. " +
"The current universal date is: {1:u}.",
numberOfFleas, DateTime.Now);
Console.WriteLine(miscInfo);
// The example displays the following output:
// Your dog has 12 fleas. It is time to get a flea collar.
// The current universal date is: 2008-03-28 13:31:40Z.
En este ejemplo, DateTime.Now muestra la fecha y hora actuales en el formato especificado por la referencia
cultural asociada al subproceso actual.
Concat
El método String.Concat se puede usar para crear fácilmente un objeto de cadena a partir de dos o más objetos
existentes. Proporciona una manera independiente del lenguaje de concatenar cadenas. Este método acepta
cualquier clase que derive de System.Object. En el ejemplo siguiente se crea una cadena a partir de dos objetos
de cadena existentes y un carácter de separación.
Join
El método String.Join crea una cadena a partir de una matriz de cadenas y una cadena separadora. Este método
resulta útil si quiere concatenar varias cadenas para formar una lista quizás separada por una coma.
En el ejemplo siguiente se usa un espacio para enlazar una matriz de cadenas.
Insertar
El método String.Insert crea una cadena al insertar una cadena en la posición especificada de otra cadena. Este
método usa un índice basado en cero. En el ejemplo siguiente se inserta una cadena en la quinta posición del
índice de MyString y se crea una nueva cadena con este valor.
CopyTo
El método String.CopyTo copia partes de una cadena en una matriz de caracteres. Puede especificar el índice
inicial de la cadena y el número de caracteres que se va a copiar. Este método toma el índice de origen, una matriz
de caracteres, el índice de destino y el número de caracteres que se va a copiar. Todos los índices se basan en cero.
En el ejemplo siguiente se usa el método CopyTo para copiar los caracteres de la palabra "Hello" de un objeto de
cadena en la primera posición del índice de una matriz de caracteres.
Vea también
Operaciones básicas de cadenas
Formatos compuestos
Recorte y eliminación de caracteres de cadenas en
.NET
04/11/2019 • 8 minutes to read • Edit Online
Si va a analizar una frase en las palabras que la forman, el resultado pueden ser palabras con espacios en blanco
delante y detrás. En este caso, puede usar uno de los métodos de recorte de la clase System.String para quitar
espacios u otros caracteres de una posición especificada de la cadena. En la tabla siguiente se describen los
métodos de recorte disponibles.
String.Trim Quita del comienzo y del final de una cadena los espacios en
blanco o los caracteres especificados en una matriz de
caracteres.
Trim
Los espacios en blanco situados delante y detrás de una cadena se pueden quitar fácilmente con el método
String.Trim, como se muestra en el ejemplo siguiente.
También se pueden quitar del principio y el final de una cadena los caracteres especificados en una matriz de
caracteres. En el ejemplo siguiente se quitan los caracteres de espacio en blanco, los puntos y asteriscos.
using System;
Module Example
Public Sub Main()
Dim header As String = "* A Short String. *"
Console.WriteLine(header)
Console.WriteLine(header.Trim( { " "c, "*"c, "."c } ))
End Sub
End Module
' The example displays the following output:
' * A Short String. *
' A Short String
TrimEnd
El método String.TrimEnd quita caracteres del final de una cadena, creando un nuevo objeto de cadena. A este
método se le pasa una matriz de caracteres para especificar los caracteres que se van a quitar. El orden de los
elementos en la matriz de caracteres no afecta a la operación de recorte. El recorte se detiene cuando se encuentra
un carácter no especificado en la matriz.
En el ejemplo siguiente se quitan las últimas letras de una cadena con el método TrimEnd. En este ejemplo, se
invierte la posición de los caracteres 'r' y 'W' para ilustrar que el orden de los caracteres en la matriz no tiene
importancia. Observe que este código quita la última palabra de MyString y parte de la primera.
TrimStart
El método String.TrimStart es parecido al método String.TrimEnd, con la diferencia de que crea una nueva
cadena quitando caracteres del comienzo de un objeto de cadena existente. Al método TrimStart se le pasa una
matriz de caracteres para especificar los caracteres que se van a quitar. Lo mismo que en el método TrimEnd, el
orden de los elementos en la matriz de caracteres no afecta a la operación de recorte. El recorte se detiene cuando
se encuentra un carácter no especificado en la matriz.
En el siguiente ejemplo se quita la primera palabra de una cadena. En este ejemplo, se invierte la posición de los
caracteres 'l' y 'H' para ilustrar que el orden de los caracteres en la matriz no tiene importancia.
Quitar
El método String.Remove quita un número especificado de caracteres, comenzando en una posición especificada
de una cadena existente. Este método utiliza un índice basado en cero.
En el ejemplo siguiente se quitan diez caracteres de una cadena, comenzando en la posición cinco de un índice de
base cero de la cadena.
Sustituya
También puede quitar un carácter o una subcadena de una cadena llamando al método String.Replace(String,
String) y especificando una cadena vacía (String.Empty) como reemplazo. En el ejemplo siguiente se quitan todas
las comas de una cadena.
using System;
Module Example
Public Sub Main()
Dim phrase As String = "a cold, dark night"
Console.WriteLine("Before: {0}", phrase)
phrase = phrase.Replace(",", "")
Console.WriteLine("After: {0}", phrase)
End Sub
End Module
' The example displays the following output:
' Before: a cold, dark night
' After: a cold dark night
Vea también
Operaciones básicas de cadenas
Relleno de cadenas en .NET
04/11/2019 • 2 minutes to read • Edit Online
Use uno de los siguientes métodos String para crear una cadena que conste de una cadena original rellenada con
caracteres iniciales o finales hasta una longitud total especificada. El carácter de relleno puede ser un espacio o un
carácter especificado. La cadena resultante aparece alineada a la derecha o bien a la izquierda. Si la longitud de la
cadena original ya es igual o mayor que la longitud total deseada, los métodos de relleno devuelven la cadena
original sin modificarla. Para obtener más información, vea las secciones Devoluciones de las dos sobrecargas de
los métodos String.PadLeft y String.PadRight.
String.PadLeft Rellena una cadena con caracteres iniciales hasta una longitud
total especificada.
String.PadRight Rellena una cadena con caracteres finales hasta una longitud
total especificada.
PadLeft
El método String.PadLeft crea una cadena mediante la concatenación de suficientes caracteres de relleno iniciales
con una cadena original para alcanzar la longitud total especificada. El método String.PadLeft(Int32) usa el espacio
en blanco como carácter de relleno y el método String.PadLeft(Int32, Char) le permite especificar su propio
carácter de relleno.
En el ejemplo de código siguiente se usa el método PadLeft para crear una cadena con una longitud de veinte
caracteres. En el ejemplo se muestra " --------Hello World! " en la consola.
PadRight
El método String.PadRight crea una cadena mediante la concatenación de suficientes caracteres de relleno finales
con una cadena original para alcanzar la longitud total especificada. El método String.PadRight(Int32) usa el
espacio en blanco como carácter de relleno y el método String.PadRight(Int32, Char) le permite especificar su
propio carácter de relleno.
En el ejemplo de código siguiente se usa el método PadRight para crear una cadena con una longitud de veinte
caracteres. En el ejemplo se muestra " Hello World!-------- " en la consola.
String^ MyString = "Hello World!";
Console::WriteLine(MyString->PadRight(20, '-'));
Vea también
Operaciones básicas de cadenas
Comparación de cadenas en .NET
04/11/2019 • 13 minutes to read • Edit Online
.NET proporciona varios métodos para comparar los valores de cadenas. En la tabla siguiente se enumeran y
describen los métodos de comparación de valores.
Comparar
El método String.Compare estático proporciona una manera de comparar dos cadenas exhaustivamente. En este
método se tiene en cuenta la referencia cultural. Esta función se puede usar para comparar dos cadenas o
subcadenas de dos cadenas. Además, se proporcionan sobrecargas para tener en cuenta o no las diferencias de
referencia cultural y de mayúsculas y minúsculas. En la tabla siguiente, se muestran los tres valores enteros que
este método puede devolver.
O bien
O bien
IMPORTANT
La finalidad principal del método String.Compare es que se utilice para la ordenación o clasificación de cadenas. El método
String.Compare no debe utilizarse para comprobar la igualdad (es decir, para buscar explícitamente un valor devuelto que sea
0 sin tener en cuenta si una cadena es menor o mayor que otra). En su lugar, para determinar si dos cadenas son iguales, use
el método String.Equals(String, String, StringComparison) .
En el ejemplo siguiente, se usa el método String.Compare para determinar los valores relativos de dos cadenas.
CompareOrdinal
El método String.CompareOrdinal compara dos objetos de cadena sin tener en cuenta la referencia cultural local.
Los valores devueltos de este método son idénticos a los que devolvía el método Compare en la tabla anterior.
IMPORTANT
La finalidad principal del método String.CompareOrdinal es que se utilice para la ordenación o clasificación de cadenas. El
método String.CompareOrdinal no debe utilizarse para comprobar la igualdad (es decir, para buscar explícitamente un valor
devuelto que sea 0 sin tener en cuenta si una cadena es menor o mayor que otra). En su lugar, para determinar si dos
cadenas son iguales, use el método String.Equals(String, String, StringComparison) .
En el ejemplo siguiente se usa el método CompareOrdinal para comparar los valores de dos cadenas.
CompareTo
El método String.CompareTo compara la cadena que encapsula el objeto de cadena actual con otra cadena u
objeto. Los valores devueltos de este método son idénticos a los que devolvía el método String.Compare en la
tabla anterior.
IMPORTANT
La finalidad principal del método String.CompareTo es que se utilice para la ordenación o clasificación de cadenas. El método
String.CompareTo no debe utilizarse para comprobar la igualdad (es decir, para buscar explícitamente un valor devuelto que
sea 0 sin tener en cuenta si una cadena es menor o mayor que otra). En su lugar, para determinar si dos cadenas son iguales,
use el método String.Equals(String, String, StringComparison) .
En el ejemplo siguiente se usa el método String.CompareTo para comparar los objetos string1 y string2 .
Es igual a
El método String.Equals puede determinar con facilidad si dos cadenas son iguales. Este método distingue entre
mayúsculas y minúsculas y devuelve un valor booleano True o False . Se puede usar desde una clase existente,
como se muestra en el siguiente ejemplo. En el ejemplo siguiente se usa el método Equals para determinar si un
objeto de cadena contiene la frase "Hello World".
StartsWith y EndsWith
El método String.StartsWith se puede usar para determinar si un objeto de cadena comienza con los mismos
caracteres que forman otra cadena. Este método distingue entre mayúsculas y minúsculas y devuelve true si el
objeto de cadena actual comienza con la cadena que se pasa y false si no lo hace. En el ejemplo siguiente se usa
este método para determinar si un objeto de cadena comienza con "Hello".
IndexOf y LastIndexOf
El método String.IndexOf se puede usar para determinar la posición de la primera aparición de un carácter
concreto dentro de una cadena. Este método, que distingue entre mayúsculas y minúsculas, empieza a contar
desde el comienzo de una cadena y devuelve la posición del carácter que se pasa utilizando un índice de base cero.
Si no encuentra el carácter, se devuelve un valor de –1.
En el ejemplo siguiente se usa el método IndexOf para buscar la primera aparición del carácter ' l ' en una
cadena.
Vea también
Operaciones básicas de cadenas
Realizar operaciones de cadenas que no distinguen entre referencias culturales
Ordenación de tablas de peso (para .NET en Windows)
Tabla de elementos de intercalación predeterminada Unicode (para .NET Core en macOS y Linux)
Cambiar mayúsculas y minúsculas en .NET
13/01/2020 • 8 minutes to read • Edit Online
Si escribe una aplicación que acepta la entrada de un usuario, nunca podrá estar seguro de si usará mayúsculas o
minúsculas para escribir los datos. Normalmente querrá que las cadenas usen mayúsculas y minúsculas de forma
coherente, especialmente si se van a mostrar en la interfaz de usuario. En la tabla siguiente se describen tres
métodos para cambiar las mayúsculas y minúsculas. Los dos primeros métodos proporcionan una sobrecarga que
acepta una referencia cultural.
WARNING
Tenga en cuenta que los métodos String.ToUpper y String.ToLower no deben usarse para convertir cadenas para compararlas
ni para comprobar su igualdad. Para más información, vea la sección Comparar cadenas con mayúsculas y minúsculas
mezcladas.
ToUpper
El método String.ToUpper convierte todos los caracteres de una cadena a mayúsculas. En el siguiente ejemplo, se
convierte la cadena "Hello World!" de mayúsculas y minúsculas mezcladas a mayúsculas.
El ejemplo anterior tiene en cuenta la referencia cultural de forma predeterminada; aplica las convenciones de
mayúsculas y minúsculas de la referencia cultural actual. Para realizar un cambio de mayúsculas y minúsculas sin
tener en cuenta la referencia cultural o para aplicar las convenciones de mayúsculas y minúsculas de una referencia
cultural determinada, use la sobrecarga del método String.ToUpper(CultureInfo) y proporcione un valor
CultureInfo.InvariantCulture o un objeto System.Globalization.CultureInfo que representa la referencia cultural
especificada al parámetro culture. Para obtener un ejemplo que muestra cómo usar el método ToUpper para
realizar un cambio de mayúsculas y minúsculas sin tener en cuenta la referencia cultural, consulte Realizar cambios
de mayúsculas y minúsculas que no tienen en cuenta las referencias culturales.
ToLower
El método String.ToLower es similar al método anterior, pero en su lugar convierte todos los caracteres de una
cadena a minúsculas. En el siguiente ejemplo, se convierte la cadena "Hello World!" en minúsculas.
El ejemplo anterior tiene en cuenta la referencia cultural de forma predeterminada; aplica las convenciones de
mayúsculas y minúsculas de la referencia cultural actual. Para realizar un cambio de mayúsculas y minúsculas sin
tener en cuenta la referencia cultural o para aplicar las convenciones de mayúsculas y minúsculas de una referencia
cultural determinada, use la sobrecarga del método String.ToLower(CultureInfo) y proporcione un valor
CultureInfo.InvariantCulture o un objeto System.Globalization.CultureInfo que representa la referencia cultural
especificada al parámetro culture. Para obtener un ejemplo que muestra cómo usar el método
ToLower(CultureInfo) para realizar un cambio de mayúsculas y minúsculas sin tener en cuenta la referencia
cultural, consulte Realizar cambios de mayúsculas y minúsculas que no tienen en cuenta las referencias culturales.
ToTitleCase
El método TextInfo.ToTitleCase convierte el primer carácter de cada palabra a mayúsculas y el resto de los
caracteres a minúsculas. Sin embargo, se da por hecho que las palabras que están completamente en mayúsculas
son siglas y no se convierten.
El método TextInfo.ToTitleCase tiene en cuenta la referencia cultural; es decir, usa las convenciones de mayúsculas y
minúsculas de una referencia cultural determinada. Para llamar al método, recupere primero el objeto TextInfo que
representa las convenciones de mayúsculas y minúsculas de la referencia cultural determinada a partir de la
propiedad CultureInfo.TextInfo de una referencia cultural determinada.
En el ejemplo siguiente, se pasa cada cadena de una matriz al método TextInfo.ToTitleCase. Las cadenas incluyen
cadenas de título correctas así como acrónimos. Las cadenas se convierten a mayúsculas de tipo título usando las
convenciones de mayúsculas y minúsculas de la referencia cultural Inglés (Estados Unidos).
using System;
using System.Globalization;
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
Imports System.Globalization
Module Example
Public Sub Main()
Dim values() As String = { "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"}
Recuerde que, aunque tiene en cuenta la referencia cultural, el método TextInfo.ToTitleCase no proporciona reglas
de mayúsculas y minúsculas lingüísticamente correctas. En el ejemplo anterior, el método convierte "a tale of two
cities" en "A Tale Of Two Cities". Sin embargo, el uso lingüísticamente correcto de las mayúsculas y minúsculas de
título para la referencia cultural en-US es "A Tale of Two Cities".
Vea también
Operaciones básicas de cadenas
Realizar operaciones de cadenas que no distinguen entre referencias culturales
Utilizar la clase StringBuilder en .NET
04/11/2019 • 11 minutes to read • Edit Online
El objeto String es inmutable. Cada vez que se usa uno de los métodos de la clase System.String, se crea un objeto
de cadena en la memoria, lo que requiere una nueva asignación de espacio para ese objeto. En las situaciones en
las que es necesario realizar modificaciones repetidas en una cadena, la sobrecarga asociada a la creación de un
objeto String puede ser costosa. La clase System.Text.StringBuilder se puede usar para modificar una cadena sin
crear un objeto. Por ejemplo, el uso de la clase StringBuilder puede mejorar el rendimiento al concatenar muchas
cadenas en un bucle.
using System;
using System.Text;
Imports System.Text
Además, se puede usar la propiedad de lectura y escritura Capacity para establecer la longitud máxima del objeto.
En el ejemplo siguiente se usa la propiedad Capacity para definir la longitud máxima del objeto.
myStringBuilder->Capacity = 25;
myStringBuilder.Capacity = 25;
myStringBuilder.Capacity = 25
El método EnsureCapacity se puede usar para comprobar la capacidad del objeto StringBuilder actual. Si la
capacidad es mayor que el valor transmitido, no se realiza ningún cambio, pero si es menor que este, la capacidad
actual se cambia para que coincida con el valor en cuestión.
También se puede ver o establecer la propiedad Length. Si la propiedad Length se establece en un valor mayor
que el de la propiedad Capacity, la propiedad Capacity se cambia automáticamente al mismo valor de la
propiedad Length. Si la propiedad Length se establece en un valor menor que la longitud de la cadena de
StringBuilder actual, se acorta la cadena.
Anexar
El método Append se puede usar para agregar texto o la representación de cadena de un objeto al final de una
cadena representada por el objeto StringBuilder actual. En el ejemplo siguiente, se inicializa StringBuilder en
"Hello World" y, después, se anexa texto al final del objeto. El espacio se asigna automáticamente según sea
necesario.
AppendFormat
El método StringBuilder.AppendFormat agrega texto al final del objeto StringBuilder. Admite la característica de
formatos compuestos (para obtener más información, consulte Formatos compuestos) mediante la llamada a la
implementación de IFormattable del objeto u objetos a los que se va a dar formato. Por tanto, acepta las cadenas
de formato estándar para valores numéricos, de fecha y hora y de enumeración; las cadenas de formato
personalizado para valores numéricos y de fecha y hora; y las cadenas de formato definidas para los tipos
personalizados. (Para obtener información acerca del formato, consulte Aplicar formato a tipos.) Este método se
puede usar para personalizar el formato de las variables y anexar esos valores a StringBuilder. En el ejemplo
siguiente se usa el método AppendFormat para colocar un valor entero con formato de valor de divisa al final de
un objeto StringBuilder.
Insertar
El método Insert agrega una cadena o un objeto en una posición especificada del objeto StringBuilder actual. En el
ejemplo siguiente se usa este método para insertar una palabra en la sexta posición de un objeto StringBuilder.
Quitar
El método Remove se puede usar para quitar un número de caracteres especificado del objeto StringBuilder, a
partir de un índice de base cero definido. En el ejemplo siguiente se usa el método Remove para acortar un objeto
StringBuilder.
Sustituya
El método Replace se puede usar para reemplazar caracteres del objeto StringBuilder por otro carácter
especificado. En el ejemplo siguiente se usa el método Replace para buscar todas las instancias del carácter de
signo de exclamación (!) y reemplazarlas por el carácter de signo de interrogación (?) en un objeto StringBuilder.
using System;
using System.Text;
Module Example
Public Sub Main()
Dim sb As New StringBuilder()
Dim flag As Boolean = True
Dim spellings() As String = { "recieve", "receeve", "receive" }
sb.AppendFormat("Which of the following spellings is {0}:", flag)
sb.AppendLine()
For ctr As Integer = 0 To spellings.GetUpperBound(0)
sb.AppendFormat(" {0}. {1}", ctr, spellings(ctr))
sb.AppendLine()
Next
sb.AppendLine()
Console.WriteLine(sb.ToString())
End Sub
End Module
' The example displays the following output:
' Which of the following spellings is True:
' 0. recieve
' 1. receeve
' 2. receive
Vea también
System.Text.StringBuilder
Operaciones básicas de cadenas
Aplicación de formato a tipos
Procedimiento para realizar manipulaciones de
cadena básicas en .NET
13/01/2020 • 5 minutes to read • Edit Online
En el ejemplo siguiente, se usan algunos de los métodos descritos en los temas de Operaciones básicas de cadenas
para construir una clase que realice manipulaciones de cadena de una manera que podría encontrarse en una
aplicación real. La clase MailToData almacena el nombre y dirección de los individuos en propiedades distintas y
proporciona una forma de combinar los campos City , State y Zip en una única cadena para mostrar al usuario.
Además, la clase permite al usuario que escriba la información sobre la ciudad, estado y código postal como una
sola cadena; de forma automática, la aplicación analiza la cadena única y escribe la información adecuada en la
propiedad correspondiente.
Para simplificar, en este ejemplo se usa una aplicación de consola con una interfaz de línea de comandos.
Ejemplo
using System;
class MainClass
{
static void Main()
{
MailToData MyData = new MailToData();
if (MyData.Validated) {
Console.WriteLine("Name: {0}", MyData.Name);
Console.WriteLine("Address: {0}", MyData.Address);
Console.WriteLine("City: {0}", MyData.City);
Console.WriteLine("State: {0}", MyData.State);
Console.WriteLine("Zip: {0}", MyData.Zip);
// Throw a FormatException if the user did not enter the necessary spaces
// between elements.
try
{
// City may consist of multiple words, so we'll have to parse the
// string from right to left starting with the zip code.
int zipIndex = citystatezip.LastIndexOf(" ");
if (zipIndex == -1) {
msg = "\nCannot identify a zip code." + msgEnd;
throw new FormatException(msg);
}
zip = citystatezip.Substring(zipIndex + 1);
// Put the value of city, state, and zip together in the proper manner.
string MyCityStateZip = String.Concat(city, ", ", state, " ", zip);
return MyCityStateZip;
}
}
Class MainClass
Public Shared Sub Main()
Dim MyData As New MailToData()
If MyData.Validated Then
Console.WriteLine("Name: {0}", MyData.Name)
Console.WriteLine("Address: {0}", MyData.Address)
Console.WriteLine("City: {0}", MyData.City)
Console.WriteLine("State: {0}", MyData.State)
Console.WriteLine("ZIP Code: {0}", MyData.Zip)
' Throw a FormatException if the user did not enter the necessary spaces
' between elements.
Try
' City may consist of multiple words, so we'll have to parse the
' string from right to left starting with the zip code.
Dim zipIndex As Integer = strCityStateZip.LastIndexOf(" ")
If zipIndex = -1 Then
msg = vbCrLf + "Cannot identify a zip code." + msgEnd
msg = vbCrLf + "Cannot identify a zip code." + msgEnd
Throw New FormatException(msg)
End If
strZip = strCityStateZip.Substring(zipIndex + 1)
Cuando se ejecuta el código anterior, se le pide al usuario que escriba su nombre y dirección. La aplicación coloca
la información en las propiedades adecuadas y muestra la información al usuario, creando una única cadena que
muestra la información sobre la ciudad, el estado y el código postal.
Vea también
Operaciones básicas de cadenas
Expresiones regulares de .NET
04/11/2019 • 16 minutes to read • Edit Online
Las expresiones regulares proporcionan un método eficaz y flexible para procesar texto. La notación extensiva de
búsqueda de patrones coincidentes de las expresiones regulares permite analizar rápidamente grandes
cantidades de texto para buscar patrones de caracteres específicos; para validar un texto con el fin de asegurar
que se corresponde con un patrón predefinido (por ejemplo, una dirección de correo electrónico); para extraer,
editar, reemplazar o eliminar subcadenas de texto; y para agregar las cadenas extraídas a una colección con el fin
de generar un informe. Para muchas aplicaciones que usan cadenas o analizan grandes bloques de texto, las
expresiones regulares son una herramienta indispensable.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "(Mr\.? |Mrs\.? |Miss |Ms\.? )"
Dim names() As String = { "Mr. Henry Hunt", "Ms. Sara Samuels", _
"Abraham Adams", "Ms. Nicole Norris" }
For Each name As String In names
Console.WriteLine(Regex.Replace(name, pattern, String.Empty))
Next
End Sub
End Module
' The example displays the following output:
' Henry Hunt
' Sara Samuels
' Abraham Adams
' Nicole Norris
El patrón de expresión regular (Mr\.? |Mrs\.? |Miss |Ms\.? ) busca coincidencias con cualquier aparición de
"Mr ", "Mr. ", "Mrs ", "Mrs. ", "Miss ", "Ms " o "Ms. ". La llamada al método Regex.Replace reemplaza la cadena
coincidente con String.Empty; es decir, la quita de la cadena original.
Ejemplo 2: Identificación de palabras duplicadas
Duplicar palabras accidentalmente es un error frecuente que cometen los escritores. Se puede usar una
expresión regular para identificar palabras duplicadas, como se muestra en el ejemplo siguiente.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module modMain
Public Sub Main()
Dim pattern As String = "\b(\w+?)\s\1\b"
Dim input As String = "This this is a nice day. What about this? This tastes good. I saw a a dog."
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
Console.WriteLine("{0} (duplicates '{1}') at position {2}", _
match.Value, match.Groups(1).Value, match.Index)
Next
End Sub
End Module
' The example displays the following output:
' This this (duplicates 'This') at position 0
' a a (duplicates 'a') at position 66
' Get numeric string, convert it to a value, and add it to List object.
Dim expenses As New List(Of Decimal)
En un equipo cuya referencia cultural actual sea Inglés - Estados Unidos (en-US ), el ejemplo crea dinámicamente
la expresión regular \$\s*[-+]?([0-9]{0,3}(,[0-9]{3})*(\.[0-9]+)?) . Este patrón de expresión regular se puede
interpretar de la manera siguiente:
\$ Busque una sola aparición del símbolo de dólar ( $ ) en la
cadena de entrada. La cadena del patrón de expresión regular
incluye una barra diagonal inversa para indicar que el símbolo
de dólar debe interpretarse literalmente en lugar de
interpretarse como un delimitador de la expresión regular. (Si
solo apareciese el símbolo $ , esto indicaría que el motor de
expresión regular debe intentar comenzar su búsqueda de
coincidencias al final de una cadena). Para asegurarse de que
el símbolo de divisa de la referencia cultural actual no se
interprete erróneamente como un símbolo de expresión
regular, en el ejemplo se llama al método Regex.Escape como
escape de caracteres.
Si se encuentra cada uno de estos subpatrones en la cadena de entrada, la búsqueda de coincidencias se realiza
correctamente y se agrega al objeto Match un objeto MatchCollection que contiene información sobre la
coincidencia.
Temas relacionados
TITLE DESCRIPCIÓN
Lenguaje de expresiones regulares: referencia rápida Ofrece información sobre el conjunto de caracteres,
operadores y construcciones que se pueden utilizar para
definir expresiones regulares.
Modelo de objetos de expresión regular Proporciona información y ejemplos de código que muestran
cómo usar las clases de expresiones regulares.
TITLE DESCRIPCIÓN
Detalles del comportamiento de expresiones regulares Proporciona información sobre las funcionalidades y el
comportamiento de las expresiones regulares de .NET.
Ejemplos de expresiones regulares Proporciona ejemplos de código que muestran los usos
habituales de las expresiones regulares.
Referencia
System.Text.RegularExpressions
System.Text.RegularExpressions.Regex
Expresiones regulares: referencia rápida (descarga en formato Word)
Expresiones regulares: referencia rápida (descarga en formato PDF )
Lenguaje de expresiones regulares - Referencia
rápida
25/11/2019 • 22 minutes to read • Edit Online
Una expresión regular es un modelo con el que el motor de expresiones regulares intenta buscar una
coincidencia en el texto de entrada. Un modelo consta de uno o más literales de carácter, operadores o
estructuras. Para obtener una breve introducción, consulte Expresiones regulares de .NET.
Cada sección de esta referencia rápida enumera una categoría determinada de caracteres, operadores y
construcciones que puede usar para definir expresiones regulares.
Esta información también se proporciona en dos formatos que se pueden descargar e imprimir para facilitar su
consulta:
Descargar en formato Word (.docx)
Descarga en formato PDF (.pdf)
Escapes de carácter
El carácter de barra diagonal inversa (\) en una expresión regular indica que el carácter que le sigue es un
carácter especial (como se muestra en la tabla siguiente) o que se debe interpretar literalmente. Para más
información, consulte Escapes de carácter.
Clases de caracteres
Una clase de caracteres coincide con cualquiera de un juego de caracteres. Las clases de caracteres incluyen los
elementos del lenguaje enumerados en la tabla siguiente. Para más información, consulte Clases de caracteres.
Delimitadores
Los delimitadores, o aserciones atómicas de ancho cero, hacen que una coincidencia tenga éxito o no
dependiendo de la posición actual en la cadena, pero no hacen que el motor avance por la cadena ni consuma
caracteres. Los metacaracteres enumerados en la tabla siguiente son delimitadores. Para obtener más
información, consulte Delimitadores.
Construcciones de agrupamiento
Las construcciones de agrupamiento definen subexpresiones de una expresión regular y, normalmente,
capturan subcadenas de una cadena de entrada. Las construcciones de agrupamiento incluyen los elementos
del lenguaje enumerados en la tabla siguiente. Para obtener más información, consulte Construcciones de
agrupamiento.
CONSTRUCCIÓN DE
AGRUPAMIENTO DESCRIPCIÓN MODELO COINCIDENCIAS
"Write" en
"Console.Write(value)"
Cuantificadores
Un cuantificador especifica cuántas instancias del elemento anterior (que puede ser un carácter, un grupo o una
clase de caracteres) debe haber en la cadena de entrada para que se encuentre una coincidencia. Los
cuantificadores incluyen los elementos del lenguaje enumerados en la tabla siguiente. Para obtener más
información, consulte Cuantificadores.
CONSTRUCCIÓN DE
REFERENCIAS INVERSAS DESCRIPCIÓN MODELO COINCIDENCIAS
Construcciones de alternancia
Las estructuras de alternancia modifican una expresión regular para habilitar o no la coincidencia. Estas
construcciones incluyen los elementos del lenguaje enumerados en la tabla siguiente. Para obtener más
información, consulte Construcciones de alternancia.
CONSTRUCCIONES DE
ALTERNANCIA DESCRIPCIÓN MODELO COINCIDENCIAS
Sustituciones
Las sustituciones son elementos del lenguaje de expresiones regulares que se admiten en modelos de
reemplazo. Para obtener más información, consulte Substituciones. Los metacaracteres enumerados en la tabla
siguiente son aserciones atómicas de ancho cero.
Construcciones misceláneas
Las estructuras misceláneas modifican un modelo de expresión regular o proporcionan información sobre él. En
la tabla siguiente se enumeran las construcciones misceláneas admitidas por .NET. Para obtener más
información, consulte Construcciones misceláneas.
Vea también
System.Text.RegularExpressions
System.Text.RegularExpressions.Regex
Expresiones regulares
Clases de expresiones regulares
Ejemplos de expresiones regulares
Expresiones regulares: referencia rápida (descarga en formato Word)
Expresiones regulares: referencia rápida (descarga en formato PDF )
Escapes de carácter en expresiones regulares
20/01/2020 • 8 minutes to read • Edit Online
La barra diagonal inversa (\) en una expresión regular indica una de las siguientes situaciones:
El carácter que va detrás de ella es un carácter especial, como se muestra en la tabla de la sección siguiente.
Por ejemplo, \b es un delimitador que indica que una coincidencia de expresión regular debería comenzar
en un límite de palabras, \t representa un carácter de tabulación y \x020 representa un espacio.
Un carácter que de otro modo se interpretaría como una construcción de lenguaje sin escape, se debe
interpretar literalmente. Por ejemplo, una llave ( { ) inicia la definición de un cuantificador, pero una barra
diagonal inversa seguida de una llave ( \{ ) indica que el motor de expresiones regulares debería coincidir
con la llave. De igual forma, una sola barra diagonal inversa marca el principio de una construcción de
lenguaje con escape, pero dos barras diagonales inversas ( \\ ) indican que el motor de expresiones
regulares debería coincidir con la barra diagonal inversa.
NOTE
Los escapes de caracteres se reconocen en los patrones de expresiones regulares, pero no en los patrones de reemplazo.
Todos los caracteres excepto los siguientes: Los caracteres que no aparecen en la columna Carácter o
secuencia no tienen ningún significado especial en las
.$^{[(|)*+?\ expresiones regulares, sino que equivalen a sí mismos.
Un ejemplo
En el ejemplo siguiente se muestra el uso de escapes de carácter en una expresión regular. Analiza una cadena que
contiene los nombres de las ciudades más grandes del mundo y sus poblaciones en 2009. Cada nombre de ciudad
se separa de su población por un carácter de tabulación ( \t ) o una barra vertical (| o \u007c ). Cada ciudad y su
población está separada de la siguiente por un retorno de carro y un avance de línea.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim delimited As String = "\G(.+)[\t\u007c](.+)\r?\n"
Dim input As String = "Mumbai, India|13,922,125" + vbCrLf + _
"Shanghai, China" + vbTab + "13,831,900" + vbCrLf + _
"Karachi, Pakistan|12,991,000" + vbCrLf + _
"Delhi, India" + vbTab + "12,259,230" + vbCrLf + _
"Istanbul, Turkey|11,372,613" + vbCrLf
Console.WriteLine("Population of the World's Largest Cities, 2009")
Console.WriteLine()
Console.WriteLine("{0,-20} {1,10}", "City", "Population")
Console.WriteLine()
For Each match As Match In Regex.Matches(input, delimited)
Console.WriteLine("{0,-20} {1,10}", match.Groups(1).Value, _
match.Groups(2).Value)
Next
End Sub
End Module
' The example displays the following output:
' Population of the World's Largest Cities, 2009
'
' City Population
'
' Mumbai, India 13,922,125
' Shanghai, China 13,831,900
' Karachi, Pakistan 12,991,000
' Delhi, India 12,259,230
' Istanbul, Turkey 11,372,613
Vea también
Lenguaje de expresiones regulares: referencia rápida
Clases de caracteres en expresiones regulares
11/02/2020 • 58 minutes to read • Edit Online
Una clase de caracteres define un conjunto de caracteres, cualquiera de los cuales puede estar en una cadena de
entrada para que se produzca una coincidencia. El lenguaje de expresiones regulares de .NET admite las
siguientes clases de caracteres:
Grupos de caracteres positivos. Un carácter de la cadena de entrada debe coincidir con uno de los
caracteres del conjunto especificado. Para obtener más información, consulte Grupo de caracteres
positivos.
Grupos de caracteres negativos. Ningún carácter de la cadena de entrada debe coincidir con ninguno de
los caracteres del conjunto especificado. Para obtener más información, consulte Grupo de caracteres
negativos.
Cualquier carácter. El carácter . (punto) en una expresión regular es un carácter comodín que coincide
con cualquier carácter excepto con \n . Para obtener más información, consulte Cualquier carácter.
Una categoría general o un bloque con nombre Unicode. Para que se produzca una coincidencia, un
carácter de la cadena de entrada debe ser miembro de una categoría Unicode determinada o debe estar
dentro de un intervalo contiguo de caracteres Unicode. Para obtener más información, consulte Categoría
Unicode o bloque Unicode.
Un bloque con nombre o una categoría general negativa Unicode. Para que se produzca una coincidencia,
un carácter de la cadena de entrada no debe ser miembro de una categoría Unicode determinada o no
debe estar dentro de un intervalo contiguo de caracteres Unicode. Para obtener más información,
consulte Categoría Unicode o bloque Unicode negativo.
Un carácter de palabra. Un carácter de la cadena de entrada puede pertenecer a cualquiera de las
categorías Unicode que son adecuadas para los caracteres que se usan para formar palabras. Para
obtener más información, consulte Carácter de palabra.
Un carácter que no se usa en las palabras. Un carácter de la cadena de entrada puede pertenecer a
cualquier categoría Unicode que no se usa para formar palabras. Para obtener más información, consulte
Carácter que no se usa en las palabras.
Un carácter de espacio en blanco. Un carácter de la cadena de entrada puede ser cualquiera de los
caracteres separadores Unicode, así como cualquiera de los caracteres de una serie de caracteres de
control. Para obtener más información, consulte Carácter de espacio en blanco.
Un carácter que no sea un espacio en blanco. Un carácter de la cadena de entrada puede ser cualquier
carácter que no sea un espacio en blanco. Para obtener más información, consulte Carácter que no sea un
espacio en blanco.
Un dígito decimal. Un carácter de la cadena de entrada puede ser cualquiera de los caracteres clasificados
como dígitos decimales de Unicode. Para obtener más información, consulte Carácter de dígito decimal.
Un carácter que no sea un dígito decimal. Un carácter de la cadena de entrada puede ser cualquier
carácter que no sea un dígito decimal de Unicode. Para obtener más información, consulte Carácter de
dígito decimal.
.NET admite expresiones de sustracción de clases de caracteres, que permiten definir un conjunto de caracteres
como el resultado de excluir una clase de caracteres de otra clase de caracteres. Para obtener más información,
consulte Sustracción de clases de caracteres.
NOTE
Las clases que coinciden con los caracteres por categoría, como \w para que coincidan con caracteres alfabéticos o \p{} para
que coincidan con una categoría Unicode, que se basan en la clase CharUnicodeInfo para proporcionar información sobre
las categorías de caracteres. A partir de .NET Framework 4.6.2, las categorías de caracteres se basan en el estándar Unicode,
versión 8.0.0. Desde .NET Framework 4 hasta .NET Framework 4.6.1, se basan en el estándar Unicode, versión 6.3.0.
donde grupo_caracteres es una lista de cada uno de los caracteres que pueden aparecer en la cadena de entrada
para que se produzca una coincidencia. grupo_caracteres puede estar formado por cualquier combinación de
uno o varios caracteres literales, caracteres de escape o clases de caracteres.
La sintaxis para especificar un intervalo de caracteres es la siguiente:
[firstCharacter-lastCharacter]
donde firstCharacter es el carácter que comienza el intervalo y lastCharacter es el carácter final del intervalo. Un
intervalo de caracteres es una serie contigua de caracteres que se define especificando el primer carácter de la
serie, un guion (-) y, a continuación, el último carácter de la serie. Dos caracteres son contiguos si tienen puntos
de código Unicode adyacentes. firstCharacter debe ser el carácter con el punto de código inferior y lastCharacter
debe ser el carácter con el punto de código superior.
NOTE
Dado que un grupo de caracteres positivos puede incluir un conjunto de caracteres y un rango de caracteres, un carácter
de guión ( - ) siempre se interpreta como el separador de rango, a menos que sea el primer carácter del grupo o el último.
En la tabla siguiente se recogen algunos de los patrones de expresiones regulares comunes que contienen clases
de caracteres positivos.
MODELO DESCRIPCIÓN
En el ejemplo siguiente se define un grupo de caracteres positivos que contiene los caracteres "a" y "e" de
manera que la cadena de entrada deba contener las palabras "grey" o "gray" seguidas de cualquier otra palabra
para que se produzca una coincidencia.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "gr[ae]y\s\S+?[\s\p{P}]"
Dim input As String = "The gray wolf jumped over the grey wall."
Dim matches As MatchCollection = Regex.Matches(input, pattern)
For Each match As Match In matches
Console.WriteLine($"'{match.Value}'")
Next
End Sub
End Module
' The example displays the following output:
' 'gray wolf '
' 'grey wall.'
MODELO DESCRIPCIÓN
En el ejemplo siguiente se buscan palabras que comienzan por cualquier letra mayúscula. Utiliza la subexpresión
[A-Z] para representar el intervalo de letras mayúsculas de la A a la Z.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b[A-Z]\w*\b"
Dim input As String = "A city Albany Zulu maritime Marseilles"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(match.Value)
Next
End Sub
End Module
MODELO DESCRIPCIÓN
donde grupo_caracteres es una lista de cada uno de los caracteres que no pueden aparecer en la cadena de
entrada para que se produzca una coincidencia. grupo_caracteres puede estar formado por cualquier
combinación de uno o varios caracteres literales, caracteres de escape o clases de caracteres.
La sintaxis para especificar un intervalo de caracteres es la siguiente:
[^*firstCharacter*-*lastCharacter*]
donde firstCharacter es el carácter que comienza el intervalo y lastCharacter es el carácter final del intervalo. Un
intervalo de caracteres es una serie contigua de caracteres que se define especificando el primer carácter de la
serie, un guion (-) y, a continuación, el último carácter de la serie. Dos caracteres son contiguos si tienen puntos
de código Unicode adyacentes. firstCharacter debe ser el carácter con el punto de código inferior y lastCharacter
debe ser el carácter con el punto de código superior.
NOTE
Dado que un grupo de caracteres negativos puede incluir un conjunto de caracteres y un rango de caracteres, un carácter
de guión ( - ) siempre se interpreta como el separador de rango, a menos que sea el primer carácter del grupo o el último.
Es posible concatenar dos o más intervalos de caracteres. Por ejemplo, para especificar el intervalo de dígitos
decimales del "0" al "9", el intervalo de letras minúsculas de la "a" a la "f" y el intervalo de letras mayúsculas de la
"A" a la "F", utilice [0-9a-fA-F] .
El carácter inicial de acento circunflejo ( ^ ) de un grupo de caracteres negativos es obligatorio e indica que el
grupo de caracteres es un grupo de caracteres negativos en lugar de un grupo de caracteres positivos.
IMPORTANT
Un grupo de caracteres negativos dentro de un patrón de expresión regular más grande no es una aserción de ancho cero.
Es decir, después de evaluar el grupo de caracteres negativos, el motor de expresiones regulares avanza un carácter en la
cadena de entrada.
En la tabla siguiente se recogen algunos de los patrones de expresiones regulares comunes que contienen
grupos de caracteres negativos.
MODELO DESCRIPCIÓN
En el ejemplo siguiente se busca cualquier palabra que comience por los caracteres "th" y no vaya seguida de
una "o".
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\bth[^o]\w+\b"
Dim input As String = "thought thing though them through thus " + _
"thorough this"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(match.Value)
Next
End Sub
End Module
' The example displays the following output:
' thing
' them
' through
' thus
' this
MODELO DESCRIPCIÓN
Cualquier carácter: .
El carácter de punto (.) coincide con cualquier carácter excepto con \n (carácter de nueva línea, \u000A), con los
dos requisitos siguientes:
Si la opción RegexOptions.Singleline modifica un patrón de expresión regular o si la opción . modifica
la parte del patrón que contiene la clase de caracteres s , . coincide con cualquier carácter. Para obtener
más información, consulte Opciones de expresiones regulares.
El ejemplo siguiente muestra el comportamiento predeterminado de la clase de caracteres . y con la
opción RegexOptions.Singleline. La expresión regular ^.+ comienza en el principio de la cadena y
coincide con todos los caracteres. De forma predeterminada, la coincidencia termina al final de la primera
línea; el patrón de la expresión regular coincide con el carácter de retorno de carro, \r o \u000D, pero no
coincide con \n . Dado que la opción RegexOptions.Singleline interpreta la cadena de entrada completa
como una sola línea, coincide con cada carácter de la cadena de entrada, incluido \n .
using System;
using System.Text.RegularExpressions;
Console.WriteLine();
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.Singleline))
Console.WriteLine(Regex.Escape(match.Value));
}
}
// The example displays the following output:
// This\ is\ one\ line\ and\r
//
// This\ is\ one\ line\ and\r\nthis\ is\ the\ second\.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "^.+"
Dim input As String = "This is one line and" + vbCrLf + "this is the second."
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(Regex.Escape(match.Value))
Next
Console.WriteLine()
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.SingleLine)
Console.WriteLine(Regex.Escape(match.Value))
Next
End Sub
End Module
' The example displays the following output:
' This\ is\ one\ line\ and\r
'
' This\ is\ one\ line\ and\r\nthis\ is\ the\ second\.
NOTE
Dado que coincide con cualquier carácter excepto con \n , la clase de caracteres . también coincide con \r (el carácter
de retorno de carro, \u000D).
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As STring = "\b.*[.?!;:](\s|\z)"
Dim input As String = "this. what: is? go, thing."
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(match.Value)
Next
End Sub
End Module
' The example displays the following output:
' this. what: is? go, thing.
NOTE
Dado que coincide con cualquier carácter, el elemento del lenguaje . se utiliza a menudo con un cuantificador no
expansivo si un patrón de expresión regular intenta coincidir varias veces con cualquier carácter. Para obtener más
información, consulte Cuantificadores.
coincide con cualquier carácter que pertenezca a una categoría general o bloque con nombre de Unicode, donde
nombre es la abreviatura de la categoría o el nombre del bloque con nombre. Para obtener una lista de
abreviaturas de categorías, consulte la sección Categorías generales Unicode compatibles más adelante en este
tema. Para obtener una lista de bloques con nombre, consulte la sección Bloques con nombre compatibles más
adelante en este tema.
En el ejemplo siguiente se usa la construcción \p{ nombre } para buscar coincidencias con una categoría
general de Unicode (en este caso, Pd o Punctuation, Dash) y un bloque con nombre (los bloques con nombre
IsGreek e IsBasicLatin ).
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b(\p{IsGreek}+(\s)?)+\p{Pd}\s(\p{IsBasicLatin}+(\s)?)+"
Dim input As String = "Κατα Μαθθαίον - The Gospel of Matthew"
MODELO DESCRIPCIÓN
coincide con cualquier carácter que no pertenezca a una categoría general o bloque con nombre de Unicode,
donde nombre es la abreviatura de la categoría o el nombre del bloque con nombre. Para obtener una lista de
abreviaturas de categorías, consulte la sección Categorías generales Unicode compatibles más adelante en este
tema. Para obtener una lista de bloques con nombre, consulte la sección Bloques con nombre compatibles más
adelante en este tema.
En el siguiente ejemplo se usa la construcción \P{ nombre } para quitar cualquier símbolo de divisa (en este
caso, la categoría Sc , o Symbol, Currency) de las cadenas numéricas.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim pattern As String = "(\P{Sc})+"
El patrón de expresión regular (\P{Sc})+ coincide con uno o varios caracteres que no son símbolos de divisa;
quita eficazmente cualquier símbolo de divisa de la cadena de resultado.
Carácter de palabra: \w
\w coincide con cualquier carácter de palabra. Un carácter de palabra es un miembro de alguna de las
categorías Unicode enumeradas en la tabla siguiente.
CATEGORÍA DESCRIPCIÓN
Ll Letra, minúscula
Lu Letra, mayúscula
Lo Letra, otra
Lm Letra, modificador
NOTE
Dado que coincide con cualquier carácter de palabra, el elemento del lenguaje \w se suele usar con un cuantificador
diferido si un patrón de expresión regular intenta coincidir varias veces con cualquier carácter de palabra, seguido de un
carácter de palabra específico. Para obtener más información, consulte Cuantificadores.
En el ejemplo siguiente se usa el elemento del lenguaje \w para buscar coincidencias de caracteres duplicados
en una palabra. El ejemplo define un patrón de expresión regular, (\w)\1 , que se puede interpretar de la
siguiente manera.
ELEMENTO DESCRIPCIÓN
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim pattern As String = "(\w)\1"
Dim words() As String = { "trellis", "seer", "latter", "summer", _
"hoarse", "lesser", "aardvark", "stunned" }
For Each word As String In words
Dim match As Match = Regex.Match(word, pattern)
If match.Success Then
Console.WriteLine("'{0}' found in '{1}' at position {2}.", _
match.Value, word, match.Index)
Else
Console.WriteLine("No double characters in '{0}'.", word)
End If
Next
End Sub
End Module
' The example displays the following output:
' 'll' found in 'trellis' at position 3.
' 'ee' found in 'seer' at position 1.
' 'tt' found in 'latter' at position 2.
' 'mm' found in 'summer' at position 2.
' No double characters in 'hoarse'.
' 'ss' found in 'lesser' at position 2.
' 'aa' found in 'aardvark' at position 0.
' 'nn' found in 'stunned' at position 3.
En otras palabras, coincide con cualquier carácter excepto con los que figuran en las categorías Unicode de la
tabla siguiente.
CATEGORÍA DESCRIPCIÓN
Ll Letra, minúscula
Lu Letra, mayúscula
Lo Letra, otra
Lm Letra, modificador
NOTE
Dado que coincide con cualquier carácter que no sea de palabra, el elemento del lenguaje \W se suele usar con un
cuantificador diferido si un patrón de expresión regular intenta coincidir varias veces con cualquier carácter que no sea de
palabra, seguido de un carácter que no sea de palabra específico. Para obtener más información, consulte Cuantificadores.
ELEMENTO DESCRIPCIÓN
(\W){1,2} Coincide una o dos veces con un carácter que no se usa para
formar palabras. Este es el segundo grupo de captura.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim pattern As String = "\b(\w+)(\W){1,2}"
Dim input As String = "The old, grey mare slowly walked across the narrow, green pasture."
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(match.Value)
Console.Write(" Non-word character(s):")
Dim captures As CaptureCollection = match.Groups(2).Captures
For ctr As Integer = 0 To captures.Count - 1
Console.Write("'{0}' (\u{1}){2}", captures(ctr).Value, _
Convert.ToUInt16(captures(ctr).Value.Chars(0)).ToString("X4"), _
If(ctr < captures.Count - 1, ", ", ""))
Next
Console.WriteLine()
Next
End Sub
End Module
' The example displays the following output:
' The
' Non-word character(s):' ' (\u0020)
' old,
' Non-word character(s):',' (\u002C), ' ' (\u0020)
' grey
' Non-word character(s):' ' (\u0020)
' mare
' Non-word character(s):' ' (\u0020)
' slowly
' Non-word character(s):' ' (\u0020)
' walked
' Non-word character(s):' ' (\u0020)
' across
' Non-word character(s):' ' (\u0020)
' the
' Non-word character(s):' ' (\u0020)
' narrow,
' Non-word character(s):',' (\u002C), ' ' (\u0020)
' green
' Non-word character(s):' ' (\u0020)
' pasture.
' Non-word character(s):'.' (\u002E)
Dado que el objeto Group del segundo grupo de captura contiene solo un carácter que no se usa para formar
palabras, el ejemplo recupera todos los caracteres que no se usan para formar palabras capturados del objeto
CaptureCollection que devuelve la propiedad Group.Captures.
CATEGORÍA DESCRIPCIÓN
ELEMENTO DESCRIPCIÓN
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim pattern As String = "\b\w+(e)?s(\s|$)"
Dim input As String = "matches stores stops leave leaves"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(match.Value)
Next
End Sub
End Module
' The example displays the following output:
' matches
' stores
' stops
' leaves
ELEMENTO DESCRIPCIÓN
Module Example
Public Sub Main()
Dim pattern As String = "\b(\S+)\s?"
Dim input As String = "This is the first sentence of the first paragraph. " + _
"This is the second sentence." + vbCrLf + _
"This is the only sentence of the second paragraph."
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(match.Groups(1))
Next
End Sub
End Module
' The example displays the following output:
' This
' is
' the
' first
' sentence
' of
' the
' first
' paragraph.
' This
' is
' the
' second
' sentence.
' This
' is
' the
' only
' sentence
' of
' the
' second
' paragraph.
ELEMENTO DESCRIPCIÓN
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim pattern As String = "^(\(?\d{3}\)?[\s-])?\d{3}-\d{4}$"
Dim inputs() As String = { "111 111-1111", "222-2222", "222 333-444", _
"(212) 111-1111", "111-AB1-1111", _
"212-111-1111", "01 999-9999" }
ELEMENTO DESCRIPCIÓN
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "^\D\d{1,5}\D*$"
Dim inputs() As String = { "A1039C", "AA0001", "C18A", "Y938518" }
CATEGORÍA DESCRIPCIÓN
Lu Letra, mayúscula
Ll Letra, minúscula
Lm Letra, modificador
CATEGORÍA DESCRIPCIÓN
Lo Letra, otra
Me Marca, inclusión
Nl Número, letra
No Número, otro
Pc Puntuación, conector
Pd Puntuación, raya
Ps Puntuación, abrir
Pe Puntuación, cerrar
Po Puntuación, otro
Sm Símbolo, matemático
Sc Símbolo, divisa
Sk Símbolo, modificador
So Símbolo, otro
CATEGORÍA DESCRIPCIÓN
Zs Separador, espacio
Zl Separador, línea
Zp Separador, párrafo
Cc Otro, control
Cf Otro, formato
Cs Otro, suplente
Puede determinar la categoría Unicode de cualquier carácter concreto pasando dicho carácter al método
GetUnicodeCategory. En el ejemplo siguiente se utiliza el método GetUnicodeCategory para determinar la
categoría de cada elemento de una matriz que contiene determinados caracteres latinos.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim chars() As Char = { "a"c, "X"c, "8"c, ","c, " "c, ChrW(9), "!"c }
o bien
IsGreekandCoptic
o bien
IsCombiningMarksforSymbols
Elija las clases de caracteres para que una expresión de sustracción de clases de caracteres produzca resultados
satisfactorios. Evite el uso de expresiones que produzcan un conjunto vacío de caracteres, que no coincidan con
nada, o expresiones equivalentes al grupo base original. Por ejemplo, el conjunto vacío es el resultado de la
expresión [\p{IsBasicLatin}-[\x00-\x7F]] , que resta todos los caracteres del intervalo de caracteres
IsBasicLatin de la categoría general IsBasicLatin . Ocurre lo mismo con el grupo base original, que es el
resultado de la expresión [a-z-[0-9]] . Esto se debe a que el grupo base, que está formado por el intervalo de
caracteres comprendido entre las letras de la "a" a la "z", no contiene ningún carácter del grupo excluido, que es
el intervalo de caracteres formado por los dígitos decimales del "0" al "9".
En el ejemplo siguiente se define una expresión regular, ^[0-9-[2468]]+$ , que coincide con cero y con los dígitos
impares de una cadena de entrada. La expresión regular se interpreta como se muestra en la tabla siguiente.
ELEMENTO DESCRIPCIÓN
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim inputs() As String = { "123", "13579753", "3557798", "335599901" }
Dim pattern As String = "^[0-9-[2468]]+$"
Vea también
GetUnicodeCategory
Lenguaje de expresiones regulares: referencia rápida
Opciones de expresiones regulares
Delimitadores en expresiones regulares
13/01/2020 • 30 minutes to read • Edit Online
Los delimitadores, o aserciones atómicas de ancho cero, especifican la posición de la cadena en que se debe
producir una coincidencia. Cuando se usa un delimitador en una expresión de búsqueda, el motor de expresiones
regulares no avanza por la cadena o ni consume caracteres, sino que solo busca una coincidencia en la posición
especificada. Por ejemplo, ^ especifica que la coincidencia debe empezar al principio de una cadena o línea. Por
consiguiente, la expresión regular ^http: coincide con "http": solo cuando se encuentra al principio de una línea.
En la tabla siguiente, se enumeran los delimitadores que admiten las expresiones regulares de .NET.
DELIMITADOR DESCRIPCIÓN
using System;
using System.Text.RegularExpressions;
Console.WriteLine(".");
match = match.NextMatch();
}
Console.WriteLine();
Console.WriteLine(".");
match = match.NextMatch();
}
Console.WriteLine();
}
}
// The example displays the following output:
// The Brooklyn Dodgers played in the National League in 1911, 1912, 1932-1957.
//
// The Brooklyn Dodgers played in the National League in 1911, 1912, 1932-1957.
// The Chicago Cubs played in the National League in 1903-present.
// The Detroit Tigers played in the American League in 1901-present.
// The New York Giants played in the National League in 1885-1957.
// The Washington Senators played in the American League in 1901-1960.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "Brooklyn Dodgers, National League, 1911, 1912, 1932-1957" + vbCrLf +
"Chicago Cubs, National League, 1903-present" + vbCrLf +
"Detroit Tigers, American League, 1901-present" + vbCrLf +
"New York Giants, National League, 1885-1957" + vbCrLf +
"Washington Senators, American League, 1901-1960" + vbCrLf
MODELO DESCRIPCIÓN
((\w+(\s?)){2,} Coincide con uno o varios caracteres que se usan para formar
palabras seguidos de cero o un espacio, al menos dos veces.
Este es el primer grupo de captura. Esta expresión también
define un segundo y tercer grupo de captura: El segundo
grupo está compuesto por la palabra capturada y el tercero
consta de los espacios en blanco capturados.
MODELO DESCRIPCIÓN
(\w+\s\w+) Coincide con uno o varios caracteres que se usan para formar
palabras seguidos de un espacio, seguidos de uno o varios
caracteres que se usan para formar palabras. Este es el cuarto
grupo de captura.
Si usa $ con la opción RegexOptions.Multiline , la coincidencia también se puede producir al final de una línea.
Observe que $ coincide con \n , pero no coincide con \r\n (la combinación de caracteres de retorno de carro
y nueva línea, o CR/LF ). Para buscar la combinación de caracteres CR/LF, incluya \r?$ en el patrón de expresión
regular.
En el ejemplo siguiente se agrega el delimitador $ al patrón de expresión regular usado en el ejemplo de la
sección Principio de cadena o línea . Cuando se usa con la cadena de entrada original, que incluye cinco líneas de
texto, el método Regex.Matches(String, String) no puede encontrar una coincidencia, porque el final de la primera
línea no coincide con el patrón $ . Cuando la cadena de entrada original se divide en una matriz de cadenas, el
método Regex.Matches(String, String) consigue encontrar coincidencias en cada una de las cinco líneas. Cuando
se llama al método Regex.Matches(String, String, RegexOptions) con el parámetro options establecido en
RegexOptions.Multiline, no se encuentra ninguna coincidencia porque el patrón de la expresión regular no tiene
en cuenta el elemento de retorno de carro (\u+000D ). Sin embargo, cuando el patrón de la expresión regular se
modifica al remplazar $ por \r?$ , si se llama al método Regex.Matches(String, String, RegexOptions) con el
parámetro options establecido en RegexOptions.Multiline , ahora encuentra cinco coincidencias.
using System;
using System.Text.RegularExpressions;
Console.WriteLine(".");
match = match.NextMatch();
}
Console.WriteLine();
Console.WriteLine(".");
match = match.NextMatch();
}
Console.WriteLine();
Console.WriteLine(".");
match = match.NextMatch();
}
Console.WriteLine();
}
}
// The example displays the following output:
// Attempting to match the entire input string:
//
// Attempting to match each element in a string array:
// The Brooklyn Dodgers played in the National League in 1911, 1912, 1932-1957.
// The Chicago Cubs played in the National League in 1903-present.
// The Detroit Tigers played in the American League in 1901-present.
// The New York Giants played in the National League in 1885-1957.
// The Washington Senators played in the American League in 1901-1960.
//
// Attempting to match each line of an input string with '$':
//
// Attempting to match each line of an input string with '\r?$':
// The Brooklyn Dodgers played in the National League in 1911, 1912, 1932-1957.
// The Chicago Cubs played in the National League in 1903-present.
// The Detroit Tigers played in the American League in 1901-present.
// The New York Giants played in the National League in 1885-1957.
// The Washington Senators played in the American League in 1901-1960.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "Brooklyn Dodgers, National League, 1911, 1912, 1932-1957" + vbCrLf +
"Chicago Cubs, National League, 1903-present" + vbCrLf +
"Detroit Tigers, American League, 1901-present" + vbCrLf +
"New York Giants, National League, 1885-1957" + vbCrLf +
"Washington Senators, American League, 1901-1960" + vbCrLf
match = match.NextMatch()
Loop
Console.WriteLine()
End Sub
End Module
' The example displays the following output:
' Attempting to match the entire input string:
'
' Attempting to match each element in a string array:
' The Brooklyn Dodgers played in the National League in 1911, 1912, 1932-1957.
' The Chicago Cubs played in the National League in 1903-present.
' The Detroit Tigers played in the American League in 1901-present.
' The New York Giants played in the National League in 1885-1957.
' The Washington Senators played in the American League in 1901-1960.
'
' Attempting to match each line of an input string with '$':
'
' Attempting to match each line of an input string with '\r?$':
' The Brooklyn Dodgers played in the National League in 1911, 1912, 1932-1957.
' The Chicago Cubs played in the National League in 1903-present.
' The Detroit Tigers played in the American League in 1901-present.
' The New York Giants played in the National League in 1885-1957.
' The Washington Senators played in the American League in 1901-1960.
Console.WriteLine(".");
match = match.NextMatch();
}
Console.WriteLine();
}
}
// The example displays the following output:
// The Brooklyn Dodgers played in the National League in 1911, 1912, 1932-1957.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "Brooklyn Dodgers, National League, 1911, 1912, 1932-1957" + vbCrLf +
"Chicago Cubs, National League, 1903-present" + vbCrLf +
"Detroit Tigers, American League, 1901-present" + vbCrLf +
"New York Giants, National League, 1885-1957" + vbCrLf +
"Washington Senators, American League, 1901-1960" + vbCrLf
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim inputs() As String = {"Brooklyn Dodgers, National League, 1911, 1912, 1932-1957",
"Chicago Cubs, National League, 1903-present" + vbCrLf,
"Detroit Tigers, American League, 1901-present" + vbLf,
"New York Giants, National League, 1885-1957",
"Washington Senators, American League, 1901-1960" + vbCrLf}
Dim pattern As String = "^((\w+(\s?)){2,}),\s(\w+\s\w+),(\s\d{4}(-(\d{4}|present))?,?)+\r?\Z"
Module Example
Public Sub Main()
Dim inputs() As String = {"Brooklyn Dodgers, National League, 1911, 1912, 1932-1957",
"Chicago Cubs, National League, 1903-present" + vbCrLf,
"Detroit Tigers, American League, 1901-present" + vbLf,
"New York Giants, National League, 1885-1957",
"Washington Senators, American League, 1901-1960" + vbCrLf}
Dim pattern As String = "^((\w+(\s?)){2,}),\s(\w+\s\w+),(\s\d{4}(-(\d{4}|present))?,?)+\r?\z"
Coincidencias contiguas: \G
El delimitador \G especifica que debe producirse una coincidencia en el punto en el que finalizó la coincidencia
anterior. El uso de este delimitador con el método Regex.Matches o Match.NextMatch permite asegurarse de que
todas las coincidencias son contiguas.
En el ejemplo siguiente se usa una expresión regular para extraer los nombres de especies de roedores de una
cadena delimitada por comas.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "capybara,squirrel,chipmunk,porcupine,gopher," +
"beaver,groundhog,hamster,guinea pig,gerbil," +
"chinchilla,prairie dog,mouse,rat"
Dim pattern As String = "\G(\w+\s?\w*),?"
Dim match As Match = Regex.Match(input, pattern)
Do While match.Success
Console.WriteLine(match.Groups(1).Value)
match = match.NextMatch()
Loop
End Sub
End Module
' The example displays the following output:
' capybara
' squirrel
' chipmunk
' porcupine
' gopher
' beaver
' groundhog
' hamster
' guinea pig
' gerbil
' chinchilla
' prairie dog
' mouse
' rat
La expresión regular \G(\w+\s?\w*),? se interpreta como se muestra en la tabla siguiente.
MODELO DESCRIPCIÓN
(\w+\s?\w*) Coincide con uno o varios caracteres que se usan para formar
palabras seguidos de cero o un espacio, seguidos de cero o
más caracteres que se usan para formar palabras. Este es el
primer grupo de captura.
Límite de palabras: \b
El delimitador \b especifica que la coincidencia se debe producir en un límite entre un carácter que se usa para
formar palabras (el elemento del lenguaje \w ) y un carácter que no se usa para formar palabras (el elemento del
lenguaje \W ). Los caracteres que se usan para formar palabras son los caracteres alfanuméricos y de subrayado;
un carácter que no se usa para formar palabras es cualquier carácter que no es alfanumérico ni de subrayado.
(Para más información, vea Clases de carácter). La coincidencia también se puede producir en un límite de
palabras al principio o al final de la cadena.
El delimitador \b se usa con frecuencia para asegurarse de que una subexpresión coincide con una palabra
completa en lugar de solo con el principio o el final de una palabra. La expresión regular \bare\w*\b del ejemplo
siguiente muestra este uso. Coincide con cualquier palabra que comience por la subcadena "are". El resultado del
ejemplo también muestra que \b coincide tanto con el principio como con el final de la cadena de entrada.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim input As String = "area bare arena mare"
Dim pattern As String = "\bare\w*\b"
Console.WriteLine("Words that begin with 'are':")
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("'{0}' found at position {1}",
match.Value, match.Index)
Next
End Sub
End Module
' The example displays the following output:
' Words that begin with 'are':
' 'area' found at position 0
' 'arena' found at position 10
MODELO DESCRIPCIÓN
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim input As String = "equity queen equip acquaint quiet"
Dim pattern As String = "\Bqu\w+"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("'{0}' found at position {1}",
match.Value, match.Index)
Next
End Sub
End Module
' The example displays the following output:
' 'quity' found at position 1
' 'quip' found at position 14
' 'quaint' found at position 21
MODELO DESCRIPCIÓN
Vea también
Lenguaje de expresiones regulares: referencia rápida
Opciones de expresiones regulares
Construcciones de agrupamiento en expresiones
regulares
22/01/2020 • 66 minutes to read • Edit Online
Las construcciones de agrupamiento definen las subexpresiones de una expresión regular y capturan las
subcadenas de una cadena de entrada. Puede utilizar construcciones de agrupamiento para hacer lo siguiente:
Buscar una subexpresión que se repite en la cadena de entrada.
Aplicar un cuantificador a una subexpresión que tiene varios elementos del lenguaje de expresiones
regulares. Para más información sobre los cuantificadores, vea Quantifiers.
Incluir una subexpresión en la cadena devuelta por los métodos Regex.Replace y Match.Result .
Recuperar subexpresiones individuales de la propiedad Match.Groups y procesarlas por separado del
texto coincidente en su conjunto.
En la tabla siguiente se enumeran las construcciones de agrupamiento admitidas por el motor de expresiones
regulares de .NET y se indica si son de captura o sin captura.
Para obtener información sobre los grupos y el modelo de objetos de expresiones regulares, vea
Construcciones de agrupamiento y objetos de las expresiones regulares.
Subexpresiones coincidentes
La construcción de agrupación siguiente captura una subexpresión coincidente:
( subexpresión )
donde subexpresión es cualquier patrón de expresión regular válido. Las capturas que usan paréntesis se
numeran automáticamente de izquierda a derecha según el orden de los paréntesis de apertura de la
expresión regular, empezando desde uno. La captura con el número cero es el texto coincidente con el patrón
de la expresión regular completa.
NOTE
De manera predeterminada, el elemento de lenguaje ( subexpresión ) captura la subexpresión coincidente. No
obstante, la subexpresión coincidente no se captura si el parámetro RegexOptions del método de coincidencia de
patrones de una expresión regular incluye la marca RegexOptions.ExplicitCapture o si se aplica la opción n a esta
subexpresión (vea Opciones de grupo más adelante en este tema).
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim pattern As String = "(\w+)\s(\1)\W"
Dim input As String = "He said that that was the the correct answer."
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
Console.WriteLine("Duplicate '{0}' found at positions {1} and {2}.", _
match.Groups(1).Value, match.Groups(1).Index, match.Groups(2).Index)
Next
End Sub
End Module
' The example displays the following output:
' Duplicate 'that' found at positions 8 and 13.
' Duplicate 'the' found at positions 22 and 26.
MODELO DESCRIPCIÓN
O bien
(?'name'subexpression)
donde nombre es un nombre de grupo válido, y subexpresión es cualquier patrón de expresión regular válido.
nombre no debe contener ningún carácter de puntuación y no puede comenzar por un número.
NOTE
Si el parámetro RegexOptions del método de coincidencia de patrones de una expresión regular incluye la marca
RegexOptions.ExplicitCapture o si se aplica la opción n a esta subexpresión (vea Opciones de grupo más adelante en
este tema), la única forma de capturar una subexpresión es asignar nombres explícitamente a los grupos de captura.
Puede tener acceso a los grupos capturados con nombre de las maneras siguientes:
Usando la construcción de referencia inversa con nombre dentro de la expresión regular. Para hacer
referencia a la subexpresión coincidente desde la misma expresión regular, se usa la sintaxis \k<
nombre > , donde nombre es el nombre de la subexpresión capturada.
Usando la construcción de referencia inversa dentro de la expresión regular. Para hacer referencia a la
subexpresión coincidente desde la misma expresión regular, se usa la sintaxis \ número, donde
número es el número ordinal de la subexpresión capturada. Las subexpresiones coincidentes con
nombre se numeran consecutivamente de izquierda a derecha después de las subexpresiones
coincidentes.
Usando la secuencia de reemplazo ${ nombre } en una llamada al método Regex.Replace o
Match.Result , donde nombre es el nombre de la subexpresión capturada.
Usando la secuencia de reemplazo $ número en una llamada al método Regex.Replace o Match.Result
, donde número es el número ordinal de la subexpresión capturada.
Mediante programación, usando el objeto GroupCollection devuelto por la propiedad Match.Groups .
El miembro en la posición cero de la colección representa la coincidencia de la expresión regular
completa. Cada miembro subsiguiente representa una subexpresión coincidente. Los grupos
capturados con nombre se almacenan en la colección después de los grupos capturados numerados.
Mediante programación, proporcionando el nombre de la subexpresión al indizador del objeto
GroupCollection (en C#) o a su propiedad Item[String] (en Visual Basic).
Un patrón de expresión regular simple muestra cómo se puede hacer referencia a los grupos numerados (sin
nombre) y con nombre mediante programación o utilizando la sintaxis del lenguaje de expresiones regulares.
La expresión regular ((?<One>abc)\d+)?(?<Two>xyz)(.*) produce los siguientes grupos de captura por número
y por nombre. El primer grupo de captura (el número 0) siempre hace referencia al patrón completo.
3 Uno (?<One>abc)
4 Dos (?<Two>xyz)
En el ejemplo siguiente se muestra una expresión regular que identifica las palabras duplicadas y la palabra
que sigue inmediatamente a cada palabra duplicada. El patrón de la expresión regular define dos
subexpresiones con nombre: duplicateWord , que representa la palabra duplicada; y nextWord , que representa
la palabra que sigue a la palabra duplicada.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "(?<duplicateWord>\w+)\s\k<duplicateWord>\W(?<nextWord>\w+)"
Dim input As String = "He said that that was the the correct answer."
Console.WriteLine(Regex.Matches(input, pattern, RegexOptions.IgnoreCase).Count)
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
Console.WriteLine("A duplicate '{0}' at position {1} is followed by '{2}'.", _
match.Groups("duplicateWord").Value, match.Groups("duplicateWord").Index, _
match.Groups("nextWord").Value)
Next
End Sub
End Module
' The example displays the following output:
' A duplicate 'that' at position 8 is followed by 'was'.
' A duplicate 'the' at position 22 is followed by 'correct'.
MODELO DESCRIPCIÓN
Tenga en cuenta que un nombre de grupo se puede repetir en una expresión regular. Por ejemplo, es posible
que más de un grupo se llame digit , como muestra el ejemplo siguiente. En el caso de nombres duplicados,
el valor del objeto Group viene determinado por la última captura correcta en la cadena de entrada. Además,
la colección CaptureCollection se rellena con información de cada captura igual que si el nombre de grupo no
estuviera duplicado.
En el ejemplo siguiente, la expresión regular \D+(?<digit>\d+)\D+(?<digit>\d+)? incluye dos apariciones de
un grupo llamado digit . El primer grupo llamado digit captura uno o más caracteres de dígito. El segundo
grupo llamado digit captura cero o una aparición de uno o más caracteres de dígito. Tal y como muestra la
salida del ejemplo, si el segundo grupo de captura coincide correctamente con el texto, el valor de ese texto
define el valor del objeto Group . Si el segundo grupo de captura no coincide con la cadena de entrada, el
valor de la última coincidencia correcta define el valor del objeto Group .
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim pattern As String = "\D+(?<digit>\d+)\D+(?<digit>\d+)?"
Dim inputs() As String = { "abc123def456", "abc123def" }
For Each input As String In inputs
Dim m As Match = Regex.Match(input, pattern)
If m.Success Then
Console.WriteLine("Match: {0}", m.Value)
For grpCtr As Integer = 1 to m.Groups.Count - 1
Dim grp As Group = m.Groups(grpCtr)
Console.WriteLine("Group {0}: {1}", grpCtr, grp.Value)
For capCtr As Integer = 0 To grp.Captures.Count - 1
Console.WriteLine(" Capture {0}: {1}", capCtr,
grp.Captures(capCtr).Value)
Next
Next
Else
Console.WriteLine("The match failed.")
End If
Console.WriteLine()
Next
End Sub
End Module
' The example displays the following output:
' Match: abc123def456
' Group 1: 456
' Capture 0: 123
' Capture 1: 456
'
' Match: abc123def
' Group 1: 123
' Capture 0: 123
MODELO DESCRIPCIÓN
O bien
(?'name1-name2' subexpression)
donde nombre1 es el grupo actual (opcional), nombre2 es un grupo definido previamente y subexpresión es
cualquier patrón de expresión regular válido. La definición de grupo de compensación elimina la definición de
nombre2 y almacena el intervalo entre nombre2 y nombre1 en nombre1. Si no se ha definido el grupo
nombre2 , la búsqueda de coincidencias retrocede. Como al eliminar la última definición de nombre2 se
revela la definición anterior de nombre2, esta construcción permite usar la pila de capturas del grupo
nombre2 como contador para realizar el seguimiento de construcciones anidadas como paréntesis o
corchetes de apertura y cierre.
La definición del grupo de compensación utiliza nombre2 como pila. El carácter inicial de cada construcción
anidada se coloca en el grupo y en su colección Group.Captures . Cuando se encuentra una coincidencia con
el carácter de cierre, el carácter de apertura correspondiente se quita del grupo, y la colección Captures
disminuye en una unidad. Después de buscar las coincidencias con los caracteres de apertura y cierre de
todas las construcciones anidadas, nombre2 estará vacío.
NOTE
Después de modificar la expresión regular del ejemplo siguiente para que utilice el carácter de apertura y cierre
adecuado de una construcción anidada, puede utilizarla con la mayoría de las estructuras anidadas, como expresiones
matemáticas o líneas de código de programa que incluyen varias llamadas a métodos anidadas.
En el ejemplo siguiente se usa una definición de grupo de compensación para que coincida con los corchetes
angulares de apertura y de cierre (<>) de una cadena de entrada. En el ejemplo se definen dos grupos con
nombre, Open y Close , que se utilizan como una pila para realizar el seguimiento de los pares de corchetes
angulares coincidentes. Cada corchete angular de apertura capturado se inserta en la colección de captura del
grupo Open , y cada corchete angular de cierre capturado se inserta en la colección de captura del grupo
Close . Mediante la definición del grupo de compensación se comprueba que haya un corchete angular de
cierre para cada corchete angular de apertura. Si no lo hay, el subpatrón final, (?(Open)(?!)) , se evalúa solo
si el grupo Open no está vacío (y, por consiguiente, si no se han cerrado todas las construcciones anidadas).
Si se evalúa el subpatrón final, la coincidencia produce un error, porque el subpatrón (?!) es una aserción de
búsqueda anticipada negativa de ancho cero que siempre produce un error.
using System;
using System.Text.RegularExpressions;
class Example
{
public static void Main()
{
string pattern = "^[^<>]*" +
"(" +
"((?'Open'<)[^<>]*)+" +
"((?'Close-Open'>)[^<>]*)+" +
")*" +
"(?(Open)(?!))$";
string input = "<abc><mno<xyz>>";
Module Example
Public Sub Main()
Dim pattern As String = "^[^<>]*" & _
"(" + "((?'Open'<)[^<>]*)+" & _
"((?'Close-Open'>)[^<>]*)+" + ")*" & _
"(?(Open)(?!))$"
Dim input As String = "<abc><mno<xyz>>"
Dim rgx AS New Regex(pattern)'
Dim m As Match = Regex.Match(input, pattern)
If m.Success Then
Console.WriteLine("Input: ""{0}"" " & vbCrLf & "Match: ""{1}""", _
input, m)
Dim grpCtr As Integer = 0
For Each grp As Group In m.Groups
Console.WriteLine(" Group {0}: {1}", grpCtr, grp.Value)
grpCtr += 1
Dim capCtr As Integer = 0
For Each cap As Capture In grp.Captures
Console.WriteLine(" Capture {0}: {1}", capCtr, cap.Value)
capCtr += 1
Next
Next
Else
Console.WriteLine("Match failed.")
End If
End Sub
End Module
' The example displays the following output:
' Input: "<abc><mno<xyz>>"
' Match: "<abc><mno<xyz>>"
' Group 0: <abc><mno<xyz>>
' Capture 0: <abc><mno<xyz>>
' Group 1: <mno<xyz>>
' Capture 0: <abc>
' Capture 1: <mno<xyz>>
' Group 2: <xyz
' Capture 0: <abc
' Capture 1: <mno
' Capture 2: <xyz
' Group 3: >
' Capture 0: >
' Capture 1: >
' Capture 2: >
' Group 4:
' Group 5: mno<xyz>
' Capture 0: abc
' Capture 1: xyz
' Capture 2: mno<xyz>
MODELO DESCRIPCIÓN
1 ^ Comienza la búsqueda de
coincidencias al principio de la cadena
de entrada
donde subexpresión es cualquier patrón de expresión regular válido. La construcción de grupo sin captura se
utiliza normalmente cuando un cuantificador se aplica a un grupo, pero las subcadenas capturadas por el
grupo no tienen ningún interés.
NOTE
Si una expresión regular incluye construcciones de agrupamiento anidadas, no se aplica una construcción de grupo sin
captura exterior a las construcciones de grupo anidadas interiores.
En el ejemplo siguiente se muestra una expresión regular que incluye grupos sin captura. Observe que la
salida no incluye ningún grupo capturado.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim pattern As String = "(?:\b(?:\w+)\W*)+\."
Dim input As String = "This is a short sentence."
Dim match As Match = Regex.Match(input, pattern)
Console.WriteLine("Match: {0}", match.Value)
For ctr As Integer = 1 To match.Groups.Count - 1
Console.WriteLine(" Group {0}: {1}", ctr, match.Groups(ctr).Value)
Next
End Sub
End Module
' The example displays the following output:
' Match: This is a short sentence.
La expresión regular (?:\b(?:\w+)\W*)+\. coincide con una frase que termina en un punto. Dado que la
expresión regular se centra en frases y no en palabras individuales, las construcciones de agrupamiento se
usan exclusivamente como cuantificadores. El patrón de la expresión regular se interpreta como se muestra
en la tabla siguiente.
MODELO DESCRIPCIÓN
Opciones de grupo
La siguiente construcción de agrupamiento aplica o deshabilita las opciones especificadas dentro de una
subexpresión:
(?imnsx-imnsx: subexpresión )
donde subexpresión es cualquier patrón de expresión regular válido. Por ejemplo, (?i-s:) activa la opción
que no hace distinción entre mayúsculas y minúsculas y deshabilita el modo de una sola línea. Para obtener
más información sobre las opciones insertadas que puede especificar, vea Opciones de expresiones regulares.
NOTE
Puede especificar opciones que se apliquen a una expresión regular completa en lugar de a una subexpresión usando
un constructor de la clase System.Text.RegularExpressions.Regex o un método estático. También puede especificar
opciones insertadas que se aplican después de un punto concreto en una expresión regular usando la construcción de
lenguaje (?imnsx-imnsx) .
La construcción de opciones de grupo no es un grupo de captura. Es decir, aunque cualquier parte de una
cadena capturada por subexpresión se incluye en la coincidencia, no se incluye en un grupo capturado ni se
usa para rellenar el objeto GroupCollection .
Por ejemplo, la expresión regular \b(?ix: d \w+)\s del ejemplo siguiente utiliza opciones insertadas en una
construcción de agrupamiento para habilitar la coincidencia sin distinción entre mayúsculas y minúsculas y
omitir el espacio en blanco del patrón para identificar todas las palabras que comienzan por la letra "d". La
expresión regular se define como se muestra en la tabla siguiente.
MODELO DESCRIPCIÓN
donde subexpresión es cualquier patrón de expresión regular. Para que se produzca una coincidencia, la
cadena de entrada debe coincidir con el patrón de expresión regular de subexpresión, aunque la subcadena
coincidente no se incluya en el resultado de la coincidencia. Una aserción de búsqueda anticipada positiva de
ancho cero no retrocede.
Normalmente, una aserción de búsqueda anticipada positiva de ancho cero se encuentra al final de un patrón
de expresión regular. Define una subcadena que se debe encontrar al final de una cadena para que se
produzca una coincidencia, pero que no debe incluirse en la coincidencia. También resulta útil para evitar un
retroceso excesivo. Puede usar una aserción de búsqueda anticipada positiva de ancho cero para asegurarse
de que un grupo capturado determinado comienza por un texto que coincide con un subconjunto del patrón
definido para dicho grupo capturado. Por ejemplo, si un grupo de captura coincide con caracteres
consecutivos que se usan para formar palabras, puede usar una aserción de búsqueda anticipada positiva de
ancho cero para requerir que el primero de los caracteres sea alfabético y esté en mayúsculas.
En el ejemplo siguiente se usa una aserción de búsqueda anticipada positiva de ancho cero para buscar la
palabra que precede al verbo "is" en la cadena de entrada.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim pattern As String = "\b\w+(?=\sis\b)"
Dim inputs() As String = { "The dog is a Malamute.", _
"The island has beautiful birds.", _
"The pitch missed home plate.", _
"Sunday is a weekend day." }
MODELO DESCRIPCIÓN
donde subexpresión es cualquier patrón de expresión regular. Para que se produzca la coincidencia, la cadena
de entrada no debe coincidir con el patrón de expresión regular de subexpresión, aunque la cadena
coincidente no se incluya en el resultado de la coincidencia.
Una aserción de búsqueda anticipada negativa de ancho cero se utiliza normalmente al principio o al final de
una expresión regular. Al principio de una expresión regular, puede definir un patrón concreto que no se
debería buscar cuando el principio de la expresión regular define un patrón similar pero más general que se
desea buscar. En este caso, se usa a menudo para limitar el retroceso. Al final de una expresión regular, puede
definir una subexpresión que no se puede producir al final de una coincidencia.
En el ejemplo siguiente se define una expresión regular que utiliza una aserción de búsqueda anticipada
negativa de ancho cero al principio de la expresión regular para buscar palabras que no comienzan por "un".
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b(?!un)\w+\b"
Dim input As String = "unite one unethical ethics use untie ultimate"
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
Console.WriteLine(match.Value)
Next
End Sub
End Module
' The example displays the following output:
' one
' ethics
' use
' ultimate
MODELO DESCRIPCIÓN
En el ejemplo siguiente se define una expresión regular que utiliza una aserción de búsqueda anticipada
negativa de ancho cero al final de la expresión regular para buscar palabras que no terminan por un carácter
de puntuación.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b\w+\b(?!\p{P})"
Dim input As String = "Disconnected, disjointed thoughts in a sentence fragment."
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(match.Value)
Next
End Sub
End Module
' The example displays the following output:
' disjointed
' thoughts
' in
' a
' sentence
MODELO DESCRIPCIÓN
donde subexpresión es cualquier patrón de expresión regular. Para que se produzca una coincidencia,
subexpresión debe encontrarse en la cadena de entrada a la izquierda de la posición actual, aunque
subexpression no esté incluida en el resultado de la coincidencia. Una aserción de búsqueda tardía positiva
de ancho cero no retrocede.
Las aserciones de búsqueda tardía positiva de ancho cero se usan normalmente al principio de las
expresiones regulares. El patrón que definen es una condición previa de una coincidencia, aunque no forma
parte del resultado de la coincidencia.
Por ejemplo, el ejemplo siguiente coincide con los dos últimos dígitos del año para el siglo XXI (es decir,
requiere que los dígitos "20" precedan a la cadena coincidente).
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "2010 1999 1861 2140 2009"
Dim pattern As String = "(?<=\b20)\d{2}\b"
MODELO DESCRIPCIÓN
Las aserciones de búsqueda tardía positiva de ancho cero también se usan para limitar el retroceso cuando el
último carácter o caracteres de un grupo capturado debe ser un subconjunto de los caracteres que coincide
con el patrón de la expresión regular de dicho grupo. Por ejemplo, si un grupo captura todos los caracteres
que se usan para formar palabras consecutivos, puede usar una aserción de búsqueda tardía positiva de
ancho cero para requerir que el último carácter sea alfabético.
donde subexpresión es cualquier patrón de expresión regular. Para que se produzca una coincidencia,
subexpresión no debe encontrarse en la cadena de entrada a la izquierda de la posición actual. Sin embargo,
cualquier subcadena que no coincida con subexpression no se incluye en el resultado de la coincidencia.
Las aserciones de búsqueda tardía negativa de ancho cero se usan normalmente al principio de las
expresiones regulares. El patrón que definen impide una coincidencia en la cadena que sigue. También se
usan para limitar el retroceso cuando el último carácter o caracteres de un grupo capturado no debe ser uno
o varios de los caracteres que coinciden con el patrón de expresión regular de dicho grupo. Por ejemplo, si un
grupo captura todos los caracteres que se usan para formar palabras consecutivos, se puede usar una
aserción de búsqueda tardía positiva de ancho cero para requerir que el último carácter no sea de subrayado
(_ ).
El ejemplo siguiente busca la fecha de cualquier día de la semana que no sea fin de semana (es decir, que no
sea ni sábado ni domingo).
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim dates() As String = { "Monday February 1, 2010", _
"Wednesday February 3, 2010", _
"Saturday February 6, 2010", _
"Sunday February 7, 2010", _
"Monday, February 8, 2010" }
Dim pattern As String = "(?<!(Saturday|Sunday) )\b\w+ \d{1,2}, \d{4}\b"
MODELO DESCRIPCIÓN
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim inputs() As String = { "cccd.", "aaad", "aaaa" }
Dim back As String = "(\w)\1+.\b"
Dim noback As String = "(?>(\w)\1+).\b"
La expresión regular sin retroceso (?>(\w)\1+).\b se define como se muestra en la tabla siguiente.
MODELO DESCRIPCIÓN
Module Example
Public Sub Main()
Dim pattern As String = "(\b(\w+)\W+)+"
Dim input As String = "This is a short sentence."
Dim match As Match = Regex.Match(input, pattern)
Console.WriteLine("Match: '{0}'", match.Value)
For ctr As Integer = 1 To match.Groups.Count - 1
Console.WriteLine(" Group {0}: '{1}'", ctr, match.Groups(ctr).Value)
Dim capCtr As Integer = 0
For Each capture As Capture In match.Groups(ctr).Captures
Console.WriteLine(" Capture {0}: '{1}'", capCtr, capture.Value)
capCtr += 1
Next
Next
End Sub
End Module
' The example displays the following output:
' Match: 'This is a short sentence.'
' Group 1: 'sentence.'
' Capture 0: 'This '
' Capture 1: 'is '
' Capture 2: 'a '
' Capture 3: 'short '
' Capture 4: 'sentence.'
' Group 2: 'sentence'
' Capture 0: 'This'
' Capture 1: 'is'
' Capture 2: 'a'
' Capture 3: 'short'
' Capture 4: 'sentence'
El patrón de expresión regular (\b(\w+)\W+)+ extrae palabras individuales de una cadena. Se define como se
muestra en la tabla siguiente.
MODELO DESCRIPCIÓN
El segundo grupo de captura coincide con cada palabra de la frase. El primer grupo de captura coincide con
cada palabra, junto con la puntuación y el espacio en blanco que siguen a la palabra. El objeto Group cuyo
índice es 2 proporciona información sobre el texto coincidente con el segundo grupo de captura. El conjunto
de palabras completo capturado por el grupo de captura está disponible desde el objeto CaptureCollection
devuelto por la propiedad Group.Captures .
Vea también
Lenguaje de expresiones regulares: referencia rápida
Retroceso
cuantificadores en expresiones regulares
04/11/2019 • 35 minutes to read • Edit Online
Los cuantificadores especifican cuántas instancias de un carácter, grupo o clase de caracteres deben estar
presentes en la entrada para que se encuentre una coincidencia. En la tabla siguiente se indican los
cuantificadores compatibles con .NET.
{ n , m } { n , m }? Coincide de n a m veces.
Las cantidades n y m son constantes de tipo entero. Normalmente, los cuantificadores son expansivos, ya que
hacen que el motor de expresiones regulares busque el mayor número posible de repeticiones de patrones
concretos. Si se anexa el carácter ? a un cuantificador se convierte en diferido, ya que hace que el motor de
expresiones regulares busque el menor número posible de repeticiones. Para obtener una descripción completa
de la diferencia entre los cuantificadores expansivos y diferidos, consulte la sección Cuantificadores expansivos
y diferidos más adelante en este tema.
IMPORTANT
El anidamiento de cuantificadores (por ejemplo, como hace el patrón de expresión regular (a*)* ) puede aumentar el
número de comparaciones que debe realizar el motor de expresiones regulares, como una función exponencial del
número de caracteres de la cadena de entrada. Para obtener más información sobre este comportamiento y sus
soluciones alternativas, consulte Retroceso.
NOTE
Si los caracteres *, +, ?, { y } se encuentran en un patrón de expresión regular, el motor de expresiones regulares los
interpreta como cuantificadores o como parte de construcciones de cuantificador, a menos que se incluyan en una clase
de caracteres. Para interpretarlos como caracteres literales fuera de una clase de caracteres, debe anteponerles una barra
diagonal inversa para indicar su secuencia de escape. Por ejemplo, la cadena \* en un patrón de expresión regular se
interpreta como un carácter de asterisco literal ("*").
MODELO DESCRIPCIÓN
string input = "Autumn is a great time for an annual announcement to all antique collectors.";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
Dim input As String = "Autumn is a great time for an annual announcement to all antique collectors."
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
' 'an' found at position 27.
' 'annual' found at position 30.
' 'announcement' found at position 37.
' 'antique' found at position 57.
MODELO DESCRIPCIÓN
an+ Coincide con una "a" seguida de uno o más caracteres "n".
MODELO DESCRIPCIÓN
MODELO DESCRIPCIÓN
MODELO DESCRIPCIÓN
MODELO DESCRIPCIÓN
MODELO DESCRIPCIÓN
(\w{3,}?\.){2}? Coincide con el patrón del primer grupo dos veces, pero el
menor número de veces posible.
MODELO DESCRIPCIÓN
La expresión regular no coincide con el primer número porque el cuantificador * intenta coincidir con el
elemento anterior tantas veces como sea posible en toda la cadena y, por tanto, encuentra una coincidencia al
final de la cadena.
Este no es el comportamiento deseado. En su lugar, puede usar el cuantificador diferido *? para extraer los
dígitos de ambos números, tal como se muestra en el ejemplo siguiente.
En la mayoría de los casos, las expresiones regulares con cuantificadores expansivos y diferidos devuelven las
mismas coincidencias. Suelen devolver resultados diferentes cuando se usan con el metacarácter comodín ( . ),
que coincide con cualquier carácter.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim pattern As String = "(a?)*"
Dim input As String = "aaabbb"
Dim match As Match = Regex.Match(input, pattern)
Console.WriteLine("Match: '{0}' at index {1}",
match.Value, match.Index)
If match.Groups.Count > 1 Then
Dim groups As GroupCollection = match.Groups
For grpCtr As Integer = 1 To groups.Count - 1
Console.WriteLine(" Group {0}: '{1}' at index {2}",
grpCtr,
groups(grpCtr).Value,
groups(grpCtr).Index)
Dim captureCtr As Integer = 0
For Each capture As Capture In groups(grpCtr).Captures
captureCtr += 1
Console.WriteLine(" Capture {0}: '{1}' at index {2}",
captureCtr, capture.Value, capture.Index)
Next
Next
End If
End Sub
End Module
' The example displays the following output:
' Match: 'aaa' at index 0
' Group 1: '' at index 3
' Capture 1: 'a' at index 0
' Capture 2: 'a' at index 1
' Capture 3: 'a' at index 2
' Capture 4: '' at index 3
Para ver la diferencia práctica entre un grupo de captura que define un número mínimo y máximo de capturas y
otro que define un número fijo de capturas, tenga en cuenta los patrones de expresiones regulares
(a\1|(?(1)\1)){0,2} y (a\1|(?(1)\1)){2} . Ambas expresiones regulares constan de un único grupo de captura,
que se define como se muestra en la tabla siguiente.
MODELO DESCRIPCIÓN
(a\1 Coincide con "a", junto con el valor del primer grupo
capturado...
La primera expresión regular intenta coincidir con este patrón de cero a dos veces; el segundo, exactamente dos
veces. Dado que el primer modelo alcanza el número mínimo de capturas con su primera captura de
String.Empty, nunca se repite para intentar coincidir con a\1 ; el cuantificador {0,2} solo permite las
coincidencias vacías en la última iteración. En cambio, la segunda expresión regular coincide con "a" porque
evalúa a\1 una segunda vez. El número mínimo de iteraciones (dos) obliga al motor a repetirse tras una
coincidencia vacía.
using System;
using System.Text.RegularExpressions;
pattern = @"(a\1|(?(1)\1)){0,2}";
input = "aaabbb";
pattern = @"(a\1|(?(1)\1)){2}";
Console.WriteLine("Regex pattern: {0}", pattern);
match = Regex.Match(input, pattern);
Console.WriteLine("Matched '{0}' at position {1}.",
match.Value, match.Index);
if (match.Groups.Count > 1) {
for (int groupCtr = 1; groupCtr <= match.Groups.Count - 1; groupCtr++)
{
Group group = match.Groups[groupCtr];
Console.WriteLine(" Group: {0}: '{1}' at position {2}.",
groupCtr, group.Value, group.Index);
int captureCtr = 0;
foreach (Capture capture in group.Captures) {
captureCtr++;
Console.WriteLine(" Capture: {0}: '{1}' at position {2}.",
captureCtr, capture.Value, capture.Index);
}
}
}
}
}
// The example displays the following output:
// Regex pattern: (a\1|(?(1)\1)){0,2}
// Match: '' at position 0.
// Group: 1: '' at position 0.
// Capture: 1: '' at position 0.
//
// Regex pattern: (a\1|(?(1)\1)){2}
// Matched 'a' at position 0.
// Group: 1: 'a' at position 0.
// Capture: 1: '' at position 0.
// Capture: 2: 'a' at position 0.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern, input As String
pattern = "(a\1|(?(1)\1)){0,2}"
input = "aaabbb"
pattern = "(a\1|(?(1)\1)){2}"
Console.WriteLine("Regex pattern: {0}", pattern)
match = Regex.Match(input, pattern)
Console.WriteLine("Matched '{0}' at position {1}.",
match.Value, match.Index)
If match.Groups.Count > 1 Then
For groupCtr As Integer = 1 To match.Groups.Count - 1
Dim group As Group = match.Groups(groupCtr)
Console.WriteLine(" Group: {0}: '{1}' at position {2}.",
groupCtr, group.Value, group.Index)
Dim captureCtr As Integer = 0
For Each capture As Capture In group.Captures
captureCtr += 1
Console.WriteLine(" Capture: {0}: '{1}' at position {2}.",
captureCtr, capture.Value, capture.Index)
Next
Next
End If
End Sub
End Module
' The example displays the following output:
' Regex pattern: (a\1|(?(1)\1)){0,2}
' Match: '' at position 0.
' Group: 1: '' at position 0.
' Capture: 1: '' at position 0.
'
' Regex pattern: (a\1|(?(1)\1)){2}
' Matched 'a' at position 0.
' Group: 1: 'a' at position 0.
' Capture: 1: '' at position 0.
' Capture: 2: 'a' at position 0.
Vea también
Lenguaje de expresiones regulares: referencia rápida
Retroceso
Construcciones de referencia inversa en expresiones
regulares
20/01/2020 • 16 minutes to read • Edit Online
Las referencias inversas proporcionan una forma cómoda de identificar un carácter o subcadena repetidos dentro
de una cadena. Por ejemplo, si la cadena de entrada contiene varias apariciones de una subcadena arbitraria,
puede buscar una coincidencia con la primera aparición con un grupo de captura y después usar una referencia
inversa para buscar una coincidencia con las siguientes apariciones de la subcadena.
NOTE
Se usa una sintaxis independiente para hacer referencia a los grupos de captura con numeración y con nombre de las
cadenas de reemplazo. Para obtener más información, consulte Substituciones.
.NET define elementos del lenguaje independientes para hacer referencia a los grupos de captura con
numeración y con nombre. Para más información sobre los grupos de captura con nombre, vea Construcciones
de agrupamiento.
ELEMENTO DESCRIPCIÓN
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "(\w)\1"
Dim input As String = "trellis llama webbing dresser swagger"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("Found '{0}' at position {1}.", _
match.Value, match.Index)
Next
End Sub
End Module
' The example displays the following output:
' Found 'll' at position 3.
' Found 'll' at position 8.
' Found 'bb' at position 16.
' Found 'ss' at position 25.
' Found 'gg' at position 33.
O bien
\k' nombre '
donde nombre es el nombre de un grupo de captura definido en el patrón de expresión regular. Si nombre no
está definido en el patrón de expresión regular, se produce un error de análisis y el motor de expresiones
regulares produce una clase ArgumentException.
En el ejemplo siguiente, se buscan caracteres de palabra duplicados en una cadena. Define una expresión regular,
(?<char>\w)\k<char> , que consta de los siguientes elementos.
ELEMENTO DESCRIPCIÓN
\k<char> Coincide con el siguiente carácter que sea igual que el valor
del grupo de captura char .
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "(?<char>\w)\k<char>"
Dim input As String = "trellis llama webbing dresser swagger"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("Found '{0}' at position {1}.", _
match.Value, match.Index)
Next
End Sub
End Module
' The example displays the following output:
' Found 'll' at position 3.
' Found 'll' at position 8.
' Found 'bb' at position 16.
' Found 'ss' at position 25.
' Found 'gg' at position 33.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "(?<2>\w)\k<2>"
Dim input As String = "trellis llama webbing dresser swagger"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("Found '{0}' at position {1}.", _
match.Value, match.Index)
Next
End Sub
End Module
' The example displays the following output:
' Found 'll' at position 3.
' Found 'll' at position 8.
' Found 'bb' at position 16.
' Found 'ss' at position 25.
' Found 'gg' at position 33.
Si nombre es la representación de cadena de un número y ningún grupo de captura tiene ese nombre, \k<
nombre > es igual que la referencia inversa \ número, donde número es la posición ordinal de la captura. En el
ejemplo siguiente, hay un único grupo de captura denominado char . La construcción de referencia inversa hace
referencia a él como \k<1> . Como muestra la salida del ejemplo, la llamada a Regex.IsMatch se realiza
correctamente porque char es el primer grupo de captura.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Console.WriteLine(Regex.IsMatch("aa", "(?<char>\w)\k<1>"))
' Displays "True".
End Sub
End Module
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Console.WriteLine(Regex.IsMatch("aa", "(?<2>\w)\k<1>"))
' Throws an ArgumentException.
End Sub
End Module
MODELO DESCRIPCIÓN
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "(?<1>a)(?<1>\1b)*"
Dim input As String = "aababb"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("Match: " + match.Value)
For Each group As Group In match.Groups
Console.WriteLIne(" Group: " + group.Value)
Next
Next
End Sub
End Module
' The example display the following output:
' Group: aababb
' Group: abb
Al comparar la expresión regular con la cadena de entrada ("aababb"), el motor de expresiones regulares realiza
las siguientes operaciones:
1. Comienza al principio de la cadena y hace que "a" coincida correctamente con la expresión (?<1>a) .
Ahora, el valor del grupo 1 es "a".
2. Se desplaza hasta el segundo carácter y hace que la cadena "ab" coincida correctamente con la expresión
\1b , o "ab". Después, asigna el resultado "ab" a \1 .
3. Se desplaza hasta el cuarto carácter. La expresión (?<1>\1b)* puede coincidir cero o más veces, así que la
cadena "abb" coincide correctamente con la expresión \1b . Vuelve a asignar el resultado, "abb", a \1 .
En este ejemplo, * es un cuantificador de bucle: se evalúa repetidas veces hasta que el motor de expresiones
regulares no puede coincidir con el patrón que define. Los cuantificadores de bucle no borran las definiciones de
grupo.
Si un grupo no ha capturado ninguna subcadena, no se define una referencia inversa a ese grupo y no coincide
nunca. Así lo ilustra el patrón de expresión regular \b(\p{Lu}{2})(\d{2})?(\p{Lu}{2})\b que se define de la
siguiente forma:
MODELO DESCRIPCIÓN
Una cadena de entrada puede coincidir con esta expresión regular aunque no estén presentes los dos dígitos
decimales que define el segundo grupo de captura. En el ejemplo siguiente, se muestra que, aunque la
coincidencia es correcta, hay un grupo de captura vacío entre dos grupos de captura correctos.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim pattern As String = "\b(\p{Lu}{2})(\d{2})?(\p{Lu}{2})\b"
Dim inputs() As String = { "AA22ZZ", "AABB" }
For Each input As String In inputs
Dim match As Match = Regex.Match(input, pattern)
If match.Success Then
Console.WriteLine("Match in {0}: {1}", input, match.Value)
If match.Groups.Count > 1 Then
For ctr As Integer = 1 To match.Groups.Count - 1
If match.Groups(ctr).Success Then
Console.WriteLine("Group {0}: {1}", _
ctr, match.Groups(ctr).Value)
Else
Console.WriteLine("Group {0}: <no match>", ctr)
End If
Next
End If
End If
Console.WriteLine()
Next
End Sub
End Module
' The example displays the following output:
' Match in AA22ZZ: AA22ZZ
' Group 1: AA
' Group 2: 22
' Group 3: ZZ
'
' Match in AABB: AABB
' Group 1: AA
' Group 2: <no match>
' Group 3: BB
Vea también
Lenguaje de expresiones regulares: referencia rápida
Construcciones de alternancia en expresiones
regulares
20/01/2020 • 14 minutes to read • Edit Online
Las construcciones de alternancia modifican una expresión regular para habilitar la coincidencia condicional o
“either/or”. .NET admite tres construcciones de alternancia:
Coincidencia de patrones con |
Coincidencia condicional con (?(expresión)sí|no)
Coincidencia condicional basada en un grupo capturado válido
using System;
using System.Text.RegularExpressions;
string input = "The gray wolf blended in among the grey rocks.";
foreach (Match match in Regex.Matches(input, pattern1))
Console.WriteLine("'{0}' found at position {1}",
match.Value, match.Index);
Console.WriteLine();
foreach (Match match in Regex.Matches(input, pattern2))
Console.WriteLine("'{0}' found at position {1}",
match.Value, match.Index);
}
}
// The example displays the following output:
// 'gray' found at position 4
// 'grey' found at position 35
//
// 'gray' found at position 4
// 'grey' found at position 35
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
' Regular expression using character class.
Dim pattern1 As String = "\bgr[ae]y\b"
' Regular expression using either/or.
Dim pattern2 As String = "\bgr(a|e)y\b"
Dim input As String = "The gray wolf blended in among the grey rocks."
For Each match As Match In Regex.Matches(input, pattern1)
Console.WriteLine("'{0}' found at position {1}", _
match.Value, match.Index)
Next
Console.WriteLine()
For Each match As Match In Regex.Matches(input, pattern2)
Console.WriteLine("'{0}' found at position {1}", _
match.Value, match.Index)
Next
End Sub
End Module
' The example displays the following output:
' 'gray' found at position 4
' 'grey' found at position 35
'
' 'gray' found at position 4
' 'grey' found at position 35
La expresión regular que usa el carácter | , \bgr(a|e)y\b , se interpreta como se muestra en la tabla siguiente:
MODELO DESCRIPCIÓN
El carácter | también se puede usar para realizar una coincidencia either/or con varios caracteres o
subexpresiones, que pueden incluir cualquier combinación de literales de carácter y elementos de lenguaje de
expresión regular. (La clase de caracteres no proporciona esta funcionalidad). En el ejemplo siguiente, se usa el
carácter | para extraer un número de la seguridad social (SSN ) de EE. UU., de nueve dígitos y en formato
ddd-dd-dddd, o un número de identificación de empleador (EIN ), de nueve dígitos y en formato dd-ddddddd.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b"
Dim input As String = "01-9999999 020-333333 777-88-9999"
Console.WriteLine("Matches for {0}:", pattern)
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(" {0} at position {1}", match.Value, match.Index)
Next
End Sub
End Module
' The example displays the following output:
' Matches for \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b:
' 01-9999999 at position 0
' 777-88-9999 at position 22
MODELO DESCRIPCIÓN
donde (?= expresión ) es una construcción de aserción de ancho cero. Para más información, consulte la
sección sobre Construcciones de agrupamiento en expresiones regulares. Como el motor de expresiones
regulares interpreta la expresión como un delimitador (una aserción de ancho cero), la expresión debe ser una
aserción de ancho cero (para más información, consulte Delimitadores en expresiones regulares) o una
subexpresión que también esté incluida en sí. De lo contrario, no se pueden encontrar coincidencias para el
patrón sí .
NOTE
Si expresión es un grupo de captura con nombre o con numeración, la construcción de alternancia se interpreta como una
prueba de captura; para obtener más información, consulte la sección siguiente, Coincidencia condicional basada en un
grupo capturado válido. En otras palabras, el motor de expresiones regulares no intenta coincidir con la subcadena
capturada, sino que, en vez de eso, comprueba la presencia o la ausencia del grupo.
El siguiente ejemplo es una variación del que aparece en la sección Coincidencia de patrones either/or con |. En él
se usa la coincidencia condicional para determinar si los tres primeros caracteres después de un límite de palabra
son dos dígitos seguidos por un guión. Si es así, intenta buscar un número de identificación de empleador (EIN )
de EE. UU. Si no, intenta buscar un número de la seguridad social (SSN ) de EE.UU.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim pattern As String = "\b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b"
Dim input As String = "01-9999999 020-333333 777-88-9999"
Console.WriteLine("Matches for {0}:", pattern)
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(" {0} at position {1}", match.Value, match.Index)
Next
End Sub
End Module
' The example displays the following output:
' Matches for \b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b:
' 01-9999999 at position 0
' 777-88-9999 at position 22
MODELO DESCRIPCIÓN
o
(?( número ) sí | no )
donde nombre es el nombre y número es el número de un grupo de captura, sí es la expresión que debe coincidir
si nombre o número tienen una coincidencia, y no es la expresión opcional que debe coincidir si no la tienen.
Si nombre no se corresponde con el nombre de un grupo de captura que se usa en el patrón de expresión
regular, la construcción de alternancia se interpreta como una prueba de expresión, tal como se explica en la
sección anterior. Normalmente, esto significa que expresión se evalúa como false . Si número no se corresponde
con un grupo de captura numerado que se usa en el patrón de expresión regular, el motor de expresiones
regulares genera una excepción ArgumentException.
El siguiente ejemplo es una variación del que aparece en la sección Coincidencia de patrones either/or con |. En él
se usa un grupo de captura denominado n2 que consta de dos dígitos seguidos por un guión. La construcción
de alternancia prueba si este grupo de captura ha coincidido en la cadena de entrada. En caso afirmativo, la
construcción de alternancia intenta hacer coincidir los últimos siete dígitos de un número de identificación de
empleador de identificación de empleador (EIN ) de EE. UU. En caso negativo, intenta coincidir con un número de
la seguridad social (SSN ) de EE.UU.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b(?<n2>\d{2}-)?(?(n2)\d{7}|\d{3}-\d{2}-\d{4})\b"
Dim input As String = "01-9999999 020-333333 777-88-9999"
Console.WriteLine("Matches for {0}:", pattern)
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(" {0} at position {1}", match.Value, match.Index)
Next
End Sub
End Module
MODELO DESCRIPCIÓN
(?<n2>\d{2}-)? Coincide con cero o con dos dígitos seguidos por un guión.
Este grupo de captura se denomina n2 .
En el ejemplo siguiente se muestra una variación de este ejemplo, pero con un grupo numerado en lugar de un
grupo con nombre. Su patrón de expresión regular es \b(\d{2}-)?(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b .
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b(\d{2}-)?(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b"
Dim input As String = "01-9999999 020-333333 777-88-9999"
Console.WriteLine("Matches for {0}:", pattern)
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(" {0} at position {1}", match.Value, match.Index)
Next
End Sub
End Module
' The example displays the following output:
' Matches for \b(\d{2}-)?(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b:
' 01-9999999 at position 0
' 777-88-9999 at position 22
Vea también
Lenguaje de expresiones regulares: referencia rápida
Sustituciones en expresiones regulares
25/11/2019 • 28 minutes to read • Edit Online
Las sustituciones son elementos del lenguaje que se reconocen solo dentro de patrones de reemplazo. Usan un
patrón de expresión regular para definir todo o parte del texto que reemplazará el texto coincidente en la cadena
de entrada. El patrón de reemplazo puede estar compuesto de una o más sustituciones junto con caracteres
literales. Los patrones de reemplazo se proporcionan a las sobrecargas del método Regex.Replace que tiene un
parámetro replacement y al método Match.Result . Los métodos reemplazan el patrón que coincide con el patrón
que define el parámetro replacement .
.NET Framework define los elementos de sustitución que se enumeran en la siguiente tabla.
SUSTITUCIÓN DESCRIPCIÓN
NOTE
Para obtener una funcionalidad similar a la de un patrón de reemplazo dentro de una expresión regular, use una referencia
inversa. Para obtener más información acerca de las referencias inversas, vea Construcciones de referencia inversa.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim pattern As String = "\p{Sc}*(\s?\d+[.,]?\d*)\p{Sc}*"
Dim replacement As String = "$1"
Dim input As String = "$16.32 12.19 £16.29 €18.29 €18,29"
Dim result As String = Regex.Replace(input, pattern, replacement)
Console.WriteLine(result)
End Sub
End Module
' The example displays the following output:
' 16.32 12.19 16.29 18.29 18,29
MODELO DESCRIPCIÓN
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\p{Sc}*(?<amount>\s?\d+[.,]?\d*)\p{Sc}*"
Dim replacement As String = "${amount}"
Dim input As String = "$16.32 12.19 £16.29 €18.29 €18,29"
Dim result As String = Regex.Replace(input, pattern, replacement)
Console.WriteLine(result)
End Sub
End Module
' The example displays the following output:
' 16.32 12.19 16.29 18.29 18,29
MODELO DESCRIPCIÓN
using System;
using System.Globalization;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
' Define array of decimal values.
Dim values() As String = { "16.35", "19.72", "1234", "0.99"}
' Determine whether currency precedes (True) or follows (False) number.
Dim precedes As Boolean = (NumberFormatInfo.CurrentInfo.CurrencyPositivePattern Mod 2 = 0)
' Get decimal separator.
Dim cSeparator As String = NumberFormatInfo.CurrentInfo.CurrencyDecimalSeparator
' Get currency symbol.
Dim symbol As String = NumberFormatInfo.CurrentInfo.CurrencySymbol
' If symbol is a "$", add an extra "$".
If symbol = "$" Then symbol = "$$"
MODELO DESCRIPCIÓN
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "^(\w+\s?)+$"
Dim titles() As String = { "A Tale of Two Cities", _
"The Hound of the Baskervilles", _
"The Protestant Ethic and the Spirit of Capitalism", _
"The Origin of Species" }
Dim replacement As String = """$&"""
For Each title As String In titles
Console.WriteLine(Regex.Replace(title, pattern, replacement))
Next
End Sub
End Module
' The example displays the following output:
' "A Tale of Two Cities"
' "The Hound of the Baskervilles"
' "The Protestant Ethic and the Spirit of Capitalism"
' "The Origin of Species"
MODELO DESCRIPCIÓN
El patrón de reemplazo "$&" agrega una comilla literal al principio y al final de cada coincidencia.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim input As String = "aa1bb2cc3dd4ee5"
Dim pattern As String = "\d+"
Dim substitution As String = "$`"
Console.WriteLine("Matches:")
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(" {0} at position {1}", match.Value, match.Index)
Next
Console.WriteLine("Input string: {0}", input)
Console.WriteLine("Output string: " + _
Regex.Replace(input, pattern, substitution))
End Sub
End Module
' The example displays the following output:
' Matches:
' 1 at position 2
' 2 at position 5
' 3 at position 8
' 4 at position 11
' 5 at position 14
' Input string: aa1bb2cc3dd4ee5
' Output string: aaaabbaa1bbccaa1bb2ccddaa1bb2cc3ddeeaa1bb2cc3dd4ee
En este ejemplo, la cadena de entrada "aa1bb2cc3dd4ee5" contiene cinco coincidencias. En la siguiente tabla se
muestra cómo la sustitución $` hace que el motor de expresiones regulares reemplace cada coincidencia en la
cadena de entrada. El texto insertado se muestra en negrita en la columna de resultados.
CADENA ANTES DE LA
COINCIDIR CON POSICIÓN COINCIDENCIA CADENA DE RESULTADO
1 2 aa aaaabb2cc3dd4ee5
2 5 aa1bb aaaabbaa1bbcc3dd4ee5
3 8 aa1bb2cc aaaabbaa1bbccaa1bb2ccdd
4ee5
4 11 aa1bb2cc3dd aaaabbaa1bbccaa1bb2ccdda
a1bb2cc3ddee5
5 14 aa1bb2cc3dd4ee aaaabbaa1bbccaa1bb2ccdda
a1bb2cc3ddeeaa1bb2cc3d
d4ee
En el ejemplo siguiente, se usa el patrón de expresión regular \d+ para que coincida con una secuencia de uno o
más dígitos decimales en la cadena de entrada. La cadena de reemplazo $' reemplaza estos dígitos por el texto
que sigue a la coincidencia.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "aa1bb2cc3dd4ee5"
Dim pattern As String = "\d+"
Dim substitution As String = "$'"
Console.WriteLine("Matches:")
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(" {0} at position {1}", match.Value, match.Index)
Next
Console.WriteLine("Input string: {0}", input)
Console.WriteLine("Output string: " + _
Regex.Replace(input, pattern, substitution))
End Sub
End Module
' The example displays the following output:
' Matches:
' 1 at position 2
' 2 at position 5
' 3 at position 8
' 4 at position 11
' 5 at position 14
' Input string: aa1bb2cc3dd4ee5
' Output string: aabb2cc3dd4ee5bbcc3dd4ee5ccdd4ee5ddee5ee
En este ejemplo, la cadena de entrada "aa1bb2cc3dd4ee5" contiene cinco coincidencias. En la siguiente tabla se
muestra cómo la sustitución $' hace que el motor de expresiones regulares reemplace cada coincidencia en la
cadena de entrada. El texto insertado se muestra en negrita en la columna de resultados.
CADENA DESPUÉS DE LA
COINCIDIR CON POSICIÓN COINCIDENCIA CADENA DE RESULTADO
CADENA DESPUÉS DE LA
COINCIDIR CON POSICIÓN COINCIDENCIA CADENA DE RESULTADO
1 2 bb2cc3dd4ee5 aabb2cc3dd4ee5bb2cc3dd
4ee5
2 5 cc3dd4ee5 aabb2cc3dd4ee5bbcc3dd4e
e5cc3dd4ee5
3 8 dd4ee5 aabb2cc3dd4ee5bbcc3dd4e
e5ccdd4ee5dd4ee5
4 11 ee5 aabb2cc3dd4ee5bbcc3dd4e
e5ccdd4ee5ddee5ee5
5 14 String.Empty aabb2cc3dd4ee5bbcc3dd4e
e5ccdd4ee5ddee5ee
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b(\w+)\s\1\b"
Dim substitution As String = "$+"
Dim input As String = "The the dog jumped over the fence fence."
Console.WriteLine(Regex.Replace(input, pattern, substitution, _
RegexOptions.IgnoreCase))
End Sub
End Module
' The example displays the following output:
' The dog jumped over the fence.
El patrón de expresión regular \b(\w+)\s\1\b se define como se muestra en la tabla siguiente.
MODELO DESCRIPCIÓN
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "ABC123DEF456"
Dim pattern As String = "\d+"
Dim substitution As String = "$_"
Console.WriteLine("Original string: {0}", input)
Console.WriteLine("String with substitution: {0}", _
Regex.Replace(input, pattern, substitution))
End Sub
End Module
' The example displays the following output:
' Original string: ABC123DEF456
' String with substitution: ABCABC123DEF456DEFABC123DEF456
En este ejemplo, la cadena de entrada "ABC123DEF456" contiene dos coincidencias. En la siguiente tabla se muestra
cómo la sustitución $_ hace que el motor de expresiones regulares reemplace cada coincidencia en la cadena de
entrada. El texto insertado se muestra en negrita en la columna de resultados.
1 3 123 ABCABC123DEF456DEF456
2 5 456 ABCABC123DEF456DEFABC
123DEF456
Vea también
Lenguaje de expresiones regulares: referencia rápida
Opciones de expresiones regulares
25/11/2019 • 71 minutes to read • Edit Online
De forma predeterminada, al comparar una cadena de entrada con los caracteres literales de un patrón de
expresión regular, se distinguen mayúsculas de minúsculas, los espacios en blanco del patrón de expresión
regular se interpretan como caracteres de espacio en blanco literales, y los grupos de captura de la
expresión regular se denominan tanto implícita como explícitamente. Estos y otros aspectos del
comportamiento predeterminado de la expresión regular se pueden modificar mediante la especificación
de las opciones de la expresión regular. Estas opciones —que aparecen enumeradas en la tabla siguiente
— se pueden insertar como parte del patrón de expresión regular, o se pueden suministrar a un
constructor de clases System.Text.RegularExpressions.Regex o a un método estático de coincidencia de
patrones como valor de enumeración de System.Text.RegularExpressions.RegexOptions.
Especificación de opciones
Las opciones de las expresiones regulares se pueden especificar de tres modos:
En el parámetro options de un constructor de clases System.Text.RegularExpressions.Regex o
método de coincidencia de patrones estático ( Shared en Visual Basic), como Regex.Regex(String,
RegexOptions) o Regex.Match(String, String, RegexOptions). El parámetro options es una
combinación OR bit a bit de valores enumerados de
System.Text.RegularExpressions.RegexOptions.
Cuando se proporcionan opciones a una instancia Regex mediante el parámetro options de un
constructor de clase, las opciones se asignan a la propiedad
System.Text.RegularExpressions.RegexOptions. Sin embargo, la propiedad
System.Text.RegularExpressions.RegexOptions no refleja las opciones insertadas en el mismo
patrón de expresión regular.
Esto se muestra en el ejemplo siguiente. Usa el parámetro options del método
Regex.Match(String, String, RegexOptions) para habilitar la coincidencia sin distinción entre
mayúsculas y minúsculas, así como para ignorar el espacio en blanco del patrón a la hora de
identificar palabras que empiecen por la letra “d”.
string pattern = @"d \w+ \s";
string input = "Dogs are decidedly good pets.";
RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace;
Con la aplicación de las opciones insertadas en un patrón de expresión regular con la sintaxis
(?imnsx-imnsx) . La opción se aplica al patrón a partir del punto en que la opción se define hasta el
final del patrón o hasta el punto en que otra opción insertada deja a la opción sin definir. Tenga en
cuenta que la propiedad System.Text.RegularExpressions.RegexOptions de una instancia Regex no
refleja estas opciones insertadas. Para más información, consulte el tema Construcciones
misceláneas.
Esto se muestra en el ejemplo siguiente. Usa opciones insertadas para habilitar la coincidencia sin
distinción entre mayúsculas y minúsculas, así como para ignorar el espacio en blanco del patrón a
la hora de identificar palabras que empiecen por la letra “d”.
Si las opciones están insertadas, un signo menos ( - ) antes de una opción o conjunto de opciones
desactiva dichas opciones. Por ejemplo, la construcción insertada (?ix-ms) activa las opciones
RegexOptions.IgnoreCase y RegexOptions.IgnorePatternWhitespace y desactiva las opciones
RegexOptions.Multiline y RegexOptions.Singleline. Todas las opciones de expresión regular están
desactivadas de forma predeterminada.
NOTE
Si las opciones de expresión regular especificadas en el parámetro options de un constructor o llamada a método
están en conflicto con las opciones insertadas en un patrón de expresión regular, se usan las opciones insertadas.
Las siguientes opciones de expresión regular se pueden establecer con el parámetro y mediante inserción:
RegexOptions.IgnoreCase
RegexOptions.Multiline
RegexOptions.Singleline
RegexOptions.ExplicitCapture
RegexOptions.IgnorePatternWhitespace
Las siguientes cinco opciones de expresión regular se pueden establecer con el parámetro options , pero
no mediante inserción:
RegexOptions.None
RegexOptions.Compiled
RegexOptions.RightToLeft
RegexOptions.CultureInvariant
RegexOptions.ECMAScript
Determinación de opciones
Se pueden determinar las opciones que se proporcionaron a un objeto Regex al crearse su instancia; para
ello, recupere el valor de la propiedad Regex.Options de solo lectura. Esta propiedad resulta
especialmente útil para determinar las opciones definidas para una expresión regular compilada que se ha
creado con el método Regex.CompileToAssembly.
Para probar la presencia de cualquier opción, excepto RegexOptions.None, realice una operación AND
con el valor de la propiedad Regex.Options y el valor de RegexOptions en el que esté interesado. Después,
pruebe si el resultado es igual a ese valor RegexOptions. En el ejemplo siguiente se prueba si se ha
establecido la opción RegexOptions.IgnoreCase.
if (rgx.Options == RegexOptions.None)
Console.WriteLine("No options have been set.");
En las secciones siguientes se enumeran las opciones admitidas en una expresión regular de .NET.
Opciones predeterminadas
La opción RegexOptions.None indica que no se ha especificado ninguna opción y que el motor de
expresiones regulares sigue su comportamiento predeterminado. Entre estas estructuras se incluyen las
siguientes:
El patrón se interpreta como un canónico en vez de como una expresión regular ECMAScript.
El patrón de expresión regular se compara con la cadena de entrada de izquierda a derecha.
Las comparaciones distinguen entre mayúsculas y minúsculas.
Los elementos de lenguaje ^ y $ coinciden con el principio y el final de la cadena de entrada.
El elemento de lenguaje . coincide con todos los caracteres excepto \n .
Un espacio en blanco en un patrón de expresión regular se interpreta como un carácter de espacio
literal.
Las convenciones de la referencia cultural actual se usan al comparar el patrón con la cadena de
entrada.
Los grupos de captura del patrón de expresión regular son implícitos y explícitos.
NOTE
La opción RegexOptions.None no tiene ningún equivalente de inserción. Cuando las opciones de expresión regular
se aplican mediante inserción, el comportamiento predeterminado se restaura opción por opción, mediante la
desactivación de una opción concreta. Por ejemplo, (?i) activa la comparación sin distinción entre mayúsculas y
minúsculas, y (?-i) restaura la comparación con distinción entre mayúsculas y minúsculas.
using System;
using System.Text.RegularExpressions;
Console.WriteLine();
foreach (Match match in Regex.Matches(input, pattern,
RegexOptions.IgnoreCase))
Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index);
}
}
// The example displays the following output:
// Found then at index 8.
// Found them at index 18.
//
// Found The at index 0.
// Found then at index 8.
// Found them at index 18.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\bthe\w*\b"
Dim input As String = "The man then told them about that event."
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index)
Next
Console.WriteLine()
For Each match As Match In Regex.Matches(input, pattern, _
RegexOptions.IgnoreCase)
Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index)
Next
End Sub
End Module
' The example displays the following output:
' Found then at index 8.
' Found them at index 18.
'
' Found The at index 0.
' Found then at index 8.
' Found them at index 18.
En el ejemplo siguiente se modifica el patrón de expresión regular del ejemplo anterior a fin de usar las
opciones insertadas en vez del parámetro options para realizar la comparación sin distinción entre
mayúsculas y minúsculas. El primer parámetro define la opción sin distinción entre mayúsculas y
minúsculas en una construcción de agrupamiento que se aplica solo a la letra “t” de la cadena “the”. Como
la construcción de opciones ocurre al principio del patrón, el segundo patrón aplica la opción sin
distinción entre mayúsculas y minúsculas a toda la expresión regular.
using System;
using System.Text.RegularExpressions;
Console.WriteLine();
pattern = @"(?i)\bthe\w*\b";
foreach (Match match in Regex.Matches(input, pattern,
RegexOptions.IgnoreCase))
Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index);
}
}
// The example displays the following output:
// Found The at index 0.
// Found then at index 8.
// Found them at index 18.
//
// Found The at index 0.
// Found then at index 8.
// Found them at index 18.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b(?i:t)he\w*\b"
Dim input As String = "The man then told them about that event."
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index)
Next
Console.WriteLine()
pattern = "(?i)\bthe\w*\b"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index)
Next
End Sub
End Module
' The example displays the following output:
' Found The at index 0.
' Found then at index 8.
' Found them at index 18.
'
' Found The at index 0.
' Found then at index 8.
' Found them at index 18.
Modo multilínea
La opción RegexOptions.Multiline, o la opción insertada m , habilita al motor de expresiones regulares
para que controle una cadena de entrada que consta de varias líneas. Cambia la interpretación de los
elementos de lenguaje ^ y $ de modo que coincidan con el inicio y el final de una línea, en vez de con el
inicio y el final de la cadena de entrada.
De forma predeterminada, $ coincide solo con el final de la cadena de entrada. Si se especifica la opción
RegexOptions.Multiline, coincide con el carácter de nueva línea ( \n ) o con el final de la cadena de
entrada. Sin embargo, no coincide con la combinación de caracteres de retorno de carro y salto de línea.
Para que coincida correctamente, use la subexpresión \r?$ en vez de simplemente $ .
En el ejemplo siguiente se extraen los nombres y las puntuaciones de los jugadores de bolos y se agregan
a una colección SortedList<TKey,TValue> que los ordena en sentido descendente. Se realizan dos
llamadas al método Matches. En la primera llamada a método, la expresión regular es ^(\w+)\s(\d+)$ y
no se establece ninguna opción. Como muestra el resultado, no se encuentran coincidencias, ya que el
motor de expresiones regulares no puede hacer coincidir el patrón de entrada junto con el principio y el
final de la cadena de entrada. En la segunda llamada a método, la expresión regular se cambia a
^(\w+)\s(\d+)\r?$ y las opciones se establecen en RegexOptions.Multiline. Como muestra el resultado,
los nombres y las puntuaciones coinciden correctamente, y las puntuaciones aparecen en orden
descendente.
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim scores As New SortedList(Of Integer, String)(New DescendingComparer(Of Integer)())
MODELO DESCRIPCIÓN
El ejemplo siguiente es equivalente al anterior, a excepción de que usa la opción insertada (?m) para
establecer la opción multilínea.
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim scores As New SortedList(Of Integer, String)(New DescendingComparer(Of Integer)())
Console.WriteLine();
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.Singleline))
Console.WriteLine(Regex.Escape(match.Value));
}
}
// The example displays the following output:
// This\ is\ one\ line\ and\r
//
// This\ is\ one\ line\ and\r\nthis\ is\ the\ second\.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "^.+"
Dim input As String = "This is one line and" + vbCrLf + "this is the second."
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(Regex.Escape(match.Value))
Next
Console.WriteLine()
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.SingleLine)
Console.WriteLine(Regex.Escape(match.Value))
Next
End Sub
End Module
' The example displays the following output:
' This\ is\ one\ line\ and\r
'
' This\ is\ one\ line\ and\r\nthis\ is\ the\ second\.
El ejemplo siguiente es equivalente al anterior, a excepción de que usa la opción insertada (?s) para
habilitar el modo de una sola línea.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim pattern As String = "(?s)^.+"
Dim input As String = "This is one line and" + vbCrLf + "this is the second."
Su única finalidad es extraer de un documento las oraciones que finalizan con un punto, signo de
exclamación o signo de interrogación, y solo la oración resultante (representada mediante el objeto
Match) es de interés. En cambio, las palabras individuales de la colección no son de interés.
Los grupos de captura que no se usan posteriormente pueden ser costosos, ya que el motor de
expresiones regulares debe rellenar los objetos de colección GroupCollection y CaptureCollection. Como
alternativa, se puede usar la opción RegexOptions.ExplicitCapture o la opción insertada n para
especificar que las únicas capturas válidas son grupos con nombre o número explícitos que se designan
mediante el constructor (?< nombre > subexpresión ) .
En el ejemplo siguiente se muestra información sobre las coincidencias devueltas por el patrón de
expresión regular \b\(?((\w+),?\s?)+[\.!?]\)? cuando se llama al método Match con y sin la opción
RegexOptions.ExplicitCapture. Tal como muestra el resultado de la primera llamada a método, el motor de
expresiones regulares rellena totalmente los objetos de colección GroupCollection y CaptureCollection
con información sobre las subcadenas capturadas. Dado que el segundo método se llama con options
establecido en RegexOptions.ExplicitCapture, no se captura información en grupos.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "This is the first sentence. Is it the beginning " + _
"of a literary masterpiece? I think not. Instead, " + _
"it is a nonsensical paragraph."
Dim pattern As String = "\b\(?((?>\w+),?\s?)+[\.!?]\)?"
Console.WriteLine("With implicit captures:")
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("The match: {0}", match.Value)
Dim groupCtr As Integer = 0
For Each group As Group In match.Groups
Console.WriteLine(" Group {0}: {1}", groupCtr, group.Value)
groupCtr += 1
Dim captureCtr As Integer = 0
For Each capture As Capture In group.Captures
Console.WriteLine(" Capture {0}: {1}", captureCtr, capture.Value)
captureCtr += 1
Next
Next
Next
Next
Console.WriteLine()
Console.WriteLine("With explicit captures only:")
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.ExplicitCapture)
Console.WriteLine("The match: {0}", match.Value)
Dim groupCtr As Integer = 0
For Each group As Group In match.Groups
Console.WriteLine(" Group {0}: {1}", groupCtr, group.Value)
groupCtr += 1
Dim captureCtr As Integer = 0
For Each capture As Capture In group.Captures
Console.WriteLine(" Capture {0}: {1}", captureCtr, capture.Value)
captureCtr += 1
Next
Next
Next
End Sub
End Module
' The example displays the following output:
' With implicit captures:
' The match: This is the first sentence.
' Group 0: This is the first sentence.
' Capture 0: This is the first sentence.
' Group 1: sentence
' Capture 0: This
' Capture 1: is
' Capture 2: the
' Capture 3: first
' Capture 4: sentence
' Group 2: sentence
' Capture 0: This
' Capture 1: is
' Capture 2: the
' Capture 3: first
' Capture 4: sentence
' The match: Is it the beginning of a literary masterpiece?
' Group 0: Is it the beginning of a literary masterpiece?
' Capture 0: Is it the beginning of a literary masterpiece?
' Group 1: masterpiece
' Capture 0: Is
' Capture 1: it
' Capture 2: the
' Capture 3: beginning
' Capture 4: of
' Capture 5: a
' Capture 6: literary
' Capture 7: masterpiece
' Group 2: masterpiece
' Capture 0: Is
' Capture 1: it
' Capture 2: the
' Capture 3: beginning
' Capture 4: of
' Capture 5: a
' Capture 6: literary
' Capture 7: masterpiece
' The match: I think not.
' Group 0: I think not.
' Capture 0: I think not.
' Group 1: not
' Capture 0: I
' Capture 1: think
' Capture 2: not
' Group 2: not
' Capture 0: I
' Capture 1: think
' Capture 2: not
' The match: Instead, it is a nonsensical paragraph.
' Group 0: Instead, it is a nonsensical paragraph.
' Capture 0: Instead, it is a nonsensical paragraph.
' Group 1: paragraph
' Capture 0: Instead,
' Capture 1: it
' Capture 2: is
' Capture 3: a
' Capture 4: nonsensical
' Capture 5: paragraph
' Group 2: paragraph
' Capture 0: Instead
' Capture 1: it
' Capture 2: is
' Capture 3: a
' Capture 4: nonsensical
' Capture 5: paragraph
'
' With explicit captures only:
' The match: This is the first sentence.
' Group 0: This is the first sentence.
' Capture 0: This is the first sentence.
' The match: Is it the beginning of a literary masterpiece?
' Group 0: Is it the beginning of a literary masterpiece?
' Capture 0: Is it the beginning of a literary masterpiece?
' The match: I think not.
' Group 0: I think not.
' Capture 0: I think not.
' The match: Instead, it is a nonsensical paragraph.
' Group 0: Instead, it is a nonsensical paragraph.
' Capture 0: Instead, it is a nonsensical paragraph.
MODELO DESCRIPCIÓN
También se puede usar el elemento insertado (?n) para suprimir las capturas automáticas. En el ejemplo
siguiente se modifica el patrón de expresión regular anterior para usar el elemento insertado (?n) en vez
de la opción RegexOptions.ExplicitCapture.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim input As String = "This is the first sentence. Is it the beginning " + _
"of a literary masterpiece? I think not. Instead, " + _
"it is a nonsensical paragraph."
Dim pattern As String = "(?n)\b\(?((?>\w+),?\s?)+[\.!?]\)?"
Finalmente, se puede usar el elemento de grupo insertado (?n:) para suprimir las capturas automáticas
grupo a grupo. En el ejemplo siguiente se modifica el patrón anterior para suprimir las capturas sin
nombre en el grupo externo, ((?>\w+),?\s?) . Observe que, de este modo, también se suprimen las
capturas sin nombre en el grupo interno.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim input As String = "This is the first sentence. Is it the beginning " + _
"of a literary masterpiece? I think not. Instead, " + _
"it is a nonsensical paragraph."
Dim pattern As String = "\b\(?(?n:(?>\w+),?\s?)+[\.!?]\)?"
NOTE
Una expresión regular solo se puede compilar si se suministra el valor RegexOptions.Compiled al parámetro
options de un constructor de clases Regex o de un método estático de coincidencia de patrones. No está
disponible como opción insertada.
Las expresiones regulares compiladas se pueden usar en llamadas a expresiones regulares estáticas y de
instancias. En expresiones regulares estáticas, la opción RegexOptions.Compiled se pasa al parámetro
options del método de coincidencia de patrones de expresión regular. En expresiones regulares de
instancia, se pasa al parámetro options del constructor de clases Regex. En ambos casos, tiene como
resultado una mejora en el rendimiento.
No obstante, esta mejora en el rendimiento solo se produce bajo las condiciones siguientes:
Un objeto Regex que representa una expresión regular concreta se usa en varias llamadas a
métodos de coincidencia de patrones de expresión regular.
El objeto Regex no puede estar fuera del ámbito y, por tanto, se puede volver a usar.
Una expresión regular estática se usa en varias llamadas a métodos de coincidencia de patrones de
expresión regular. (La mejora de rendimiento es posible porque el motor de expresiones regulares
almacena en la caché las expresiones regulares que se usan en llamadas de métodos estáticos).
NOTE
La opción RegexOptions.Compiled no está relacionada con el método Regex.CompileToAssembly, que crea un
ensamblado para fines especiales y que contiene expresiones regulares compiladas predefinidas.
El modelo es similar al modelo definido en la sección Solo capturas explícitas a excepción de que utiliza la
opción RegexOptions.IgnorePatternWhitespace para ignorar el espacio en blanco del modelo.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "This is the first sentence. Is it the beginning " + _
"of a literary masterpiece? I think not. Instead, " + _
"it is a nonsensical paragraph."
Dim pattern As String = "\b \(? ( (?>\w+) ,?\s? )+ [\.!?] \)? # Matches an entire sentence."
En el ejemplo siguiente se usa la opción insertada (?x) para ignorar el espacio en blanco del patrón.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "This is the first sentence. Is it the beginning " + _
"of a literary masterpiece? I think not. Instead, " + _
"it is a nonsensical paragraph."
Dim pattern As String = "(?x)\b \(? ( (?>\w+) ,?\s? )+ [\.!?] \)? # Matches an entire
sentence."
NOTE
El modo de patrón de derecha a izquierda solo está disponible si se suministra el valor RegexOptions.RightToLeft al
parámetro options de un constructor de clases Regex o de un método estático de coincidencia de patrones. No
está disponible como opción insertada.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\bb\w+\s"
Dim input As String = "builder rob rabble"
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.RightToLeft)
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
End Sub
End Module
' The example displays the following output:
' 'builder ' found at position 0.
Observe también que la aserción de búsqueda anticipada (el elemento de lenguaje (?= subexpresión ) ) y
la aserción de búsqueda tardía (el elemento de lenguaje (?<= subexpresión ) ) no cambian de dirección.
Las aserciones de búsqueda anticipada miran hacia la derecha, mientras que las de búsqueda tardía lo
hacen hacia la izquierda. Por ejemplo, la expresión regular (?<=\d{1,2}\s)\w+,?\s\d{4} usa la aserción de
búsqueda tardía para probar una fecha que precede al nombre de un mes. Después, la expresión regular
busca coincidencias con el mes y el año. Para información sobre aserciones de búsqueda anticipada y
tardía, consulte Construcciones de agrupamiento.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim inputs() As String = { "1 May 1917", "June 16, 2003" }
Dim pattern As String = "(?<=\d{1,2}\s)\w+,?\s\d{4}"
MODELO DESCRIPCIÓN
NOTE
El comportamiento conforme a ECMAScript solo está disponible si se suministra el valor RegexOptions.ECMAScript
al parámetro options de un constructor de clases Regex o de un método estático de coincidencia de patrones.
No está disponible como opción insertada.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim values() As String = { "целый мир", "the whole world" }
Dim pattern As String = "\b(\w+\s*)+"
For Each value In values
Console.Write("Canonical matching: ")
If Regex.IsMatch(value, pattern)
Console.WriteLine("'{0}' matches the pattern.", value)
Else
Console.WriteLine("{0} does not match the pattern.", value)
End If
Grupos de captura con autorreferencia. Una clase de captura de expresión regular con una
referencia inversa a sí misma debe actualizarse con cada iteración de captura. Como se muestra en
el ejemplo siguiente, esta característica permite a la expresión regular ((a+)(\1) ?)+ coincidir con
la cadena “ aa aaaa aaaaaa ” si se usa ECMAScript, pero no si se usa la búsqueda de coincidencias
canónica.
using System;
using System.Text.RegularExpressions;
Module Example
Dim pattern As String
MODELO DESCRIPCIÓN
\ seguido de un dígito de 1 a 9, Interprete los dígitos como un Para interpretarlo como una
seguido de dígitos decimales valor decimal. Si existe ese grupo referencia inversa, convierta todos
adicionales de captura, interprete la expresión los dígitos posibles en un valor
como una referencia inversa. decimal que pueda hacer
referencia a una captura. Si no se
De lo contrario, interprete los puede convertir ningún dígito,
dígitos octales iniciales hasta el interprételo como un octal; para
octal 377; es decir, tenga en ello, use los dígitos octales
cuenta solo los 8 bits inferiores iniciales hasta el octal 377 e
del valor. Interprete el resto de interprete el resto de dígitos
dígitos como literales. Por como literales.
ejemplo, en la expresión \3000 ,
si existe el grupo de captura 300,
interprételo como referencia
inversa de 300; si el grupo de
captura 300 no existe,
interprételo como un octal 300
seguido de 0.
Thread.CurrentThread.CurrentCulture = defaultCulture;
// The example displays the following output:
// Culture-sensitive matching (tr-TR culture)...
// Access to file://c:/Documents.MyReport.doc is allowed.
Thread.CurrentThread.CurrentCulture = defaultCulture
' The example displays the following output:
' Culture-sensitive matching (tr-TR culture)...
' Access to file://c:/Documents.MyReport.doc is allowed.
NOTE
Para obtener más información sobre la comparación de cadenas con distinción entre mayúsculas y minúsculas, y
con la referencia cultural de todos los idiomas, consulte Procedimientos recomendados para el uso de cadenas.
En vez de usar comparaciones sin distinción entre mayúsculas y minúsculas de la referencia cultural
actual, se puede especificar la opción RegexOptions.CultureInvariant para ignorar las diferencias
culturales de idioma y usar las convenciones de la referencia cultural de todos los idiomas.
NOTE
La comparación con la referencia cultural de todos los idiomas solo está disponible si se suministra el valor
RegexOptions.CultureInvariant al parámetro options de un constructor de clases Regex o de un método estático
de coincidencia de patrones. No está disponible como opción insertada.
El ejemplo siguiente es idéntico al anterior, excepto que se llama al método Regex.IsMatch(String, String,
RegexOptions) estático con opciones que incluyen RegexOptions.CultureInvariant. A pesar de que la
referencia cultural actual está establecida en turco (Turquía), el motor de expresiones regulares es capaz
de encontrar coincidencias con “FILE” y “file” y bloquear el acceso al recurso de archivo.
Console.WriteLine("Culture-insensitive matching...");
if (Regex.IsMatch(input, pattern,
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
Console.WriteLine("URLs that access files are not allowed.");
else
Console.WriteLine("Access to {0} is allowed.", input);
Thread.CurrentThread.CurrentCulture = defaultCulture;
// The example displays the following output:
// Culture-insensitive matching...
// URLs that access files are not allowed.
Console.WriteLine("Culture-insensitive matching...")
If Regex.IsMatch(input, pattern, _
RegexOptions.IgnoreCase Or RegexOptions.CultureInvariant) Then
Console.WriteLine("URLs that access files are not allowed.")
Else
Console.WriteLine("Access to {0} is allowed.", input)
End If
Thread.CurrentThread.CurrentCulture = defaultCulture
' The example displays the following output:
' Culture-insensitive matching...
' URLs that access files are not allowed.
Vea también
Lenguaje de expresiones regulares: referencia rápida
Construcciones misceláneas en expresiones regulares
04/11/2019 • 11 minutes to read • Edit Online
Las expresiones regulares en .NET incluyen tres construcciones de lenguaje misceláneas. Una permite habilitar o
deshabilitar opciones de coincidencia determinadas en medio de un patrón de expresión regular. Las otras dos
permiten incluir comentarios en una expresión regular.
Opciones insertadas
Puede establecer o deshabilitar opciones de coincidencia de patrones específicas para una parte de una expresión
regular mediante la sintaxis
(?imnsx-imnsx)
Indique las opciones que quiere habilitar después del signo de interrogación y las opciones que quiere
deshabilitar después del signo menos. En la siguiente tabla se describe cada una de las opciones. Para obtener
más información sobre cada opción, consulte Opciones de expresiones regulares.
OPCIÓN DESCRIPCIÓN
m Modo multilínea.
Cualquier cambio en las opciones de expresión regular definido mediante la construcción (?imnsx-imnsx)
permanece en vigor hasta el final del grupo envolvente.
NOTE
La construcción de agrupamiento (?imnsx-imnsx: subexpresión ) proporciona una funcionalidad idéntica para una
subexpresión. Para obtener más información, consulte Construcciones de agrupamiento.
En el ejemplo siguiente se usan las opciones i , n y x para habilitar las capturas explícitas y la opción que no
hace distinción entre mayúsculas y minúsculas, y para omitir el espacio en blanco del patrón de expresión regular
en medio de una expresión regular.
using System;
using System.Text.RegularExpressions;
pattern = @"\b(D\w+)\s(d\w+)\b";
// Match pattern using default options.
foreach (Match match in Regex.Matches(input, pattern))
{
Console.WriteLine(match.Value);
if (match.Groups.Count > 1)
for (int ctr = 1; ctr < match.Groups.Count; ctr++)
Console.WriteLine(" Group {0}: {1}", ctr, match.Groups[ctr].Value);
}
Console.WriteLine();
Module Example
Public Sub Main()
Dim pattern As String
Dim input As String = "double dare double Double a Drooling dog The Dreaded Deep"
pattern = "\b(D\w+)\s(d\w+)\b"
' Match pattern using default options.
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(match.Value)
If match.Groups.Count > 1 Then
For ctr As Integer = 1 To match.Groups.Count - 1
Console.WriteLine(" Group {0}: {1}", ctr, match.Groups(ctr).Value)
Next
End If
Next
Console.WriteLine()
En el ejemplo se definen dos expresiones regulares. La primera, \b(D\w+)\s(d\w+)\b , coincide con dos palabras
consecutivas que empiezan con una "D" mayúscula y una "d" minúscula. La segunda expresión regular,
\b(D\w+)(?ixn) \s (d\w+) \b , usa opciones insertadas para modificar este patrón, como se describe en la tabla
siguiente. Una comparación de los resultados confirma los efectos de la construcción (?ixn) .
MODELO DESCRIPCIÓN
Comentario alineado
La construcción (?# comment ) permite incluir un comentario alineado en una expresión regular. El motor de
expresiones regulares no usa ninguna parte del comentario en la coincidencia de patrones, aunque el comentario
se incluye en la cadena devuelta por el método Regex.ToString. El comentario termina en el primer paréntesis de
cierre.
En el ejemplo siguiente se repite el primer patrón de expresión regular del ejemplo de la sección anterior. Se
agregan dos comentarios alineados en la expresión regular para indicar si la comparación distingue entre
mayúsculas y minúsculas. El patrón de expresión regular,
\b((?# case-sensitive comparison)D\w+)\s(?ixn)((?#case-insensitive comparison)d\w+)\b , se define como se indica
a continuación.
MODELO DESCRIPCIÓN
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b((?# case-sensitive comparison)D\w+)\s(?ixn)((?#case-insensitive
comparison)d\w+)\b"
Dim rgx As New Regex(pattern)
Dim input As String = "double dare double Double a Drooling dog The Dreaded Deep"
MODELO DESCRIPCIÓN
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim pattern As String = "\{\d+(,-*\d+)*(\:\w{1,4}?)*\}(?x) # Looks for a composite format item."
Dim input As String = "{0,-3:F}"
Console.WriteLine("'{0}':", input)
If Regex.IsMatch(input, pattern) Then
Console.WriteLine(" contains a composite format item.")
Else
Console.WriteLine(" does not contain a composite format item.")
End If
End Sub
End Module
' The example displays the following output:
' '{0,-3:F}':
' contains a composite format item.
Tenga en cuenta que, en lugar de proporcionar la construcción (?x) en la expresión regular, el comentario
también podía haberse reconocido llamando al método Regex.IsMatch(String, String, RegexOptions) y pasando
el valor de enumeración RegexOptions.IgnorePatternWhitespace.
Vea también
Lenguaje de expresiones regulares: referencia rápida
Procedimientos recomendados con expresiones
regulares en .NET
20/01/2020 • 63 minutes to read • Edit Online
El motor de expresiones regulares de .NET es una herramienta eficaz y completa que procesa texto basándose en
coincidencias de patrones en lugar de comparar y buscar coincidencias con texto literal. En la mayoría de los casos,
realiza la coincidencia de modelos de manera rápida y eficaz. Sin embargo, en algunos casos, puede parecer que el
motor de expresiones regulares es muy lento. En casos extremos, incluso puede parecer que deja de responder
mientras procesa una entrada relativamente pequeña a lo largo de las horas o incluso los días.
En este tema se describen algunos de los procedimientos recomendados que los desarrolladores pueden adoptar
para garantizar que sus expresiones regulares alcancen un rendimiento óptimo.
WARNING
En el ejemplo siguiente se utiliza una expresión regular que es propensa a un retroceso excesivo y que es probable que
rechace direcciones de correo electrónico válidas. No debería utilizarse en una rutina de validación de correo electrónico. Si
desea que una expresión regular valide las direcciones de correo electrónico, vea Procedimiento: Comprobación de que las
cadenas están en un formato de correo electrónico válido.
Por ejemplo, considere una expresión regular de uso muy frecuente pero sumamente problemática para validar el
alias de una dirección de correo electrónico. Se escribe la expresión regular ^[0-9A-Z]([-.\w]*[0-9A-Z])*$ para
procesar qué se considera una dirección de correo electrónico válida, que consta de un carácter alfanumérico
seguido de cero o más caracteres que pueden ser alfanuméricos, puntos o guiones. La expresión regular debe
finalizar con un carácter alfanumérico. Sin embargo, como se muestra en el ejemplo siguiente, aunque esta
expresión regular trata la entrada válida fácilmente, su rendimiento es muy ineficaz cuando está procesando datos
de entrada casi válidos.
using System;
using System.Diagnostics;
using System.Text.RegularExpressions;
Imports System.Diagnostics
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim sw As Stopwatch
Dim addresses() As String = { "AAAAAAAAAAA@contoso.com",
"AAAAAAAAAAaaaaaaaaaa!@contoso.com" }
' The following regular expression should not actually be used to
' validate an email address.
Dim pattern As String = "^[0-9A-Z]([-.\w]*[0-9A-Z])*$"
Dim input As String
Como muestra el resultado del ejemplo, el motor de expresiones regulares procesa el alias válido de correo
electrónico casi en el mismo intervalo de tiempo independientemente de su longitud. Por otra parte, cuando la
dirección de correo electrónico casi válida tiene más de cinco caracteres, el tiempo de procesamiento se duplica
aproximadamente por cada carácter de la cadena. Esto significa que una cadena casi válida de 28 caracteres
tardaría más de una hora en procesarse y una cadena casi válida de 33 caracteres tardaría casi un día en
procesarse.
Como esta expresión regular se desarrolló teniendo en cuenta solamente el formato de entrada que había que
hacer coincidir, no tiene en cuenta los datos de entrada que no coinciden con el patrón. A su vez, esto puede
permitir que unos datos de entrada sin restricciones que casi coinciden con el patrón de expresión regular reduzcan
considerablemente el rendimiento.
Para resolver este problema, puede hacer lo siguiente:
A la hora de desarrollar un modelo, debe considerar cómo puede afectar el retroceso al rendimiento del
motor de expresiones regulares, especialmente si la expresión regular está diseñada para procesar datos de
entrada sin restricciones. Para obtener más información, consulte la sección Controlar el retroceso.
Probar exhaustivamente la expresión regular usando datos de entrada no válidos y casi válidos, así como
datos de entrada válidos. Para generar de forma aleatoria la entrada para una expresión regular
determinada, puede usar Rex, que es una herramienta de exploración de expresiones regulares de Microsoft
Research.
NOTE
Para obtener una explicación más detallada de las implicaciones sobre el rendimiento de usar expresiones regulares
interpretadas y compiladas, vea Optimizing Regular Expression Performance, Part II: (Optimización del rendimiento de
expresiones regulares, Parte II: Control del retroceso) en el blog del equipo de BCL.
Puede acoplar el motor de expresiones regulares con un determinado patrón de expresión regular y, a
continuación, usar el motor para buscar coincidencias con texto de varias maneras:
Puede llamar a un método estático de coincidencia de patrones como Regex.Match(String, String). Para ello
no es necesario crear instancias de un objeto de expresión regular.
Puede crear instancias de un objeto Regex y llamar a una instancia de un método de coincidencia de
modelos de una expresión regular interpretada. Este es el método predeterminado para enlazar el motor de
expresiones regulares a un patrón de expresión regular. Se produce cuando se crea una instancia de un
objeto Regex sin un argumento options que incluya la marca Compiled.
Puede crear instancias de un objeto Regex y llamar a una instancia de un método de coincidencia de
modelos de una expresión regular compilada. Los objetos de expresiones regulares representan modelos
compilados cuando se crea una instancia de un objeto Regex con un argumento options que incluye la
marca Compiled.
Puede crear un objeto Regex especial que esté acoplado estrechamente con un determinado patrón de
expresión regular, compilarlo y guardarlo en un ensamblado independiente. Puede hacerlo llamando al
método Regex.CompileToAssembly.
La forma de llamar a los métodos de coincidencia de expresiones regulares puede tener un impacto significativo en
la aplicación. En las próximas secciones se explica cómo usar llamadas a métodos estáticos, expresiones regulares
interpretadas y expresiones regulares compiladas para mejorar el rendimiento de la aplicación.
IMPORTANT
El formato de la llamada al método (estático, interpretado o compilado) afecta al rendimiento si la misma expresión regular se
usa repetidamente en llamadas a métodos o si una aplicación usa muchos objetos de expresiones regulares.
En el ejemplo siguiente se muestra una implementación muy poco eficaz del método IsValidCurrency . Observe
que cada llamada al método vuelve a crear una instancia de un objeto Regex con el mismo modelo. Esto, a su vez,
significa que el patrón de expresión regular se debe volver a compilar cada vez que se llama al método.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Debe reemplazar este código ineficaz con una llamada al método estático Regex.IsMatch(String, String). Esto
elimina la necesidad de crear instancias de un objeto Regex cada vez que desea llamar a un método de coincidencia
de modelos y permite que el motor de expresiones regulares recupere una versión compilada de la expresión
regular de su memoria caché.
using System;
using System.Text.RegularExpressions;
De forma predeterminada, se almacenan en caché los 15 últimos patrones de expresiones regulares estáticas
usados recientemente. En el caso de las aplicaciones que necesitan un mayor número de expresiones regulares
estáticas almacenadas en caché, el tamaño de la memoria caché se puede ajustar estableciendo la propiedad
Regex.CacheSize.
La expresión regular \p{Sc}+\s*\d+ que se usa en este ejemplo comprueba que la cadena de entrada consta de un
símbolo de moneda y al menos un dígito decimal. El patrón se define como se muestra en la tabla siguiente.
MODELO DESCRIPCIÓN
using System;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
Imports System.Diagnostics
Imports System.IO
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b(\w+((\r?\n)|,?\s))*\w+[.?:;!]"
Dim sw As Stopwatch
Dim match As Match
Dim ctr As Integer
MODELO DESCRIPCIÓN
using System;
using System.Reflection;
using System.Text.RegularExpressions;
Imports System.Reflection
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim SentencePattern As New RegexCompilationInfo("\b(\w+((\r?\n)|,?\s))*\w+[.?:;!]",
RegexOptions.Multiline,
"SentencePattern",
"Utilities.RegularExpressions",
True)
Dim regexes() As RegexCompilationInfo = {SentencePattern}
Dim assemName As New AssemblyName("RegexLib, Version=1.0.0.1001, Culture=neutral, PublicKeyToken=null")
Regex.CompileToAssembly(regexes, assemName)
End Sub
End Module
Imports System.IO
Imports System.Text.RegularExpressions
Imports Utilities.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As New SentencePattern()
Dim inFile As New StreamReader(".\Dreiser_TheFinancier.txt")
Dim input As String = inFile.ReadToEnd()
inFile.Close()
Controlar el retroceso
Normalmente, el motor de expresiones regulares usa la progresión lineal para desplazarse a través de una cadena
de entrada y compararla con un patrón de expresión regular. Sin embargo, cuando en un patrón de expresión
regular se usan cuantificadores indeterminados como * , + y ? , el motor de expresiones regulares puede
abandonar una parte de las coincidencias parciales correctas y volver a un estado guardado previamente para
buscar una coincidencia correcta de todo el patron. Este proceso se denomina retroceso.
NOTE
Para obtener más información acerca del retroceso, consulte Detalles del comportamiento de expresiones regulares y
Retroceso. Para obtener una explicación detallada del retroceso, vea Optimizing Regular Expression Performance, Part II:
(Optimización del rendimiento de expresiones regulares, Parte II: Control del retroceso) en el blog del equipo de BCL.
La compatibilidad con el retroceso aporta a las expresiones regulares eficacia y flexibilidad. También deja la
responsabilidad de controlar el funcionamiento del motor de expresiones regulares en manos de los
desarrolladores de expresiones regulares. Puesto que los desarrolladores no suelen ser conscientes de esta
responsabilidad, su uso incorrecto del retroceso o su dependencia de un retroceso excesivo suele desempeñar el
rol más significativo en la degradación del rendimiento de las expresiones regulares. En un escenario de caso peor,
el tiempo de ejecución puede duplicarse por cada carácter adicional de la cadena de entrada. De hecho, usando
excesivamente el retroceso, es fácil crear el equivalente en programación de un bucle infinito si la entrada coincide
casi con el patrón de expresiones regulares; el motor de expresiones regulares puede tardar horas o incluso días en
procesar una cadena de entrada relativamente corta.
A menudo, las aplicaciones sufren una reducción del rendimiento por usar el retroceso a pesar de que el retroceso
no es esencial para una coincidencia. Por ejemplo, la expresión regular \b\p{Lu}\w*\b busca una coincidencia con
todas las palabras que comienzan por un carácter en mayúsculas, como se muestra en la tabla siguiente.
MODELO DESCRIPCIÓN
Puesto que un límite de palabra no es igual, o un subconjunto de, que un carácter alfabético, no hay ninguna
posibilidad de que el motor de expresiones regulares cruce un límite de palabra cuando busca coincidencias con
caracteres alfabéticos. Esto significa que para esta expresión regular, el retroceso nunca puede contribuir al éxito
global de cualquier coincidencia; solo puede degradar el rendimiento, ya que se fuerza que el motor de expresiones
regulares guarde su estado para cada coincidencia preliminar correcta de un carácter alfabético.
Si determina que el retroceso no es necesario, puede deshabilitarlo mediante el elemento de lenguaje
(?>subexpression) . En el ejemplo siguiente se analiza una cadena de entrada usando dos expresiones regulares. La
primera, \b\p{Lu}\w*\b , se basa en el retroceso. La segunda, \b\p{Lu}(?>\w*)\b , deshabilita el retroceso. Como
muestra el resultado del ejemplo, ambas producen el mismo resultado.
using System;
using System.Text.RegularExpressions;
Console.WriteLine();
pattern = @"\b\p{Lu}(?>\w*)\b";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine(match.Value);
}
}
// The example displays the following output:
// This
// Sentence
// Capital
//
// This
// Sentence
// Capital
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "This this word Sentence name Capital"
Dim pattern As String = "\b\p{Lu}\w*\b"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(match.Value)
Next
Console.WriteLine()
pattern = "\b\p{Lu}(?>\w*)\b"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(match.Value)
Next
End Sub
End Module
' The example displays the following output:
' This
' Sentence
' Capital
'
' This
' Sentence
' Capital
En muchos casos, el retroceso es esencial para buscar una coincidencia de un patrón de expresión regular con el
texto de entrada. Sin embargo, el retroceso excesivo puede degradar gravemente el rendimiento y dar la impresión
de que una aplicación ha dejado de responder. En concreto, esto ocurre cuando se anidan los cuantificadores y el
texto que coincide con la subexpresión externa es un subconjunto del texto que coincide con la subexpresión
interna.
WARNING
Además de evitar el retroceso excesivo, se debe utilizar la característica de tiempo de espera para garantizar que el retroceso
excesivo no reduzca gravemente el rendimiento de la expresión regular. Para obtener más información, consulte la sección
Usar valores de tiempo de espera.
Por ejemplo, el patrón de expresión regular ^[0-9A-Z]([-.\w]*[0-9A-Z])*\$$ está diseñado para buscar
coincidencias con un número de pieza que contiene al menos un carácter alfanumérico. Cualquier carácter
adicional puede constar de un carácter alfanumérico, un guión, un carácter de subrayado o un punto, aunque el
último carácter debe ser alfanumérico. El número de pieza termina con un signo de dólar. En algunos casos, este
patrón de expresión regular puede presentar un rendimiento muy deficiente porque los cuantificadores están
anidados y porque la subexpresión [0-9A-Z] es un subconjunto de la subexpresión [-.\w]* .
En estos casos, puede optimizar el rendimiento de la expresión regular quitando los cuantificadores anidados y
reemplazando la subexpresión externa con una aserción de búsqueda anticipada o de búsqueda tardía de ancho
cero. Las aserciones de búsqueda anticipada y de búsqueda tardía son delimitadores; no mueven el puntero en la
cadena de entrada, sino que realizan una búsqueda hacia delante o hacia atrás para comprobar si se cumple una
condición especificada. Por ejemplo, la expresión regular de número de pieza se puede volver a escribir como
^[0-9A-Z][-.\w]*(?<=[0-9A-Z])\$$ . Este patrón de expresión regular se define como se muestra en la tabla
siguiente.
MODELO DESCRIPCIÓN
(?<=[0-9A-Z]) Realizar una búsqueda anticipada del signo de dólar final para
asegurarse de que el carácter anterior es alfanumérico.
En el ejemplo siguiente se muestra el uso de esta expresión regular para encontrar una matriz que contiene los
números de pieza posibles.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim pattern As String = "^[0-9A-Z][-.\w]*(?<=[0-9A-Z])\$$"
Dim partNos() As String = { "A1C$", "A4", "A4$", "A1603D$",
"A1603D#" }
El lenguaje de expresiones regulares de .NET incluye los elementos del lenguaje siguientes, que puede usar para
eliminar cuantificadores anidados. Para obtener más información, consulte Construcciones de agrupamiento.
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
List<string> exclusions = new List<string>( new string[] { "a", "an", "the" });
int[] wordLengths = new int[29]; // Allocate an array of more than ample size.
string input = null;
StreamReader sr = null;
try {
sr = new StreamReader(filename);
input = sr.ReadToEnd();
input = sr.ReadToEnd();
}
catch (FileNotFoundException e) {
string msg = String.Format("Unable to find the file '{0}'", filename);
throw new IOException(msg, e);
}
catch (IOException e) {
throw new IOException(e.Message, e);
}
finally {
if (sr != null) sr.Close();
}
indexPos += m.Length + 1;
}
}
catch (RegexMatchTimeoutException e) {
if (e.MatchTimeout.TotalMilliseconds < MAX_TIMEOUT) {
timeoutInterval += INCREMENT;
init = false;
}
else {
// Rethrow the exception.
throw;
}
}
} while (m.Success);
Imports System.Collections.Generic
Imports System.IO
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim util As New RegexUtilities()
Dim title As String = "Doyle - The Hound of the Baskervilles.txt"
Dim title As String = "Doyle - The Hound of the Baskervilles.txt"
Try
Dim info = util.GetWordData(title)
Console.WriteLine("Words: {0:N0}", info.Item1)
Console.WriteLine("Average Word Length: {0:N2} characters", info.Item2)
Catch e As IOException
Console.WriteLine("IOException reading file '{0}'", title)
Console.WriteLine(e.Message)
Catch e As RegexMatchTimeoutException
Console.WriteLine("The operation timed out after {0:N0} milliseconds",
e.MatchTimeout.TotalMilliseconds)
End Try
End Sub
End Module
' If regex completed successfully, calculate number of words and average length.
Dim nWords As Integer
Dim nWords As Integer
Dim totalLength As Long
MODELO DESCRIPCIÓN
Como se muestra en el ejemplo siguiente, cuando se encuentra una coincidencia, los objetos GroupCollection y
CaptureCollection se rellenan con capturas de la coincidencia. En este caso, el grupo de captura (\w+[;,]?\s?)
existe para que se le pueda aplicar el cuantificador + , que permite que el patrón de expresión regular coincida con
cada palabra de una frase. De lo contrario, coincidiría con la última palabra de una frase.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim input As String = "This is one sentence. This is another."
Dim pattern As String = "\b(\w+[;,]?\s?)+[.?!]"
Cuando use subexpresiones solo para aplicarles cuantificadores y no le interese el texto capturado, debe
deshabilitar las capturas de grupo. Por ejemplo, el elemento de lenguaje (?:subexpression) impide al grupo al que
se aplica que capture subcadenas coincidentes. En el ejemplo siguiente, el patrón de expresión regular del ejemplo
anterior se cambia a \b(?:\w+[;,]?\s?)+[.?!] . Como muestra el resultado, evita que el motor de expresiones
regulares rellene las colecciones GroupCollection y CaptureCollection.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim input As String = "This is one sentence. This is another."
Dim pattern As String = "\b(?:\w+[;,]?\s?)+[.?!]"
Use la opción n del elemento de lenguaje (?imnsx) . Esta opción deshabilita todas las capturas sin nombre
o implícitas desde el punto del patrón de expresión regular en el que aparece el elemento. Las capturas se
deshabilitan hasta el final del modelo o hasta que la opción (-n) habilita las capturas sin nombre o
implícitas. Para obtener más información, consulte Construcciones misceláneas.
Use la opción n del elemento de lenguaje (?imnsx:subexpression) . Esta opción deshabilita todas las
capturas sin nombre o implícitas en subexpression . Las capturas por grupos de captura anidados sin
nombre o implícitos también se deshabilitan.
Temas relacionados
TITLE DESCRIPCIÓN
Detalles del comportamiento de expresiones regulares Examina la implementación del motor de expresiones regulares
de .NET. El tema se centra en la flexibilidad de las expresiones
regulares y explica la responsabilidad del desarrollador para
garantizar un funcionamiento eficaz y sólido del motor de
expresiones regulares.
Lenguaje de expresiones regulares: referencia rápida Describe los elementos del lenguaje de expresiones regulares
de .NET y proporciona vínculos a documentación detallada
sobre cada elemento del lenguaje.
El modelo de objetos de expresión regular
04/11/2019 • 44 minutes to read • Edit Online
En este tema se describe el modelo de objetos usado para trabajar con expresiones regulares de .NET. Contiene
las siguientes secciones:
Motor de expresiones regulares
Objetos MatchCollection y Match
Colección de grupos
Grupo capturado
Colección de capturas
Captura individual
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim values() As String = { "111-22-3333", "111-2-3333"}
Dim pattern As String = "^\d{3}-\d{2}-\d{4}$"
For Each value As String In values
If Regex.IsMatch(value, pattern) Then
Console.WriteLine("{0} is a valid SSN.", value)
Else
Console.WriteLine("{0}: Invalid", value)
End If
Next
End Sub
End Module
' The example displays the following output:
' 111-22-3333 is a valid SSN.
' 111-2-3333: Invalid
MODELO DESCRIPCIÓN
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "This is a a farm that that raises dairy cattle."
Dim pattern As String = "\b(\w+)\W+(\1)\b"
Dim match As Match = Regex.Match(input, pattern)
Do While match.Success
Console.WriteLine("Duplicate '{0}' found at position {1}.", _
match.Groups(1).Value, match.Groups(2).Index)
match = match.NextMatch()
Loop
End Sub
End Module
' The example displays the following output:
' Duplicate 'a' found at position 10.
' Duplicate 'that' found at position 22.
MODELO DESCRIPCIÓN
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "This is a a farm that that raises dairy cattle."
Dim pattern As String = "\b(\w+)\W+(\1)\b"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("Duplicate '{0}' found at position {1}.", _
match.Groups(1).Value, match.Groups(2).Index)
Next
End Sub
End Module
' The example displays the following output:
' Duplicate 'a' found at position 10.
' Duplicate 'that' found at position 22.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b\d+\.\d{2}\b"
Dim replacement As String = "$$$&"
Dim input As String = "Total Cost: 103.64"
Console.WriteLine(Regex.Replace(input, pattern, replacement))
End Sub
End Module
' The example displays the following output:
' Total Cost: $103.64
MODELO DESCRIPCIÓN
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "1. Eggs 2. Bread 3. Milk 4. Coffee 5. Tea"
Dim pattern As String = "\b\d{1,2}\.\s"
For Each item As String In Regex.Split(input, pattern)
If Not String.IsNullOrEmpty(item) Then
Console.WriteLine(item)
End If
Next
End Sub
End Module
' The example displays the following output:
' Eggs
' Bread
' Milk
' Coffee
' Tea
MODELO DESCRIPCIÓN
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim matches As MatchCollection
Dim results As New List(Of String)
Dim matchposition As New List(Of Integer)
' Create a new Regex object and define the regular expression.
Dim r As New Regex("abc")
' Use the Matches method to find all matches in the input string.
matches = r.Matches("123abc4abcd")
' Enumerate the collection to retrieve all matches and positions.
For Each match As Match In matches
' Add the match string to the string array.
results.Add(match.Value)
' Record the character position where the match was found.
matchposition.Add(match.Index)
Next
' List the results.
For ctr As Integer = 0 To results.Count - 1
Console.WriteLine("'{0}' found at position {1}.", _
results(ctr), matchposition(ctr))
Next
End Sub
End Module
' The example displays the following output:
' 'abc' found at position 3.
' 'abc' found at position 7.
La coincidencia
La clase Match representa el resultado de una coincidencia de expresión regular única. Puede tener acceso a los
objetos Match de dos formas:
Recuperándolos del objeto MatchCollection devuelto por el método Regex.Matches. Para recuperar objetos
Match individuales, itere la colección utilizando una construcción foreach (en C#) o For Each ... Next (en
Visual Basic) o use la propiedad MatchCollection.Item[Int32] para recuperar un determinado objeto Match
por índice o por nombre. También puede recuperar objetos Match individuales de la colección iterando la
colección por índice, desde cero a uno menos que el número de objetos de la colección. Sin embargo, este
método no saca partido de la evaluación diferida, porque tiene acceso a la propiedad
MatchCollection.Count.
En el siguiente ejemplo se recuperan objetos Match individuales de un objeto MatchCollection iterando la
colección mediante la construcción foreach o For Each ... Next . La expresión regular simplemente
coincide con la cadena "abc" de la cadena de entrada.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "abc"
Dim input As String = "abc123abc456abc789"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("{0} found at position {1}.", _
match.Value, match.Index)
Next
End Sub
End Module
' The example displays the following output:
' abc found at position 0.
' abc found at position 6.
' abc found at position 12.
Llamando al método Regex.Match, que devuelve un objeto Match que representa la primera coincidencia
en una cadena o una parte de una cadena. Puede determinar si la coincidencia se ha encontrado
recuperando el valor de la propiedad Match.Success . Para recuperar objetos Match que representan las
coincidencias subsiguientes, llame repetidamente al método Match.NextMatch, hasta que la propiedad
Success del objeto Match devuelto sea false .
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "abc"
Dim input As String = "abc123abc456abc789"
Dim match As Match = Regex.Match(input, pattern)
Do While match.Success
Console.WriteLine("{0} found at position {1}.", _
match.Value, match.Index)
match = match.NextMatch()
Loop
End Sub
End Module
' The example displays the following output:
' abc found at position 0.
' abc found at position 6.
' abc found at position 12.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b\d+(,\d{3})*\.\d{2}\b"
Dim input As String = "16.32" + vbCrLf + "194.03" + vbCrLf + "1,903,672.08"
MODELO DESCRIPCIÓN
El patrón de reemplazo $$ $& indica que la subcadena debe ser reemplazada por un símbolo de signo de dólar
($) (el patrón $$ ), un espacio y el valor de la coincidencia (el patrón $& ).
Volver al principio
La colección de grupos
La propiedad Match.Groups devuelve un objeto GroupCollection que contiene objetos Group que representan los
grupos capturados en una coincidencia única. El primer objeto Group de la colección (en el índice 0) representa la
coincidencia completa. Cada objeto que sigue representa los resultados de un grupo de captura único.
Puede recuperar objetos Group individuales en la colección utilizando la propiedad GroupCollection.Item[String].
Puede recuperar los grupos sin nombre por su posición ordinal en la colección y recuperar grupos con nombre
por nombre o por posición ordinal. Las capturas sin nombre aparecen primero en la colección y se indizan de
izquierda a derecha en el orden en el que aparecen en el patrón de expresión regular. Las capturas con nombre se
indizan después de las capturas sin nombre, de izquierda a derecha en el orden en el que aparecen en el patrón de
expresión regular. Para determinar qué grupos numerados están disponibles en la colección devuelta para un
determinado método de coincidencia de expresión regular, puede llamar al método Regex.GetGroupNumbers de
instancia. Para determinar qué grupos con nombre están disponibles en la colección, puede llamar al método
Regex.GetGroupNames de instancia. Ambos métodos son especialmente útiles en rutinas de uso general que
analizan las coincidencias encontradas por cualquier expresión regular.
La propiedad GroupCollection.Item[String] es el indizador de la colección en C# y la propiedad predeterminada
del objeto de la colección en Visual Basic. Esto significa que se puede tener acceso a los objetos Group
individuales por índice (o por nombre, en el caso de grupos con nombre) del modo siguiente:
En el siguiente ejemplo se define una expresión regular que usa construcciones de agrupación para capturar el
mes, día y año de una fecha.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b(\w+)\s(\d{1,2}),\s(\d{4})\b"
Dim input As String = "Born: July 28, 1989"
Dim match As Match = Regex.Match(input, pattern)
If match.Success Then
For ctr As Integer = 0 To match.Groups.Count - 1
Console.WriteLine("Group {0}: {1}", ctr, match.Groups(ctr).Value)
Next
End If
End Sub
End Module
' The example displays the following output:
' Group 0: July 28, 1989
' Group 1: July
' Group 2: 28
' Group 3: 1989
MODELO DESCRIPCIÓN
Volver al principio
El grupo capturado
La clase Group representa el resultado de un único grupo de captura. La propiedad Item[String] del objeto
GroupCollection devuelto por la propiedad Match.Groups devuelve objetos de grupo que representan grupos de
captura definidos en una expresión regular. La propiedad Item[String] es el indizador (en C#) y la propiedad
predeterminada (en Visual Basic) de la clase Group. También puede recuperar miembros individuales mediante la
iteración de la colección con la construcción foreach o For Each . Para obtener un ejemplo, vea la sección
anterior.
En el siguiente ejemplo se utilizan construcciones de agrupación anidadas para capturar subcadenas en grupos. El
patrón de expresión regular (a(b))c coincide con la cadena "abc". Asigna la subcadena "ab" al primer grupo de
captura y la subcadena "b" al segundo grupo de captura.
En el siguiente ejemplo se utilizan construcciones de agrupación con nombre para capturar subcadenas de una
cadena que contiene datos en el formato "NOMBREDATOS:VALOR" que la expresión regular divide por el signo
de dos puntos (:).
MODELO DESCRIPCIÓN
Success false
Value String.Empty
Length 0
Esto se muestra en el ejemplo siguiente. En el patrón de expresión regular aaa(bbb)*ccc , se pueden buscar
coincidencias para el primer grupo de captura (la subcadena "bbb") cero o varias veces. Dado que la
cadena de entrada "aaaccc" coincide con el patrón, el grupo de captura no tiene una coincidencia.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim pattern As String = "aaa(bbb)*ccc"
Dim input As String = "aaaccc"
Dim match As Match = Regex.Match(input, pattern)
Console.WriteLine("Match value: {0}", match.Value)
If match.Groups(1).Success Then
Console.WriteLine("Group 1 value: {0}", match.Groups(1).Value)
Else
Console.WriteLine("The first capturing group has no match.")
End If
End Sub
End Module
' The example displays the following output:
' Match value: aaaccc
' The first capturing group has no match.
Los cuantificadores pueden coincidir con varias apariciones de un patrón definido por un grupo de captura.
En este caso, las propiedades Value y Length de un objeto Group solo contienen información sobre la
última subcadena capturada. Por ejemplo, la siguiente coincidencia de expresión regular coincide con una
frase única que finaliza con un punto. La expresión utiliza dos construcciones de agrupación: la primera
captura palabras individuales junto con un carácter de espacio en blanco; la segunda captura palabras
individuales. Como lo muestra el resultado del ejemplo, aunque la expresión regular logre capturar una
frase completa, el segundo grupo de captura solo captura la última palabra.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim pattern As String = "\b((\w+)\s?)+\."
Dim input As String = "This is a sentence. This is another sentence."
Dim match As Match = Regex.Match(input, pattern)
If match.Success Then
Console.WriteLine("Match: " + match.Value)
Console.WriteLine("Group 2: " + match.Groups(2).Value)
End If
End Sub
End Module
' The example displays the following output:
' Match: This is a sentence.
' Group 2: sentence
Volver al principio
La colección de capturas
El objeto Group solo contiene información sobre la última captura. Sin embargo, el conjunto completo de
capturas realizado por un grupo de captura sigue aún disponible en el objeto CaptureCollection devuelto por la
propiedad Group.Captures. Cada miembro de la colección es un objeto Capture que representa una captura
realizada por este grupo de captura, en el orden en el que se capturaron (y, por consiguiente, en el orden en el que
las cadenas capturadas coincidían de izquierda a derecha en la cadena de entrada). Puede recuperar objetos
Capture individuales de la colección de estas dos formas:
Mediante la iteración de la colección con el uso de una construcción como foreach (en C#) o For Each
(en Visual Basic).
Utilizando la propiedad CaptureCollection.Item[Int32] para recuperar un objeto específico por índice. La
propiedad Item[Int32] es la propiedad predeterminada del objeto CaptureCollection (en Visual Basic) o el
indizador (en C#).
Si no se aplica un cuantificador a un grupo de captura, el objeto CaptureCollection contiene un objeto Capture
único que es de escaso interés, porque proporciona información sobre la misma coincidencia que su objeto
Group. Si se aplica un cuantificador a un grupo de captura, el objeto CaptureCollection contiene todas las
capturas realizadas por el grupo de captura y el último miembro de la colección representa la misma captura que
el objeto Group.
Si utiliza, por ejemplo, el patrón de expresión regular ((a(b))c)+ (donde el cuantificador + indica una o varias
coincidencias) para capturar coincidencias de la cadena "abcabcabc", el objeto CaptureCollection para cada objeto
Group contiene tres miembros.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim pattern As String = "((a(b))c)+"
Dim input As STring = "abcabcabc"
En el siguiente ejemplo se utiliza la expresión regular (Abc)+ para buscar una o más ejecuciones consecutivas de
la cadena "Abc" en la cadena "XYZAbcAbcAbcXYZAbcAb". El ejemplo ilustra la forma en que se utiliza la
propiedad Group.Captures para que devuelva varios grupos de subcadenas capturadas.
int counter;
Match m;
CaptureCollection cc;
GroupCollection gc;
Volver al principio
La captura individual
La clase Capture contiene el resultado de una única captura de subexpresiones. La propiedad Capture.Value
contiene el texto coincidente y la propiedad Capture.Index indica la posición basada en cero en la cadena de
entrada en la que la comienza la subcadena coincidente.
En el siguiente ejemplo se analiza una cadena de entrada para la temperatura de las ciudades seleccionadas. Se
utiliza una coma (",") para separar una ciudad y su temperatura, y un punto y coma (";"), para separar los datos de
cada ciudad. La cadena de entrada completa representa una coincidencia única. En el patrón de expresión regular
((\w+(\s\w+)*),(\d+);)+ , que se utiliza para analizar la cadena, se asigna el nombre de la ciudad al segundo
grupo de captura y la temperatura al cuarto grupo de captura.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "Miami,78;Chicago,62;New York,67;San Francisco,59;Seattle,58;"
Dim pattern As String = "((\w+(\s\w+)*),(\d+);)+"
Dim match As Match = Regex.Match(input, pattern)
If match.Success Then
Console.WriteLine("Current temperatures:")
For ctr As Integer = 0 To match.Groups(2).Captures.Count - 1
Console.WriteLine("{0,-20} {1,3}", match.Groups(2).Captures(ctr).Value, _
match.Groups(4).Captures(ctr).Value)
Next
End If
End Sub
End Module
' The example displays the following output:
' Current temperatures:
' Miami 78
' Chicago 62
' New York 67
' San Francisco 59
' Seattle 58
MODELO DESCRIPCIÓN
(\w+(\s\w+)*) Coincide con uno o varios caracteres que se usan para formar
palabras seguidos de cero o más apariciones de un carácter
de espacio en blanco seguidos de uno o varios caracteres que
se usan para formar palabras. Este es el segundo grupo de
captura.
Vea también
System.Text.RegularExpressions
Expresiones regulares de .NET
Lenguaje de expresiones regulares: referencia rápida
Detalles del comportamiento de expresiones
regulares
20/01/2020 • 31 minutes to read • Edit Online
NOTE
Para obtener información sobre la reducción del rendimiento que causa un retroceso excesivo y sobre las maneras de crear
una expresión regular para solucionarlo, consulte Retroceso.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim greedyPattern As String = ".+(\d+)\."
Dim lazyPattern As String = ".+?(\d+)\."
Dim input As String = "This sentence ends with the number 107325."
Dim match As Match
Las versiones expansiva y diferida de esta expresión regular se definen como se muestra en la tabla
siguiente:
MODELO DESCRIPCIÓN
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b[A-Z]+\b(?=\P{P})"
Dim input As String = "If so, what comes next?"
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
Console.WriteLine(match.Value)
Next
End Sub
End Module
' The example displays the following output:
' If
' what
' comes
MODELO DESCRIPCIÓN
Para obtener más información sobre las aserciones de búsqueda anticipada positiva, consulte
Construcciones de agrupamiento.
Búsqueda anticipada negativa: (?! subexpresión ) . Esta característica permite coincidir con una expresión
solo si no se produce una coincidencia con una subexpresión. Esto es especialmente eficaz para restringir
una búsqueda, ya que a menudo resulta más sencillo proporcionar una expresión para un caso que se debe
eliminar, en lugar de una expresión para los casos que se deben incluir. Por ejemplo, es difícil escribir una
expresión para buscar palabras que no comienzan por "non". En el ejemplo siguiente se usa la búsqueda
anticipada negativa para excluirlas.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b(?!non)\w+\b"
Dim input As String = "Nonsense is not always non-functional."
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
Console.WriteLine(match.Value)
Next
End Sub
End Module
' The example displays the following output:
' is
' not
' always
' functional
MODELO DESCRIPCIÓN
Para obtener más información sobre las aserciones de búsqueda anticipada negativa, consulte
Construcciones de agrupamiento.
Evaluación condicional: (?( expresión ) sí | no ) y (?( nombre ) sí | no ) , donde expresión es una
subexpresión que debe coincidir, nombre es el nombre de un grupo de capturas, sí es la cadena que debe
coincidir si expresión coincide o nombre es un grupo capturado válido y no vacío, y no es la subexpresión
que debe coincidir si expresión no coincide o si nombre no es un grupo capturado válido y no vacío. Esta
característica permite al motor buscar mediante más de un patrón alternativo, según el resultado de una
búsqueda de coincidencia de subexpresión anterior o el resultado de una aserción de ancho cero. Esto
posibilita una forma más eficaz de referencia inversa que permite, por ejemplo, coincidir con una
subexpresión en función de si se produjo una coincidiencia con una subexpresión anterior. La expresión
regular del ejemplo siguiente coincide con párrafos que están pensados tanto para un uso público como
interno. Los párrafos destinados únicamente al uso interno empiezan con una etiqueta <PRIVATE> . El
patrón de expresión regular ^(?<Pvt>\<PRIVATE\>\s)?(?(Pvt)((\w+\p{P}?\s)+)|((\w+\p{P}?\s)+))\r?$ usa la
evaluación condicional para asignar el contenido de los párrafos pensados para el uso público y para el uso
interno a grupos de capturas independientes. Después, estos párrafos se pueden tratar de forma diferente.
using System;
using System.Text.RegularExpressions;
Console.WriteLine("Private Document:");
Console.WriteLine(privateDocument);
Console.WriteLine("Public Document:");
Console.WriteLine(publicDocument);
}
}
// The example displays the following output:
// Private Document:
// This is not for public consumption.
// But this is for public consumption.
// Again, this is confidential.
//
// Public Document:
// But this is for public consumption.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "<PRIVATE> This is not for public consumption." + vbCrLf + _
"But this is for public consumption." + vbCrLf + _
"<PRIVATE> Again, this is confidential." + vbCrLf
Dim pattern As String = "^(?<Pvt>\<PRIVATE\>\s)?(?(Pvt)((\w+\p{P}?\s)+)|((\w+\p{P}?\s)+))\r?$"
Dim publicDocument As String = Nothing
Dim privateDocument As String = Nothing
Console.WriteLine("Private Document:")
Console.WriteLine(privateDocument)
Console.WriteLine("Public Document:")
Console.WriteLine(publicDocument)
End Sub
End Module
' The example displays the following output:
' Private Document:
' This is not for public consumption.
' But this is for public consumption.
' Again, this is confidential.
'
' Public Document:
' But this is for public consumption.
MODELO DESCRIPCIÓN
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim inputs() As String = { "aaaaa", "aaaaab" }
Dim backtrackingPattern As String = "(a+)\w"
Dim match As Match
La expresión regular ((?>a+))\w impide este comportamiento. Dado que todos los caracteres "a"
consecutivos se buscan sin retroceso, el primer grupo de capturas incluye todos los caracteres "a"
consecutivos. Si los caracteres "a" no van seguidos de al menos otro carácter que no sea "a", se produce un
error de coincidencia.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim inputs() As String = { "aaaaa", "aaaaab" }
Dim nonbacktrackingPattern As String = "((?>a+))\w"
Dim match As Match
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim greedyPattern As String = ".+(\d+)\."
Dim input As String = "This sentence ends with the number 107325."
Dim match As Match
Para obtener más información sobre la búsqueda de coincidencias de derecha a izquierda, consulte
Opciones de expresiones regulares.
Búsqueda tardía positiva y negativa: (?<= subexpresión ) para la búsqueda tardía positiva y (?<!
subexpresión ) para la búsqueda tardía negativa. Esta característica es parecida a la búsqueda anticipada,
que se describe anteriormente en este tema. Dado que el motor de expresiones regulares permite una
búsqueda de coincidencias completa de derecha a izquierda, las expresiones regulares permiten búsquedas
tardías sin restricciones. La búsqueda tardía positiva y negativa también se puede usar para evitar anidar
los cuantificadores cuando la subexpresión anidada es un superconjunto de una expresión exterior. Las
expresiones regulares con cuantificadores anidados suelen ofrecer un rendimiento bajo. Por ejemplo, en el
ejemplo siguiente se comprueba que una cadena empieza y acaba con un carácter alfanumérico y que
cualquier otro carácter de la cadena es de un subconjunto más grande. Forma parte de la expresión regular
usada para validar direcciones de correo electrónico. Para obtener más información, vea Procedimiento:
Comprobación de que las cadenas están en un formato de correo electrónico válido.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim inputs() As String = { "jack.sprat", "dog#", "dog#1", "me.myself",
"me.myself!" }
Dim pattern As String = "^[A-Z0-9]([-!#$%&'.*+/=?^`{}|~\w])*(?<=[A-Z0-9])$"
For Each input As String In inputs
If Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase) Then
Console.WriteLine("{0}: Valid", input)
Else
Console.WriteLine("{0}: Invalid", input)
End If
Next
End Sub
End Module
' The example displays the following output:
' jack.sprat: Valid
' dog#: Invalid
' dog#1: Valid
' me.myself: Valid
' me.myself!: Invalid
MODELO DESCRIPCIÓN
Para obtener más información sobre la búsqueda tardía positiva y negativa, consulte Construcciones de
agrupamiento.
Artículos relacionados
TITLE DESCRIPCIÓN
Expresiones regulares de .NET Framework Proporciona información general sobre el aspecto del lenguaje
de programación de expresiones regulares.
Modelo de objetos de expresión regular Proporciona información y ejemplos de código que muestran
cómo usar las clases de expresiones regulares.
Lenguaje de expresiones regulares: referencia rápida Ofrece información sobre el conjunto de caracteres,
operadores y construcciones que se pueden usar para definir
expresiones regulares.
Referencia
System.Text.RegularExpressions
Retroceso en expresiones regulares
23/01/2020 • 36 minutes to read • Edit Online
NOTE
En general, un motor NFA (autómata finito no determinista), como el motor de expresiones regulares de .NET, se encarga
de crear expresiones regulares eficaces y rápidas para el desarrollador.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim input As String = "needing a reed"
Dim pattern As String = "e{2}\w\b"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("{0} found at position {1}", _
match.Value, match.Index)
Next
End Sub
End Module
' The example displays the following output:
' eed found at position 11
Aunque esta expresión regular incluye el cuantificador {2} , se evalúa de manera lineal. El motor de
expresiones regulares no retrocede porque {2} no es un cuantificador opcional, ya que especifica un número
exacto y no un número variable de veces que la subexpresión anterior debe coincidir. Como resultado, el motor
de expresiones regulares intenta hacer coincidir el patrón de expresión regular con la cadena de entrada como
se muestra en la tabla siguiente.
using System;
using System.Text.RegularExpressions;
Module Example
Public Sub Main()
Dim input As String = "Essential services are provided by regular expressions."
Dim pattern As String = ".*(es)"
Dim m As Match = Regex.Match(input, pattern, RegexOptions.IgnoreCase)
If m.Success Then
Console.WriteLine("'{0}' found at position {1}", _
m.Value, m.Index)
Console.WriteLine("'es' found at position {0}", _
m.Groups(1).Index)
End If
End Sub
End Module
' 'Essential services are provided by regular expres' found at position 0
' 'es' found at position 47
Imports System.Diagnostics
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "^(a+)+$"
Dim inputs() As String = { "aaaaaa", "aaaaa!" }
Dim rgx As New Regex(pattern)
Dim sw As Stopwatch
Como muestra el resultado del ejemplo, el motor de expresiones regulares tardó en descubrir que una cadena
de entrada no coincidía con el patrón aproximadamente el doble que en identificar una cadena coincidente. Esto
se debe a que una coincidencia infructuosa siempre representa un escenario de caso peor. El motor de
expresiones regulares debe usar la expresión regular para seguir todas las rutas posibles a través de los datos
antes de poder concluir que la coincidencia no es correcta y los paréntesis anidados crean muchas rutas de
acceso adicionales a través de los datos. El motor de expresiones regulares concluye que la segunda cadena no
coincide con el patrón; para ello, hace lo siguiente:
Comprueba que está al principio de la cadena y, a continuación, busca una coincidencia de los cinco
primeros caracteres de la cadena con el patrón a+ . A continuación, determina que no hay ningún grupo
adicional de caracteres "a" en la cadena. Por último, comprueba que está al final de la cadena. Como en la
cadena queda un carácter adicional, la coincidencia produce un error. Esta coincidencia errónea necesita 9
comparaciones. El motor de expresiones regulares también guarda información de estado de las
coincidencias de "a" (que llamaremos coincidencia 1), "aa" (coincidencia 2), "aaa" (coincidencia 3) y "aaaa"
(coincidencia 4).
Vuelve a la coincidencia 4 guardada previamente. Determina que hay un carácter "a" adicional para
asignar a un grupo capturado adicional. Por último, comprueba que está al final de la cadena. Como en la
cadena queda un carácter adicional, la coincidencia produce un error. Esta coincidencia errónea necesita 4
comparaciones. Hasta ahora, se han realizado un total de 13 comparaciones.
Vuelve a la coincidencia 3 guardada previamente. Determina que hay dos caracteres "a" adicionales para
asignar a un grupo capturado adicional. Sin embargo, se produce un error en la prueba de fin de cadena.
Vuelva a la coincidencia 3 e intenta hacer coincidir los dos caracteres "a" adicionales en dos grupos
capturados adicionales. Se sigue produciendo un error en la prueba de fin de cadena. Estas coincidencias
con error necesitan 12 comparaciones. Hasta ahora, se ha realizado un total de 25 comparaciones.
La comparación de la cadena de entrada con la expresión regular continúa de esta manera hasta que el motor
de expresiones regulares ha intentado todas las posibles combinaciones de coincidencias y, a continuación,
concluye que no hay ninguna coincidencia. Debido a los cuantificadores anidados, esta comparación es O (2n ) o
una operación exponencial, donde n es el número de caracteres de la cadena de entrada. Esto significa que, en el
peor de los casos, una cadena de entrada de 30 caracteres necesita aproximadamente 1.073.741.824
comparaciones y una cadena de entrada de 40 caracteres necesita aproximadamente 1.099.511.627.776
comparaciones. Si usa cadenas de estas longitudes o incluso mayores, los métodos de expresión regular pueden
tardar mucho tiempo en completarse cuando procesan datos de entrada que no coinciden con el patrón de
expresión regular.
Controlar el retroceso
El retroceso permite crear expresiones regulares eficaces y flexibles. Sin embargo, como se ha mostrado en la
sección anterior, estas ventajas pueden conllevar un bajo rendimiento inaceptable. Para evitar el retroceso
excesivo, se debe definir un intervalo de tiempo de espera cuando se instancie un objeto Regex o se llame a un
método estático de coincidencia de expresión regular. Esta técnica se analiza en la sección siguiente. Además,
.NET admite tres elementos del lenguaje de expresiones regulares que limitan o suprimen el retroceso y que
admiten expresiones regulares complejas con poca o ninguna reducción del rendimiento: subexpresiones sin
retroceso, aserciones de búsqueda tardía y aserciones de búsqueda anticipada. Para obtener más información
sobre cada elemento del lenguaje, vea Construcciones de agrupamiento.
Definición de un intervalo de tiempo de espera
A partir de .NET Framework 4.5, se puede establecer un valor de tiempo de espera que representa el intervalo
más largo en el que el motor de expresión regular buscará una coincidencia única antes de abandonar el intento
y generar una excepción RegexMatchTimeoutException. El intervalo de tiempo de espera se especifica al
proporcionar un valor TimeSpan al constructor Regex.Regex(String, RegexOptions, TimeSpan) para las
expresiones regulares de instancias. Además, cada método estático de coincidencia de patrones tiene una
sobrecarga con un parámetro TimeSpan que permite especificar un valor de tiempo de espera. De forma
predeterminada, el intervalo de tiempo de espera se establece en Regex.InfiniteMatchTimeout y el motor de
expresiones regulares no agota dicho tiempo.
IMPORTANT
Recomendamos que se establezca siempre un intervalo de tiempo de espera si la expresión regular se basa en el
retroceso.
Una excepción RegexMatchTimeoutException indica que el motor de expresiones regulares no pudo encontrar
una coincidencia en el intervalo de tiempo de espera especificado, pero no indica por qué se produjo la
excepción. La razón puede ser un retroceso excesivo, aunque también es posible que el intervalo de tiempo de
espera establecido fuera demasiado bajo, dada la carga del sistema en el momento en que se produjo la
excepción. Cuando se controla la excepción, se puede elegir entre abandonar otras coincidencias con la cadena
de entrada o incrementar el intervalo de tiempo de espera y reintentar la operación de coincidencia.
Por ejemplo, el código siguiente llama al constructor Regex.Regex(String, RegexOptions, TimeSpan) para crear
instancias de un objeto Regex con un valor de tiempo de espera de un segundo. El patrón de expresión regular
(a+)+$ , que coincide con una o más secuencias de uno o varios caracteres "a" al final de una línea, está sujeto a
un retroceso excesivo. Si se produce una excepción RegexMatchTimeoutException , el ejemplo incrementa el
valor de tiempo de espera hasta un intervalo máximo de tres segundos. Después, abandona el intento de
coincidir con el patrón.
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Security;
using System.Text.RegularExpressions;
using System.Threading;
Imports System.ComponentModel
Imports System.Diagnostics
Imports System.Security
Imports System.Text.RegularExpressions
Imports System.Threading
Module Example
Const MaxTimeoutInSeconds As Integer = 3
Console.WriteLine("With backtracking:");
string backPattern = "^(([0-9a-fA-F]{1,4}:)*([0-9a-fA-F]{1,4}))*(::)$";
sw = Stopwatch.StartNew();
matched = Regex.IsMatch(input, backPattern);
sw.Stop();
Console.WriteLine("Match: {0} in {1}", Regex.IsMatch(input, backPattern), sw.Elapsed);
Console.WriteLine();
Console.WriteLine("Without backtracking:");
string noBackPattern = "^((?>[0-9a-fA-F]{1,4}:)*(?>[0-9a-fA-F]{1,4}))*(::)$";
sw = Stopwatch.StartNew();
matched = Regex.IsMatch(input, noBackPattern);
sw.Stop();
Console.WriteLine("Match: {0} in {1}", Regex.IsMatch(input, noBackPattern), sw.Elapsed);
}
}
// The example displays output like the following:
// With backtracking:
// Match: False in 00:00:27.4282019
//
// Without backtracking:
// Match: False in 00:00:00.0001391
Imports System.Diagnostics
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "b51:4:1DB:9EE1:5:27d60:f44:D4:cd:E:5:0A5:4a:D24:41Ad:"
Dim matched As Boolean
Dim sw As Stopwatch
Console.WriteLine("With backtracking:")
Dim backPattern As String = "^(([0-9a-fA-F]{1,4}:)*([0-9a-fA-F]{1,4}))*(::)$"
sw = Stopwatch.StartNew()
matched = Regex.IsMatch(input, backPattern)
sw.Stop()
Console.WriteLine("Match: {0} in {1}", Regex.IsMatch(input, backPattern), sw.Elapsed)
Console.WriteLine()
Console.WriteLine("Without backtracking:")
Dim noBackPattern As String = "^((?>[0-9a-fA-F]{1,4}:)*(?>[0-9a-fA-F]{1,4}))*(::)$"
sw = Stopwatch.StartNew()
matched = Regex.IsMatch(input, noBackPattern)
sw.Stop()
Console.WriteLine("Match: {0} in {1}", Regex.IsMatch(input, noBackPattern), sw.Elapsed)
End Sub
End Module
' The example displays the following output:
' With backtracking:
' Match: False in 00:00:27.4282019
'
' Without backtracking:
' Match: False in 00:00:00.0001391
Module Example
Public Sub Main()
Dim sw As Stopwatch
Dim input As String = "test@contoso.com"
Dim result As Boolean
MODELO DESCRIPCIÓN
MODELO DESCRIPCIÓN
using System;
using System.Diagnostics;
using System.Text.RegularExpressions;
Imports System.Diagnostics
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "aaaaaaaaaaaaaaaaaaaaaa."
Dim result As Boolean
Dim sw As Stopwatch
MODELO DESCRIPCIÓN
Vea también
Expresiones regulares de .NET
Lenguaje de expresiones regulares: referencia rápida
Cuantificadores
Construcciones de alternancia
Construcciones de agrupamiento
Compilar y volver a utilizar en expresiones regulares
04/11/2019 • 5 minutes to read • Edit Online
Puede optimizar el rendimiento de aplicaciones que usan en gran medida las expresiones regulares al comprender
cómo compila expresiones el motor de expresiones regulares y cómo se almacenan en caché las expresiones
regulares. En este tema, se describen la compilación y el almacenamiento en caché.
Vea también
Expresiones regulares de .NET
Seguridad para subprocesos en expresiones regulares
04/11/2019 • 2 minutes to read • Edit Online
La clase Regex es en sí misma segura para subprocesos e inmutable (de solo lectura). Es decir, se pueden crear
objetos Regex en cualquier subproceso y compartirlos entre varios subprocesos; los métodos de coincidencia
pueden llamarse desde cualquier subproceso y no modifican nunca el estado global.
Pero los objetos de resultado (Match y MatchCollection) que devuelve Regex deben usarse en un único
subproceso. Aunque muchos de estos objetos son lógicamente inmutables, sus implementaciones pueden retrasar
el cálculo de algunos resultados para mejorar el rendimiento y, en consecuencia, los llamadores deben serializar el
acceso a ellos.
Si es necesario compartir objetos de resultado de Regex en varios subprocesos, estos objetos se pueden convertir
en instancias seguras para subprocesos llamando a sus métodos sincronizados. A excepción de los enumeradores,
todas las clases de expresiones regulares son seguras para subprocesos o pueden convertirse en objetos seguros
para subprocesos mediante un método sincronizado.
Los enumeradores son la única excepción. Las aplicaciones debe serializar las llamadas a enumeradores de
colecciones. La regla es que, si una colección puede enumerarse simultáneamente en más de un subproceso, se
deben sincronizar los métodos de enumerador en el objeto raíz de la colección que recorre el enumerador.
Vea también
Expresiones regulares de .NET
Ejemplos de expresiones regulares
04/11/2019 • 2 minutes to read • Edit Online
Esta sección contiene ejemplos de código que ilustran el uso de expresiones regulares en aplicaciones comunes.
NOTE
El espacio de nombres System.Web.RegularExpressions contiene un número de objetos de expresión regular que
implementan modelos de expresión regular predefinidos para el análisis de cadenas a partir de documentos HTML, XML y
ASP.NET. Por ejemplo, la clase TagRegex identifica las etiquetas de inicio en una cadena y la clase CommentRegex identifica
los comentarios de ASP.NET en una cadena.
En esta sección
Ejemplo: Buscar etiquetas HREF
Ofrece un ejemplo en el que se busca una cadena de entrada y se muestran todos los valores href="…" y sus
ubicaciones en la cadena.
Ejemplo: Cambio de formatos de fecha
Ofrece un ejemplo en el que se reemplazan las fechas en formato mm/dd/aa por fechas en el formato dd-mm-aa.
Cómo: Extraer un protocolo y un número de puerto de una dirección URL
Ofrece un ejemplo en el que se extrae un protocolo y número de puerto de una cadena que contiene una dirección
URL. Por ejemplo, "http://www.contoso.com:8080/letters/readme.html" devuelve "http:8080".
Cómo: Quitar caracteres no válidos de una cadena
Ofrece un ejemplo en el que se eliminan los caracteres no alfanuméricos no válidos de una cadena.
Cómo: Comprobación de que las cadenas están en un formato de correo electrónico válido
Proporciona un ejemplo que comprueba si una cadena tiene un formato de correo electrónico válido.
Referencia
System.Text.RegularExpressions
Ofrece información de referencia de la biblioteca de clases para el espacio de nombres
System.Text.RegularExpressions de .NET.
Secciones relacionadas
Expresiones regulares de .NET
Proporciona información general sobre el aspecto del lenguaje de programación de expresiones regulares.
Modelo de objetos de expresión regular
Describe las clases de expresión regular contenidas en el espacio de nombres System.Text.RegularExpression y
proporciona ejemplos de su uso.
Detalles del comportamiento de expresiones regulares
Proporciona información sobre las funcionalidades y el comportamiento de las expresiones regulares de .NET.
Lenguaje de expresiones regulares: referencia rápida
Ofrece información sobre el conjunto de caracteres, operadores y construcciones que se pueden utilizar para
definir expresiones regulares.
Ejemplo de expresiones regulares: Buscar etiquetas
HREF
04/11/2019 • 6 minutes to read • Edit Online
En el ejemplo siguiente se busca una cadena de entrada y se muestran todos los valores href="…" y sus
ubicaciones en la cadena.
El objeto Regex
Dado que el método DumpHRefs puede llamarse varias veces desde el código de usuario, usa el método static (
Shared en Visual Basic) Regex.Match( String, String, RegexOptions). Esto permite que el motor de expresiones
regulares almacene en caché la expresión regular y evita la sobrecarga que se produciría al crear instancias de un
nuevo objeto Regex cada vez que se llamara al método. Después, se usa un objeto Match para iterar todas las
coincidencias de la cadena.
try
{
m = Regex.Match(inputString, HRefPattern,
RegexOptions.IgnoreCase | RegexOptions.Compiled,
TimeSpan.FromSeconds(1));
while (m.Success)
{
Console.WriteLine("Found href " + m.Groups[1] + " at "
+ m.Groups[1].Index);
m = m.NextMatch();
}
}
catch (RegexMatchTimeoutException)
{
Console.WriteLine("The matching operation timed out.");
}
}
Try
m = Regex.Match(inputString, HRefPattern, _
RegexOptions.IgnoreCase Or RegexOptions.Compiled,
TimeSpan.FromSeconds(1))
Do While m.Success
Console.WriteLine("Found href {0} at {1}.", _
m.Groups(1), m.Groups(1).Index)
m = m.NextMatch()
Loop
Catch e As RegexMatchTimeoutException
Console.WriteLine("The matching operation timed out.")
End Try
End Sub
En el ejemplo siguiente se muestra la llamada al método DumpHRefs .
MODELO DESCRIPCIÓN
Vea también
Expresiones regulares de .NET
Ejemplo de expresiones regulares: Cambiar formatos
de fecha
04/11/2019 • 2 minutes to read • Edit Online
En el siguiente ejemplo de código, se usa el método Regex.Replace para reemplazar las fechas con el formato
mm/dd/aa con fechas que tienen el formato dd-mm-aa.
Ejemplo
static string MDYToDMY(string input)
{
try {
return Regex.Replace(input,
@"\b(?<month>\d{1,2})/(?<day>\d{1,2})/(?<year>\d{2,4})\b",
"${day}-${month}-${year}", RegexOptions.None,
TimeSpan.FromMilliseconds(150));
}
catch (RegexMatchTimeoutException) {
return input;
}
}
El código siguiente muestra cómo se puede llamar al método MDYToDMY en una aplicación.
using System;
using System.Globalization;
using System.Text.RegularExpressions;
Imports System.Globalization
Imports System.Text.RegularExpressions
Module DateFormatReplacement
Public Sub Main()
Dim dateString As String = Date.Today.ToString("d", _
DateTimeFormatInfo.InvariantInfo)
Dim resultString As String = MDYToDMY(dateString)
Console.WriteLine("Converted {0} to {1}.", dateString, resultString)
End Sub
Comentarios
El patrón de la expresión regular \b(?<month>\d{1,2})/(?<day>\d{1,2})/(?<year>\d{2,4})\b se interpreta como se
muestra en la tabla siguiente.
MODELO DESCRIPCIÓN
MODELO DESCRIPCIÓN
- Agregar un guión.
- Agregar un guión.
Vea también
Expresiones regulares de .NET
Procedimiento para extraer un protocolo y un
número de puerto de una dirección URL
04/11/2019 • 2 minutes to read • Edit Online
En los siguientes ejemplos se extrae un protocolo y un número de puerto de una dirección URL.
Ejemplo
El ejemplo usa el método Match.Result para devolver el protocolo seguido de dos puntos y del número de puerto.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim url As String = "http://www.contoso.com:8080/letters/readme.html"
Dim r As New Regex("^(?<proto>\w+)://[^/]+?(?<port>:\d+)?/",
RegexOptions.None, TimeSpan.FromMilliseconds(150))
MODELO DESCRIPCIÓN
(?<port>:\d+)? Buscar una coincidencia con cero o una aparición de una coma
seguida de uno o más caracteres decimales. Asigne a este
grupo el nombre port .
El método Match.Result expande la secuencia de reemplazo ${proto}${port} , que concatena el valor de los dos
grupos con nombre capturados en el patrón de expresión regular. Resulta cómodo concatenar explícitamente las
cadenas recuperadas del objeto de la colección devueltas por la propiedad Match.Groups.
El ejemplo usa el método Match.Result con dos sustituciones, ${proto} y ${port} , para incluir los grupos
capturados en la cadena de salida. En su lugar, puede recuperar los grupos capturados del objeto de coincidencia
GroupCollection, como se muestra en el siguiente código.
Console.WriteLine(m.Groups["proto"].Value + m.Groups["port"].Value);
Console.WriteLine(m.Groups("proto").Value + m.Groups("port").Value)
Vea también
Expresiones regulares de .NET
Procedimiento para quitar caracteres no válidos de
una cadena
04/11/2019 • 2 minutes to read • Edit Online
En el ejemplo siguiente se usa el método estático Regex.Replace para quitar caracteres no válidos de una cadena.
Ejemplo
Puede usar el método CleanInput definido en este ejemplo para quitar caracteres potencialmente perjudiciales
que se hayan escrito en un campo de texto que acepta datos del usuario. En este caso, CleanInput elimina todos
los caracteres no alfanuméricos excepto puntos (.), símbolos de arroba (@) y guiones (-), y devuelve la cadena
restante. Pero puede modificar el patrón de expresión regular para que elimine todos los caracteres que no deban
incluirse en una cadena de entrada.
using System;
using System.Text.RegularExpressions;
Imports System.Text.RegularExpressions
Module Example
Function CleanInput(strIn As String) As String
' Replace invalid characters with empty strings.
Try
Return Regex.Replace(strIn, "[^\w\.@-]", "")
' If we timeout when replacing invalid characters,
' we should return String.Empty.
Catch e As RegexMatchTimeoutException
Return String.Empty
End Try
End Function
End Module
El patrón de expresión regular [^\w\.@-] coincide con cualquier carácter que no sea un carácter de palabra, un
punto, un símbolo @ o un guion. Un carácter de palabra es cualquier letra, dígito decimal o conector de
puntuación, como un guion bajo. Cualquier carácter que coincida con este patrón se sustituye por String.Empty,
que es la cadena definida por el modelo de reemplazo. Para permitir caracteres adicionales en la entrada de
usuario, agregue esos caracteres a la clase de caracteres en el patrón de la expresión regular. Por ejemplo, el
patrón de expresión regular [^\w\.@-\\%] también permite un símbolo de porcentaje y una barra diagonal inversa
en la cadena de entrada.
Vea también
Expresiones regulares de .NET
Cómo comprobar si las cadenas tienen un formato
de correo electrónico válido
25/11/2019 • 11 minutes to read • Edit Online
En el ejemplo siguiente se usa una expresión regular para comprobar que una cadena tiene un formato de correo
electrónico válido.
Ejemplo
En el ejemplo se define un método IsValidEmail , que devuelve true si la cadena contiene una dirección de
correo electrónico válida y false si no es válida, pero no realiza ninguna otra acción.
Para comprobar que la dirección de correo electrónico es válida, el método IsValidEmail llama al método
Regex.Replace(String, String, MatchEvaluator) con el patrón de expresión regular (@)(.+)$ para separar el
nombre de dominio de la dirección de correo electrónico. El tercer parámetro es un delegado MatchEvaluator
que representa el método que procesa y reemplaza el texto coincidente. El patrón de expresión regular se
interpreta de esta manera:
MODELO DESCRIPCIÓN
El nombre de dominio junto con el carácter @ se pasa al método DomainMapper , que usa la clase IdnMapping
para convertir los caracteres Unicode fuera del intervalo de caracteres EE.UU. - ASCII a Punycode. El método
también establece la marca invalid en True si el método IdnMapping.GetAscii detecta cualquier carácter no
válido en el nombre del dominio. El método devuelve el nombre de dominio Punycode precedido por el símbolo
@ al método IsValidEmail .
A continuación, el método IsValidEmail llama al método Regex.IsMatch(String, String) para comprobar que la
dirección se ajusta a un patrón de expresión regular.
Tenga en cuenta que el método IsValidEmail no realiza la autenticación para validar la dirección de correo
electrónico. Se limita a determinar si su formato es válido para una dirección de correo electrónico. Asimismo, el
método IsValidEmail no comprueba que el nombre del dominio de nivel superior sea un nombre válido
enumerado en la base de datos de la zona de la raíz IANA, lo cual requeriría una operación de búsqueda. En su
lugar, la expresión regular comprueba simplemente que el nombre de dominio de nivel superior conste de entre
dos y veinticuatro caracteres ASCII alfanuméricos, que los caracteres primero y último sean alfanuméricos y que
el resto de caracteres sean alfanuméricos o un guión (-).
using System;
using System.Globalization;
using System.Text.RegularExpressions;
try
{
// Normalize the domain
email = Regex.Replace(email, @"(@)(.+)$", DomainMapper,
RegexOptions.None, TimeSpan.FromMilliseconds(200));
try
{
return Regex.IsMatch(email,
@"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-
z])@))" +
@"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-0-9a-z]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}
[a-z0-9]))$",
RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250));
}
catch (RegexMatchTimeoutException)
{
return false;
}
}
}
Imports System.Globalization
Imports System.Text.RegularExpressions
End Function
Catch e As RegexMatchTimeoutException
Return False
Catch e As ArgumentException
Return False
End Try
Try
Return Regex.IsMatch(email,
"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\
{\}\|~\w])*)(?<=[0-9a-z])@))" +
"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-0-9a-z]*[0-9a-z]*\.)+[a-z0-9]
[\-a-z0-9]{0,22}[a-z0-9]))$",
RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250))
Catch e As RegexMatchTimeoutException
Return False
End Try
End Function
End Class
Compilar el código
Los métodos IsValidEmail y DomainMapper pueden estar incluidos en una biblioteca de métodos de la utilidad de
expresiones regulares o pueden incluirse como métodos estáticos o de instancia privados en la clase de
aplicación.
También puede usar el método Regex.CompileToAssembly para incluir esta expresión regular en una biblioteca
de expresiones regulares.
Si se utilizan en una biblioteca de expresiones regulares, puede llamarlos utilizando código como el siguiente:
class Program
{
static void Main(string[] args)
{
string[] emailAddresses = { "david.jones@proseware.com", "d.j@server1.proseware.com",
"jones@ms1.proseware.com", "j.@server1.proseware.com",
"j@proseware.com9", "js#internal@proseware.com",
"j_9@[129.126.118.1]", "j..s@proseware.com",
"js*@proseware.com", "js@proseware..com",
"js@proseware.com9", "j.s@server1.proseware.com",
"\"j\\\"s\\\"\"@proseware.com", "js@contoso.中国" };
Console.ReadKey();
}
}
// The example displays the following output:
// Valid: david.jones@proseware.com
// Valid: d.j@server1.proseware.com
// Valid: jones@ms1.proseware.com
// Invalid: j.@server1.proseware.com
// Valid: j@proseware.com9
// Valid: js#internal@proseware.com
// Valid: j_9@[129.126.118.1]
// Invalid: j..s@proseware.com
// Invalid: js*@proseware.com
// Invalid: js@proseware..com
// Valid: js@proseware.com9
// Valid: j.s@server1.proseware.com
// Valid: "j\"s\""@proseware.com
// Valid: js@contoso.中国
Public Class Application
Public Shared Sub Main()
Dim emailAddresses() As String = {"david.jones@proseware.com", "d.j@server1.proseware.com",
"jones@ms1.proseware.com", "j.@server1.proseware.com",
"j@proseware.com9", "js#internal@proseware.com",
"j_9@[129.126.118.1]", "j..s@proseware.com",
"js*@proseware.com", "js@proseware..com",
"js@proseware.com9", "j.s@server1.proseware.com",
"""j\""s\""""@proseware.com", "js@contoso.中国"}
Vea también
Expresiones regulares de .NET Framework
Codificación de caracteres de .NET
13/01/2020 • 69 minutes to read • Edit Online
Los caracteres son entidades abstractas que se pueden representar de muchas maneras diferentes. Una
codificación de caracteres es un sistema que empareja cada carácter de un juego de caracteres compatible con
algún valor que representa ese carácter. Por ejemplo, el código Morse es una codificación de caracteres que
empareja cada carácter del alfabeto latino con un patrón de puntos y guiones que son adecuados para la
transmisión a través de las líneas de telégrafo. Una codificación de caracteres para los equipos empareja cada
carácter de un juego de caracteres compatible con un valor numérico que representa ese carácter. Una codificación
de caracteres tiene dos componentes distintos:
Un codificador, que traduce una secuencia de caracteres en una secuencia de valores numéricos (bytes).
Un descodificador, que traduce una secuencia de bytes en una secuencia de caracteres.
La codificación de caracteres describe las reglas por las que funcionan un codificador y un descodificador. Por
ejemplo, la clase UTF8Encoding describe las reglas para codificar y descodificar del Formato de transformación
Unicode de 8 bits (UTF -8), que usa de uno a cuatro bytes para representar un único carácter Unicode. La
codificación y la descodificación también pueden incluir validación. Por ejemplo, la clase UnicodeEncoding
comprueba todos los suplentes para asegurarse de que constituyen pares suplentes válidos. (Un par suplente
consta de un carácter con un punto de código que va de U+D800 a U+DBFF, seguido de un carácter con un punto
de código que va de U+DC00 a U+DFFF.) Una estrategia de reserva determina cómo trata un codificador los
caracteres no válidos o cómo trata un descodificador los bytes no válidos.
WARNING
Las clases de codificación de .NET proporcionan una manera de almacenar y convertir datos de caracteres. No se deben usar
para almacenar datos binarios en formato de cadena. Dependiendo de la codificación empleada, la conversión de datos
binarios al formato de cadena con las clases de codificación puede presentar un comportamiento inesperado y mostrar datos
inexactos o dañados. Para convertir datos binarios en un formato de cadena, use el método Convert.ToBase64String .
.NET usa la codificación UTF -16 (representada por la clase UnicodeEncoding) para representar caracteres y
cadenas. Las aplicaciones cuyo destino es Common Language Runtime usan descodificadores para asignar
representaciones de caracteres Unicode admitidas por Common Language Runtime a otros esquemas de
codificación. Usan descodificadores para asignar caracteres de codificaciones no Unicode a Unicode.
Este tema consta de las siguientes secciones:
Codificaciones de .NET
Seleccionar una clase de codificación
Usar un objeto de codificación
Elegir una estrategia de reinterpretación
Implementing a Custom Fallback Strategy
Codificaciones de .NET
Todas las clases de codificación de caracteres de .NET heredan de la clase System.Text.Encoding, que es una clase
abstracta que define la funcionalidad común a todas las codificaciones de caracteres. Para acceder a los objetos
individuales de codificación implementados en .NET, haga lo siguiente:
Use las propiedades estáticas de la clase Encoding, que devuelven objetos que representan las
codificaciones de caracteres estándar disponibles en .NET (ASCII, UTF -7, UTF -8, UTF -16 y UTF -32). Por
ejemplo, la propiedad Encoding.Unicode devuelve un objeto UnicodeEncoding : Cada objeto usa la reserva
de reemplazo para controlar las cadenas que no puede codificar y los bytes que no puede descodificar. (Para
obtener más información, vea la sección Replacement Fallback ).
Llame al constructor de clase de la codificación. Se pueden crear instancias de los objetos para las
codificaciones ASCII, UTF -7, UTF -8, UTF -16 y UTF -32 de esta manera. De forma predeterminada, cada
objeto usa la reserva de reemplazo para controlar las cadenas que no puede codificar y los bytes que no
puede descodificar, pero puede especificar que se debe producir una excepción en su lugar. (Para obtener
más información, vea las secciones Replacement Fallback y Exception Fallback ).
Llame al constructor Encoding.Encoding(Int32) y pásele un entero que represente la codificación. Los
objetos de codificación estándar usan la reserva de reemplazo, y los objetos de codificación para la página
de códigos y el juego de caracteres de doble byte (DBCS ) usan el retroceso de ajuste perfecto para controlar
las cadenas que no pueden codificar y los bytes que no pueden descodificar. (Para obtener más información,
vea la sección Best-Fit Fallback ).
Llame al método Encoding.GetEncoding, que devuelve cualquier estándar, página de códigos o codificación
DBCS disponible en .NET. Las sobrecargas permiten especificar un objeto de reserva para el codificador y
para el descodificador.
NOTE
El estándar Unicode asigna un punto de código (un número) y un nombre a cada carácter en todos los scripts admitidos. Por
ejemplo, el carácter "A" está representado por el punto de código U+0041 y el nombre "LATIN CAPITAL LETTER A". Las
codificaciones de Formato de transformación Unicode (UTF) definen formas de codificar ese punto de código en una
secuencia de uno o más bytes. Un esquema de codificación Unicode simplifica el desarrollo de aplicaciones de uso
internacional porque permite que los caracteres de cualquier juego de caracteres estén representados en una única
codificación. Los desarrolladores de aplicaciones ya no tienen que realizar el seguimiento del esquema de codificación
empleado para producir caracteres para un idioma o un sistema de escritura concreto, y se pueden compartir los datos
internacionalmente entre sistemas sin dañarlos.
.NET admite tres codificaciones definidas por el estándar Unicode: UTF-8, UTF-16 y UTF-32. Para obtener más información,
vea el estándar Unicode en la página principal de Unicode.
Se puede recuperar información sobre todas las codificaciones disponibles en .NET llamando al método
Encoding.GetEncodings. .NET admite los sistemas de codificación de caracteres que se muestran en la tabla
siguiente.
Estas codificaciones permiten trabajar con caracteres Unicode, así como con codificaciones que son las más usadas
en aplicaciones heredadas. Además, puede crear una codificación personalizada definiendo una clase que se deriva
de Encoding e invalidar sus miembros.
Notas de la plataforma: .NET Core
De manera predeterminada, .NET Core no pone a disposición codificaciones de páginas de código que no sean la
página de códigos 28591 y las codificaciones Unicode, como UTF -8 y UTF -16. Sin embargo, puede agregar que las
codificaciones de páginas de código que se encuentran en las aplicaciones estándar de Windows que tienen como
destino .NET a la aplicación. Para obtener información completa, consulte el tema CodePagesEncodingProvider .
Console.WriteLine("Strings to encode:");
foreach (var stringValue in strings) {
Console.WriteLine(" {0}", stringValue);
Module Example
Public Sub Main()
Dim strings() As String = { "This is the first sentence. ",
"This is the second sentence. " }
Dim asciiEncoding As Encoding = Encoding.ASCII
Console.WriteLine("Strings to encode:")
For Each stringValue In strings
Console.WriteLine(" {0}", stringValue)
Un descodificador convierte una matriz de bytes que refleja una codificación de caracteres determinada en un
juego de caracteres, ya sea en una matriz de caracteres o en una cadena. Para descodificar una matriz de bytes en
una matriz de caracteres, se llama al método Encoding.GetChars . Para descodificar una matriz de bytes en una
cadena, se llama al método GetString . Si desea determinar cuántos caracteres son necesarios para almacenar los
bytes descodificados antes de realizar la descodificación, puede llamar al método GetCharCount .
En el ejemplo siguiente se codifican tres cadenas y después se descodifican en una sola matriz de caracteres. Se
mantiene un índice que indica la posición inicial de la matriz de caracteres para el siguiente juego de caracteres
descodificados. Se llama al método GetCharCount para asegurarse de que la matriz de caracteres es
suficientemente grande para alojar todos los caracteres descodificados. A continuación, se llama al método
ASCIIEncoding.GetChars(Byte[], Int32, Int32, Char[], Int32) para descodificar la matriz de bytes.
using System;
using System.Text;
Module Example
Public Sub Main()
Dim strings() As String = { "This is the first sentence. ",
"This is the second sentence. ",
"This is the third sentence. " }
Dim asciiEncoding As Encoding = Encoding.ASCII
' Array to hold encoded bytes.
Dim bytes() As Byte
' Array to hold decoded characters.
Dim chars(50) As Char
' Create index for current position of character array.
Dim index As Integer
Los métodos de codificación y descodificación de una clase derivada de Encoding están diseñados para funcionar
en un conjunto completo de datos; es decir, todos los datos que se va a codificar o descodificar se proporciona en
una única llamada al método. Sin embargo, en algunos casos, los datos están disponibles en una secuencia y los
datos que se va a codificar o descodificar pueden estar disponibles solo desde operaciones de lectura
independientes. Para ello, la operación de codificación o descodificación debe recordar cualquier estado guardado
de su invocación anterior. Los métodos de clases derivadas de Encoder y Decoder pueden controlar las operaciones
de codificación y descodificación que abarcan varias llamadas a métodos.
Hay disponible un objeto Encoder para una codificación determinada desde la propiedad Encoding.GetEncoder de
esa codificación. Hay disponible un objeto Decoder para una codificación determinada desde la propiedad
Encoding.GetDecoder de esa codificación. Para las operaciones de descodificación, tenga en cuenta que las clases
derivadas de Decoder incluyen un método Decoder.GetChars , pero no tienen un método que se corresponda con
Encoding.GetString.
En el ejemplo siguiente se muestra la diferencia entre el uso de los métodos Encoding.GetChars y
Decoder.GetChars para descodificar una matriz de bytes Unicode. En el ejemplo se codifica una cadena que
contiene algunos caracteres Unicode en un archivo y, a continuación, se usan los dos métodos de descodificación
para descodificarlos de diez bytes en diez bytes. Puesto que hay un par suplente en los bytes décimo y undécimo,
se descodifica en llamadas a métodos independientes. Como muestra el resultado, el método Encoding.GetChars
no puede descodificar los bytes correctamente y, en su lugar, los reemplaza con U+FFFD (carácter de reemplazo).
Por otra parte, el método Decoder.GetChars puede descodificar correctamente la matriz de bytes para obtener la
cadena original.
using System;
using System.IO;
using System.Text;
FileStream fs = File.Create(@".\characters.bin");
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(bytes);
bw.Close();
Imports System.IO
Imports System.Text
Module Example
Public Sub Main()
' Use default replacement fallback for invalid encoding.
Dim enc As New UnicodeEncoding(True, False, False)
IMPORTANT
Los problemas más frecuentes en las operaciones de codificación se producen cuando un carácter Unicode no se puede
asignar a una codificación determinada de la página de códigos. Los problemas más comunes de las operaciones de
descodificación se producen cuando las secuencias no válidas de bytes no se pueden traducir a caracteres Unicode válidos.
Por estas razones, debe saber qué estrategia de reserva emplea un determinado objeto de codificación. Siempre que sea
posible, debe especificar la estrategia de reserva usada por un objeto de codificación cuando se crea una instancia del objeto.
Best-Fit Fallback
Cuando un carácter no tiene una coincidencia exacta en la codificación de destino, el codificador puede intentar
asignarle a un carácter similar. (La reserva con ajuste perfecto es principalmente un problema de codificación en
lugar de un problema de descodificación. Hay muy pocas páginas de códigos que contengan caracteres que no se
puedan asignar correctamente a Unicode.) La reserva con ajuste perfecto es el valor predeterminado para las
codificaciones de páginas de códigos y de juegos de caracteres de doble byte recuperadas por las sobrecargas de
Encoding.GetEncoding(Int32) y Encoding.GetEncoding(String).
NOTE
En teoría, las clases de codificación Unicode proporcionadas en .NET (UTF8Encoding, UnicodeEncoding y UTF32Encoding)
admiten cada carácter de todos los juegos de caracteres, por lo que se pueden usar para eliminar los problemas de reserva
con ajuste perfecto.
Las estrategias de ajuste perfecto varían en páginas de códigos diferentes. Por ejemplo, para algunas páginas de
códigos, los caracteres latinos de ancho completo se asignarán a caracteres latinos de ancho medio, que son más
comunes. Para otras páginas de códigos no se realiza esta asignación. Incluso con una estrategia de ajuste perfecto
dinámica, algunos caracteres no tienen un ajuste imaginable en algunas codificaciones. Por ejemplo, un ideograma
chino no tiene ninguna asignación razonable a la página de códigos 1252. En este caso, se emplea una cadena de
reemplazo. De forma predeterminada, esta cadena es simplemente un carácter QUESTION MARK (U+003F ).
NOTE
Las estrategias de ajuste perfecto no están documentadas de forma detallada. Sin embargo, varias páginas de códigos se
documentan en el sitio web de Unicode Consortium. Revise el archivo Léame.txt de esa carpeta para obtener una
descripción de cómo interpretar los archivos de asignación.
En el ejemplo siguiente se usa la página de códigos 1252 (la página de códigos de Windows para los idiomas de
Europa occidental) para mostrar la asignación con ajuste perfecto y sus desventajas. El método
Encoding.GetEncoding(Int32) se usa para recuperar un objeto de codificación para la página de códigos 1252. De
forma predeterminada, usa una asignación con ajuste perfecto para los caracteres Unicode que no admite. En el
ejemplo se crea una instancia de una cadena que contiene tres caracteres no ASCII, CIRCLED LATIN CAPITAL
LETTER S (U+24C8), SUPERSCRIPT FIVE (U+2075) e INFINITY (U+221E ), separados por espacios en blanco.
Como muestra el resultado del ejemplo, cuando se codifica la cadena, los tres caracteres originales que no son
espacios en blanco se reemplazan con QUESTION MARK (U+003F ), DIGIT FIVE (U+0035) y DIGIT EIGHT
(U+0038). DIGIT EIGHT es un reemplazo especialmente deficiente para el carácter INFINITY no compatible y
QUESTION MARK indica que no había ninguna asignación disponible para el carácter original.
using System;
using System.Text;
Console.WriteLine("\n");
Module Example
Public Sub Main()
' Get an encoding for code page 1252 (Western Europe character set).
Dim cp1252 As Encoding = Encoding.GetEncoding(1252)
La asignación con ajuste perfecto es el comportamiento predeterminado para un objeto Encoding que codifica los
datos Unicode en datos de página de códigos, y hay aplicaciones heredadas que se basan en este comportamiento.
Sin embargo, la mayoría de las aplicaciones nuevas deben evitarlo por razones de seguridad. Por ejemplo, las
aplicaciones no deben asignar nombres de dominio mediante una codificación con ajuste perfecto.
NOTE
También puede implementar una asignación personalizada de reserva con ajuste perfecto para una codificación. Para más
información, vea la sección Implementing a Custom Fallback Strategy .
Si la reserva con ajuste perfecto es el valor predeterminado para un objeto de codificación, puede elegir otra
estrategia de reserva cuando se recupera un objeto Encoding llamando a la sobrecarga de
Encoding.GetEncoding(Int32, EncoderFallback, DecoderFallback) o Encoding.GetEncoding(String, EncoderFallback,
DecoderFallback) . La próxima sección incluye un ejemplo que reemplaza con un asterisco (*) cada carácter que no
se puede asignar a la página de códigos 1252.
using System;
using System.Text;
Console.WriteLine();
Console.WriteLine();
}
}
}
// The example displays the following output:
// Ⓢ ⁵ ∞
// 24C8 0020 2075 0020 221E
// Round-trip: False
// * * *
// 002A 0020 002A 0020 002A
Imports System.Text
Module Example
Public Sub Main()
Dim cp1252r As Encoding = Encoding.GetEncoding(1252,
New EncoderReplacementFallback("*"),
New DecoderReplacementFallback("*"))
Replacement Fallback
Cuando un carácter no tiene una coincidencia exacta en el esquema de destino, pero no hay ningún carácter
adecuado al que se pueda asignar, la aplicación puede especificar un carácter o una cadena de reemplazo. Este es el
comportamiento predeterminado del descodificador Unicode, que reemplaza cualquier secuencia de dos bytes que
no pueda descodificar con REPLACEMENT_CHARACTER (U+FFFD ). También es el comportamiento
predeterminado de la clase ASCIIEncoding , que reemplaza cada carácter que no puede codificar o descodificar con
un signo de interrogación. En el ejemplo siguiente se muestra el reemplazo de caracteres para la cadena Unicode
del ejemplo anterior. Como muestra el resultado, cada carácter que no se puede descodificar en un valor de bytes
ASCII se reemplaza con 0x3F, que es el código ASCII de un signo de interrogación.
using System;
using System.Text;
Console.WriteLine("\n");
Console.WriteLine();
}
}
}
// The example displays the following output:
// Ⓢ ⁵ ∞
// 24C8 0020 2075 0020 221E
//
// Encoded bytes: 3F 20 3F 20 3F
//
// Round-trip: False
// ? ? ?
// 003F 0020 003F 0020 003F
Imports System.Text
Module Example
Public Sub Main()
Dim enc As Encoding = Encoding.Ascii
.NET incluye las clases EncoderReplacementFallback y DecoderReplacementFallback, que sustituyen una cadena de
reemplazo si un carácter no se asigna exactamente en una operación de codificación o descodificación. De forma
predeterminada, esta cadena de reemplazo es un signo de interrogación, pero puede llamar a una sobrecarga del
constructor de clase para elegir otra cadena diferente. Normalmente, la cadena de reemplazo es un carácter único,
aunque esto no es un requisito. En el ejemplo siguiente se cambia el comportamiento del codificador de la página
de códigos 1252 creando una instancia de un objeto EncoderReplacementFallback que usa un asterisco (*) como
cadena de reemplazo.
using System;
using System.Text;
Console.WriteLine();
Console.WriteLine();
}
}
}
// The example displays the following output:
// Ⓢ ⁵ ∞
// 24C8 0020 2075 0020 221E
// Round-trip: False
// * * *
// 002A 0020 002A 0020 002A
Imports System.Text
Module Example
Public Sub Main()
Dim cp1252r As Encoding = Encoding.GetEncoding(1252,
New EncoderReplacementFallback("*"),
New DecoderReplacementFallback("*"))
NOTE
También puede implementar una clase de reemplazo para una codificación. Para más información, vea la sección
Implementing a Custom Fallback Strategy .
Además de QUESTION MARK (U+003F ), el REPLACEMENT CHARACTER de Unicode (U+FFFD ) se suele usar
como cadena de reemplazo, especialmente al descodificar secuencias de bytes que no se puede traducir
correctamente a caracteres Unicode. Sin embargo, se puede elegir cualquier cadena de reemplazo y esta puede
contener varios caracteres.
Exception Fallback
En lugar de proporcionar una reserva con ajuste perfecto o una cadena de reemplazo, un codificador puede
producir EncoderFallbackException si no puede codificar un juego de caracteres y un descodificador puede
producir DecoderFallbackException si no puede descodificar una matriz de bytes. Para producir una excepción en
operaciones de codificación y descodificación, se proporciona un objeto EncoderExceptionFallback y un objeto
DecoderExceptionFallback , respectivamente, al método Encoding.GetEncoding(String, EncoderFallback,
DecoderFallback) . En el ejemplo siguiente se muestra la reserva de excepción con la clase ASCIIEncoding .
using System;
using System.Text;
Console.WriteLine("\n");
Console.WriteLine();
}
catch (EncoderFallbackException e) {
Console.Write("Exception: ");
if (e.IsUnknownSurrogate())
Console.WriteLine("Unable to encode surrogate pair 0x{0:X4} 0x{1:X3} at index {2}.",
Convert.ToUInt16(e.CharUnknownHigh),
Convert.ToUInt16(e.CharUnknownLow),
e.Index);
else
Console.WriteLine("Unable to encode 0x{0:X4} at index {1}.",
Convert.ToUInt16(e.CharUnknown),
e.Index);
return;
}
Console.WriteLine();
Console.WriteLine();
}
}
catch (DecoderFallbackException e) {
Console.Write("Unable to decode byte(s) ");
foreach (byte unknown in e.BytesUnknown)
Console.Write("0x{0:X2} ");
Module Example
Public Sub Main()
Dim enc As Encoding = Encoding.GetEncoding("us-ascii",
New EncoderExceptionFallback(),
New DecoderExceptionFallback())
return true;
}
this.index--;
return charsToReturn[this.index + 1];
}
Public Overloads Overrides Function Fallback(ByVal charUnknownHigh As Char, ByVal charUnknownLow As Char,
ByVal index As Integer) As Boolean
' Do not try to map surrogates to ASCII.
Return False
End Function
Public Overloads Overrides Function Fallback(ByVal charUnknown As Char, ByVal index As Integer) As Boolean
' Return false if there are already characters to map.
If count >= 1 Then Return False
Return True
End Function
Me.index -= 1
Return charsToReturn(Me.index + 1)
End Function
using System;
using System.Collections.Generic;
using System.Text;
class Program
{
static void Main()
{
Encoding enc = Encoding.GetEncoding("us-ascii", new CustomMapper(), new DecoderExceptionFallback());
Console.WriteLine("\n");
Console.WriteLine();
}
}
}
Imports System.Text
Imports System.Collections.Generic
Module Module1
Sub Main()
Dim enc As Encoding = Encoding.GetEncoding("us-ascii", New CustomMapper(), New
DecoderExceptionFallback())
Vea también
Encoder
Decoder
DecoderFallback
Encoding
EncoderFallback
Globalización y localización
Analizar cadenas en .NET
04/11/2019 • 2 minutes to read • Edit Online
Una operación de análisis convierte una cadena que representa un tipo base de .NET en dicho tipo base. Por
ejemplo, se usa una operación de análisis para convertir una cadena en un número de punto flotante o un valor
de fecha y hora. El método que se usa normalmente para realizar una operación de análisis es el método Parse .
Dado que el análisis es la operación inversa del formato (lo que implica convertir un tipo base en su
representación de cadena), se aplican muchas de las mismas reglas y convenciones. Del mismo modo que el
formato usa un objeto que implementa la interfaz IFormatProvider para proporcionar información de formato
según la referencia cultural, el análisis también usa un objeto que implementa la interfaz IFormatProvider para
determinar cómo se interpreta una representación de cadena. Para obtener más información, consulte Aplicar
formato a tipos.
En esta sección
Análisis de cadenas numéricas
Se describe cómo convertir cadenas en tipos numéricos de .NET.
Análisis de cadenas de fecha y hora
Se describe cómo convertir cadenas en tipos DateTime de .NET.
Análisis de otras cadenas
Se describe cómo convertir cadenas en tipos carácter, booleano y enumeración.
Secciones relacionadas
Aplicación de formato a tipos
Se describen los conceptos de formato básicos, como especificadores de formato y proveedores de formato.
Conversión de tipos en .NET
Se describe cómo convertir tipos.
Tipos base
Se describen las operaciones comunes que se pueden realizar en tipos base de .NET.
Analizar cadenas numéricas en .NET
04/11/2019 • 13 minutes to read • Edit Online
Todos los tipos numéricos tienen dos métodos de análisis estáticos, Parse y TryParse , que puede usar para
convertir la representación de cadena de un número en un tipo numérico. Estos métodos permiten analizar
cadenas generadas mediante el uso de las cadenas de formato que se documentan en Cadenas con formato
numérico estándar y Cadenas con formato numérico personalizado. De forma predeterminada, los métodos
Parse y TryParse pueden convertir correctamente las cadenas que contienen dígitos decimales enteros solo en
valores enteros. Pueden convertir correctamente las cadenas que contienen dígitos decimales enteros y
fraccionarios, separadores de grupos y un separador decimal en valores de punto flotante. El método Parse
produce una excepción si se produce un error en la operación, mientras que el método TryParse devuelve false .
Module Example
Public Sub Main()
Dim values() As String = { "1,304.16", "$1,456.78", "1,094", "152",
"123,45 €", "1 304,16", "Ae9f" }
Dim number As Double
Dim culture As CultureInfo = Nothing
using System;
using System.Globalization;
Imports System.Globalization
Module Example
Public Sub Main()
Dim value As String = "1,304"
Dim number As Integer
Dim provider As IFormatProvider = CultureInfo.CreateSpecificCulture("en-US")
If Int32.TryParse(value, number) Then
Console.WriteLine("{0} --> {1}", value, number)
Else
Console.WriteLine("Unable to convert '{0}'", value)
End If
WARNING
La operación de análisis siempre usa las convenciones de formato de una referencia cultural determinada. Si no pasa un
objeto CultureInfo o NumberFormatInfo para especificar una referencia cultural, se usa la referencia cultural asociada al
subproceso actual.
En la tabla siguiente se enumeran los miembros de la enumeración NumberStyles y se describe el efecto que
tienen en la operación de análisis.
Además, la enumeración NumberStyles proporciona los siguientes estilos compuestos, que incluyen varias marcas
NumberStyles.
Vea también
NumberStyles
Parsing Strings
Aplicación de formato a tipos
Analizar cadenas de fecha y hora en .NET
22/01/2020 • 12 minutes to read • Edit Online
El análisis de cadenas para convertirlas en objetos DateTime requiere que se especifique información sobre cómo
se representan las fechas y horas en forma de texto. Las distintas referencias culturales usan distintos órdenes de
día, mes y año. Algunas representaciones horarias usan el reloj de 24 horas y otras especifican "a. m." y "p. m.".
Algunas aplicaciones solo necesitan la fecha. Otras solo necesitan la hora. Pero otras necesitan especificar la fecha
y la hora. Los métodos que convierten cadenas a objeto DateTime permiten especificar información detallada
sobre los formatos esperados y los elementos de fecha y hora que precisa la aplicación. Hay tres subtareas para
convertir correctamente el texto en un objeto DateTime:
1. Debe especificarse el formato esperado del texto que representa una fecha y hora.
2. Es posible especificar la referencia cultural del formato de fecha y hora.
3. Puede especificarse cómo se establecen los componentes que faltan en la representación de texto en la fecha y
hora.
Los métodos Parse y TryParse convierten varias representaciones comunes de fecha y hora. Los métodos
ParseExact y TryParseExact convierten una representación de cadena que se ajusta al modelo especificado por una
cadena de formato de fecha y hora. (Para obtener más información, vea los artículos sobre cadenas con formato de
fecha y hora estándar y cadenas con formato de fecha y hora personalizado).
El objeto DateTimeFormatInfo actual proporciona más control sobre la forma en que debe interpretarse el texto
como fecha y hora. Las propiedades de un objeto DateTimeFormatInfo describen los separadores de fecha y hora,
los nombres de los meses, días y eras, así como el formato de las designaciones "a. m." y "p. m.". La referencia
cultural del subproceso actual proporciona un objeto DateTimeFormatInfo que representa la referencia cultural
actual. Si quiere una referencia cultural específica o una configuración personalizada, especifique el parámetro
IFormatProvider de un método de análisis. Para el parámetro IFormatProvider, especifique un objeto CultureInfo,
que representa una referencia cultural, o un objeto DateTimeFormatInfo.
Es posible que al texto que representa una fecha y hora le falte alguna información. Por ejemplo, la mayoría de los
usuarios supondría que la fecha "12 de marzo" representa el año actual. Del mismo modo, "Marzo de 2018"
representa el mes de marzo del año 2018. El texto que representa la hora a menudo solo incluye horas, minutos y
una designación "a. m."/"p. m.". Los métodos de análisis controlan esta información que falta mediante valores
predeterminados razonables:
Cuando solo se indica la hora, la parte de fecha utiliza la fecha actual.
Cuando solo se indica la fecha, la parte de hora es la medianoche.
Cuando no se especifica el año en una fecha, se usa el año actual.
Cuando no se especifica el día del mes, se usa el primero del mes.
Si la fecha se indica en la cadena, debe incluir el mes y uno de los dos valores, el día o el año. Si se indica la hora,
debe incluir la hora y los minutos o el designador "a. m."/"p. m.".
Se puede especificar la constante NoCurrentDateDefault para invalidar los valores predeterminados. Cuando se
usa esta constante, las propiedades de año, mes o día se establecen en el valor 1 . El último ejemplo con Parse
muestra este comportamiento.
Además de un componente de fecha y hora, la representación de cadena de una fecha y hora puede incluir una
diferencia horaria que indica cuánto difiere la hora respecto de la hora universal coordinada (UTC ). Por ejemplo, la
cadena "14/2/2007 5:32:00 -7:00" define una hora que es siete horas anterior a la hora UTC. Si se omite la
diferencia horaria de la representación de cadena de una hora, el análisis devuelve un objeto DateTime con su
propiedad Kind establecida en DateTimeKind.Unspecified. Si se especifica la diferencia horaria, el análisis devuelve
un objeto DateTime con su propiedad Kind establecida en DateTimeKind.Local y su valor ajustado a la zona
horaria local del equipo. Puede modificar este comportamiento usando un valor DateTimeStyles con el método de
análisis.
El proveedor de formato también se usa para interpretar una fecha numérica ambigua. No queda claro qué
componentes de la fecha representada por la cadena "02/03/04" son el mes, el día y el año. Los componentes se
interpretan según el orden de formatos de fecha similares del proveedor de formato.
Parse
En el ejemplo siguiente se muestra el uso del método DateTime.Parse para convertir un objeto string en un valor
DateTime. En este ejemplo se usa la referencia cultural asociada al subproceso actual. Si el objeto CultureInfo
asociado a la referencia cultural actual no puede analizar la cadena de entrada, se produce una excepción
FormatException.
TIP
Todos los ejemplos de C# en este artículo se ejecutan en el explorador. Presione el botón Ejecutar para ver el resultado.
También puede modificarlos para experimentar.
NOTE
Estos ejemplos están disponibles en el repositorio de documentos de GitHub para C# y Visual Basic. También, puede
descargar el proyecto como un archivo ZIP para C# o Visual Basic.
Además, puede definir explícitamente la referencia cultural cuyas convenciones de formato se utilizan cuando se
analiza una cadena. Especifique uno de los objetos DateTimeFormatInfo estándar devueltos por la propiedad
CultureInfo.DateTimeFormat. En el ejemplo siguiente se usa un proveedor de formato para analizar una cadena en
alemán como valor DateTime. Crea un objeto CultureInfo que representa la referencia cultural de-DE . El objeto
CultureInfo garantiza el análisis correcto de esta cadena concreta. Esto impide cualquier opción que se encuentre
en CurrentCulture de CurrentThread.
Pero, aunque puede usar sobrecargas del método Parse para especificar proveedores de formato personalizados,
el método no admite el análisis de formatos no estándar. Para analizar una fecha y hora expresadas en un formato
no estándar, use en su lugar el método ParseExact.
En el ejemplo siguiente se usa la enumeración DateTimeStyles para especificar que no debe agregarse la
información de fecha y hora actual al valor DateTime en los campos no especificados.
ParseExact
Si se ajusta a uno de los patrones de cadena especificados, el método DateTime.ParseExact convierte una cadena
en un objeto DateTime. Cuando se pasa a este método una cadena que no tiene uno de las formas especificadas,
se genera una excepción FormatException. Puede definirse uno de los especificadores de formato de fecha y hora
estándar o una combinación de los especificadores de formato de fecha y hora personalizados. Con el uso de
especificadores de formato personalizados, es posible construir una cadena de reconocimiento personalizada. Para
obtener una explicación de los especificadores, consulte los temas sobre cadenas con formato de fecha y hora
estándar y cadenas con formato de fecha y hora personalizado.
En el ejemplo siguiente, se pasa al método DateTime.ParseExact un objeto de cadena para que lo analice, seguido
de un especificador de formato y luego de un objeto CultureInfo. Este método ParseExact solo puede analizar
cadenas que sigan el patrón de fecha larga en la referencia cultural en-US .
CultureInfo MyCultureInfo = new CultureInfo("en-US");
string[] MyString = { " Friday, April 10, 2009", "Friday, April 10, 2009" };
foreach (string dateString in MyString)
{
try
{
DateTime MyDateTime = DateTime.ParseExact(dateString, "D", MyCultureInfo);
Console.WriteLine(MyDateTime);
}
catch (FormatException)
{
Console.WriteLine("Unable to parse '{0}'", dateString);
}
}
// The example displays the following output:
// Unable to parse ' Friday, April 10, 2009'
// 4/10/2009 12:00:00 AM
Cada sobrecarga de los métodos Parse y ParseExact tiene también un parámetro IFormatProvider que
proporciona información específica de la referencia cultural sobre el formato de la cadena. Este objeto
IFormatProvider es un objeto CultureInfo que representa una referencia cultural estándar o un objeto
DateTimeFormatInfo devuelto por la propiedad CultureInfo.DateTimeFormat. ParseExact usa también una cadena
o un argumento de matriz de cadena adicional que define uno o más formatos de fecha y hora personalizados.
Vea también
Analizar cadenas
Aplicación de formato a tipos
Conversión de tipos en .NET
Cadenas con formato de fecha y hora estándar
Cadenas con formato de fecha y hora personalizado
Analizar otras cadenas en .NET
04/11/2019 • 3 minutes to read • Edit Online
Además de cadenas numéricas y DateTime, puede analizar cadenas que representan los tipos Char, Boolean y
Enum en tipos de datos.
Char
El método de análisis estático asociado con el tipo de datos Char es útil para convertir una cadena que contiene un
único carácter en su valor Unicode. En el ejemplo de código siguiente se analiza una cadena en un carácter
Unicode.
Booleano
El tipo de datos Boolean contiene un método Parse que se puede usar para convertir una cadena que representa
un valor Boolean en un tipo Boolean real. Este método no distingue mayúsculas de minúsculas y puede analizar
correctamente una cadena que contenga "True" o "False". El método Parse asociado al tipo Boolean también
puede analizar cadenas que estén rodeadas por espacios en blanco. Si se pasa otra cadena, se produce una
excepción FormatException.
En el ejemplo de código siguiente se usa el método Parse para convertir una cadena en un valor Boolean.
Vea también
Parsing Strings
Aplicación de formato a tipos
Conversión de tipos en .NET