Expresiones regulares para los traders

MetaQuotes | 4 agosto, 2016

 

Introducción

Expresión regular es una herramienta especial y un lenguaje para la manipulación de textos basados en un patrón especificado. Múltiples meta caracteres y reglas están definidas por la sintaxis de las expresiones regulares. 

Son capaces de llevar a cabo dos funciones principales:

  • buscar un patrón en las cadenas;
  • reemplazar el patrón encontrado.

Al crear patrones de expresiones regulares, como se mencionó anteriormente, se utilizan los caracteres especiales, meta caracteres y clases (grupos) de caracteres. Significa que una expresión regular es una cadena regular, y todos los caracteres no-especiales (no reservados) se consideran regulares.

La búsqueda de un patrón especificado en una cadena se realiza en un controlador de expresión regular. En .NET Framework y por lo tanto, en la librería RegularExpressions para MQL5, un controlador de expresión regular retrocede a expresiones regulares. Es una variación de un NFA tradicional (Nondeterministic Finite Automaton), las mismas que las aplicadas en Perl, Python, Emacs y Tcl. Se utiliza para reemplazar el patrón-coincidencias encontrados en una cadena.



1. Conceptos básicos de las expresiones regulares

Los Meta caracteres son caracteres especiales cuando especifican comandos y secuencias de manejo operando como MQL5 y secuencias de gestión de C#. Tales caracteres están precedidos por un backslash(\), y cada uno de ellos tiene un propósito especial.

MQL5 y los metacaracteres C# de las expresiones regulares en las tablas siguientes se agrupan según el significado.


1.1. Clases de caracteres:

CarácterDescripciónEjemploCoincidencias
[...]Cualquier carácter que se indica entre paréntesis[a-z]Una cadena fuente puede tener cualquier carácter del alfabeto inglés en minúsculas
[^...]Cualquier carácter no indicado entre corchetes[^0-9]Una cadena fuente puede tener cualquier caracter, aparte de números
.Cualquier carácter aparte de la línea de alimentación u otro separador de cadena Unicodeta.d"trad" en cadena "trade"
\wCualquier carácter de palabra que no es un espacio, un carácter de tabulación, etc.\w"M","Q","L","5" in "MQL 5" string
\WCualquier carácter que no es un carácter de palabra\W" ", "." in "MQL 5" string.
\sCualquier carácter de espacio en blanco del conjunto Unicode\w\s"L " in "MQL 5" string
\SCualquier carácter de espacio en blanco no del conjunto Unicode. Tenga en cuenta
que no son los mismos caracteres \w y \S
\S"M", "Q", "L", "5", "." in
"MQL 5" string
\dCualquier dígito ASCII. Equivalente a [0-9]\d"5" in "MQL 5."

 

1.2. Caracteres de repetición:

CarácterDescripciónEjemploCoincidencias
{n,m}Corresponde a un patrón anterior repetido nada menos que n o no más de m vecess{2,4}"Press", "ssl", "progressss"
{n,}Corresponde a un patrón anterior repetida n veces o máss{1,}"ssl"
{n}Coincide precisamente con n instancias de un patrón anteriors{2}"Press", "ssl", but not "progressss"
?Corresponde a cero o una instancia de una estructura anterior;
anterior no es obligatorio
Equivale a {0,1}
+Corresponde a una o más instancias de un patrón anteriorEquivale a {1}
*Corresponde a cero o más instancias de un patrón anteriorEquivale a {0}

 

1.3. Caracteres de expresiones regulares de la selección:

CarácterDescripciónEjemploCoincidencias
|Corresponde a la subexpresión de la izquierda, o subexpresión a la derecha (análogo de la operación lógica OR).1(1|2)0"110", "120" in
"100, 110, 120, 130" string
(...)Agrupación. Grupos de elementos en un todo único que se puede utilizar con caracteres *, +,?, |, etc.
También recuerda los caracteres que corresponden a este grupo para usar en los siguientes enlaces.


(?:...)Sólo agrupar. Grupos de elementos en un todo único, pero no se acuerda de los caracteres que corresponden a este grupo.

 

1.4. Ancla de caracteres de expresiones regulares:

CarácterDescripciónEjemploCoincidencias
^Se corresponde con el comienzo de una cadena de expresión o el comienzo de una cadena en la búsqueda de cadena múltiples.^Hola"Hola, mundo", pero no "Ok, Hola mundo" porque la palabra
"Hola" en esta cadena no se encuentra al principio
$Corresponde al final de una cadena de expresión o al final de una cadena en la búsqueda de cadenas múltiples.Hola$"Hola mundo"
\bCorresponde al límite de palabra, es decir, corresponde a la posición entre los caracteres \w y \W
o entre el caracter \w y el comienzo o el final de una cadena.
\b(my)\bEn la cadena "Hola mi mundo", la palabra "mi" se selecciona

Para obtener más información acerca de los elementos de las expresiones regulares, por favor, lea el artículo en la web oficial de Microsoft .



2. Características de la implementación de expresiones regulares para MQL5

2.1. Los archivos de terceros se almacenan en la carpeta interna

También es necesario para lograr la estrecha aplicación de RegularExpressions para MQL5 al código fuente de .net, para transferir una fracción de los archivos de terceros. Todos ellos se almacenan en la carpeta internal y potencialmente podrían ser muy interesantes.

Echemos un vistazo más de cerca el contenido de la carpeta internal .

  1. Generic — esta carpeta contiene archivos para implementar colecciones estrictamente tipificados, sus interfaces y enumeraciones. Una descripción más detallada se proporciona a continuación.
  2. TimeSpan — archivos para la aplicación de la estructura TimeSpan que proporciona un intervalo de tiempo.
  3. Array.MQH — en este archivo se implementa la clase Array con un número de métodos estáticos para operar con matrices. Por ejemplo: la búsqueda de clasificación, binario, recibiendo enumeración, recibiendo el índice del elemento, etc.
  4. DynamicMatrix.mqh — este archivo tiene dos clases principales para la implementación de matrices dinámicas multidimensionales. Estas son las clases de patrón que, por lo tanto, son apropiadas para los tipos de clases estándar y punteros.
  5. IComparable.mqh — archivo que implementa la interfaz IComparable que es necesaria para apoyar una serie de métodos en colecciones caracterizadas.
  6. Wrappers.MQH — envolturas para los tipos estándar y métodos para encontrar códigos hash sobre ellos.

Generic tiene tres colecciones implementadas estrictamente tipificadas:

  1. List<T> presenta una lista estrictamente tipificada de objetos disponibles por índice. Admite métodos para buscar por lista, clasificación y otras operaciones con listas.
  2. Diccionary<TKey,TValue> presenta una colección de claves y valores.
  3. LinkedList<T> presenta una lista doblemente enlazada.

Vamos a ver el uso de la lista<T> del EA TradeHistoryParsing. Este EA lee todo el histórico comercial del archivo .html y filtros por registros y columnas seleccionados. El historial de trade consiste en dos tablas: ofertas y órdenes. Las clases OrderRecord y DealRecord interpretan un registro (tuple) de las tablas con órdenes y trades, respectivamente. Por lo tanto, cada columna puede presentarse como una lista de sus registros:

List<OrderRecord*>*m_list1 = new List<OrderRecord*>();
List<DealRecord*>*m_list2 = new List<DealRecord*>();

Puesto que la clase List <T> soporta métodos de clasificación, significa que los objetos de tipo T deben compararse entre sí. En otras palabras, los operadores <,>,== se aplican para este tipo. No existen problemas con elementos estándar, pero si necesitamos crear List<T>, donde T indica la clase personalizada, entonces recibimos un error. Hay dos maneras de manejar este tema. En primer lugar, explícitamente podemos recargar los operadores de comparación en nuestra clase. Otra solución es hacer la clase descendiente de la interfaz IComparable. La segunda opción es considerablemente más corta en la aplicación, sin embargo, interrumpe la clasificación correcta. En los casos cuando es necesario ordenar las clases personalizadas, debemos recargar todos los operadores de comparación. Además de eso es recomendable implementar la herencia.

Esta es una de las características de la clase list<T>. Más información se proporciona a continuación.

Dictionary<TKey,TValue> — una especie de diccionario con conjuntos de valores y claves únicas que corresponden a ellos. Al mismo tiempo, varios valores pueden acoplarse a una de las claves. Los tipos de claves y valores están determinados por los usuarios en la etapa de creación de un objeto. Como se ve en la descripción, la clase de diccionario <TKey,TValue> es muy conveniente para el papel de la tabla hash. Para acelerar la operación con el diccionario <TKey,TValue>, debe crearse una nueva clase, que es descendiente de la clase IEqualityComparer<T> y volver a cargar dos funciones:

  • bool Equals(T x,T y) — la función devuelve truesi x es igual a y, y false, si lo contrario.
  • int GetHashCode(T obj) — la función devuelve un código hash del objeto

En la libreria RegularExpressions para MQL5, esta función se utiliza para todos los diccionarios con cadenas usadas como claves.

Aplicación del StringEqualityComparer:

class StringEqualityComparer : public IEqualityComparer<string>
  {
public:
   //--- Los métodos:
   //+------------------------------------------------------------------+
   //| Determina si los objetos especificados son iguales.              |
   //+------------------------------------------------------------------+   
   virtual bool Equals(string x,string y)
     {
      if(StringLen(x)!=StringLen(y)){ return (false); }
      else
        {
         for(int i=0; i<StringLen(x); i++)
             if(StringGetCharacter(x,i)!=StringGetCharacter(y,i)){ return (false); }
        }
      return (true);
     }
   int GetHashCode(string obj)
     {
      return (::GetHashCode(obj));
     }
  };

Ahora, al crear un nuevo objeto que pertenece a la clase Dictionary<TKey,TValue> utilizando strings como claves, enviaremos el puntero al objeto StringEqualityComparer al constructor como un parámetro:

Dictionary<string,int> *dictionary= new Dictionary<string,int>(new StringEqualityComparer);

LinkedList<T> son datos de unas estructuras que incluyen un número de elementos. Cada elemento contiene una parte informativa y dos punteros de los elementos anteriores y siguientes. Por lo tanto, dos elementos colocados cerca uno de otro, mutuamente se refieren a uno del otro. Los nodos de esta lista son ejecutados por LinkedListNode <T>objetos. Hay un sistema estándar en cada nodo que contiene el valor, el puntero hacia la lista y punteros hacia los nodos adyacentes. 

También, los enumeradores se aplican para las tres arriba mencionadas colecciones. Enumerador es un intarfaz IEnumerator generalizado<T>. IEnumerator <T>permite implementar un puente completo de la colección, independientemente de su estructura.

Para obtener el enumerador, debemos llamar al método GetEnumerator() desde el objeto, cuya clase implementa la interfaz IEnumerable:

List<int>* list = new List<int>();
list.Add(0);
list.Add(1);
list.Add(2);
IEnumerator<int> *en = list.GetEnumerator();
while(en.MoveNext())
  {
   Print(en.Current());
  }
delete en;
delete list;

En este ejemplo, iteramos sobre la lista completa y cada valor de impresión. Todo esto podría lograrse arreglando un simple lazo, pero, con frecuencia, el enfoque con los enumeradores en más conveniente. De hecho, esta solución es conveniente al crear iteraciones sobre Diccionary<TKey,TValue>.

2.2. Características de la librería RegularExpressions MQL5.

1. Para incluir toda la funcionalidad de expresiones regulares en nuestro proyecto, se debe agregar la siguiente sección:

#include <RegularExpressions\Regex.mqh>

2. por falta de espacios de nombres en MQL5 y, por lo tanto, el modificador de acceso interno , tenemos acceso a todas las clases internas y muchos métodos de la librería. De hecho, esto se considera innecesario cuando se trabaja con expresiones regulares.

Las siguientes clases serán de interés para el funcionamiento con expresiones regulares:

  • Capture — proporciona resultados de un registro exitoso de subexpresión.
  • CaptureCollection — proporciona un conjunto de registros de un grupo.
  • Group — ofrece resultados de un registro separado del grupo.
  • GroupCollection — devuelve un conjunto de grupos registrados en un partido único de búsqueda.
  • Match — proporciona resultados de coincidencias independientes de expresiones regulares.
  • MatchCollection — presenta una serie de coincidencias exitosas encontradas por aplicación iterativa de patrón de expresión regular a la cadena de entrada.
  • Regex — representa la expresión regular inmutable.

Además de las mencionadas clases utilizaremos:

  • MatchEvaluator — puntero a la función que presenta un método llamado cada vez que se encuentra una coincidencia de expresión regular.
  • RegexOptions — enumeración que presenta valores para utilizar al especificar parámetros de expresiones regulares.

RegexOptions — copia incompleta de la enumeración de fuente .Net, incluye los siguientes elementos:

Parámetro Descripción
Ninguno
Parámetros no se especifican.
IgnoreCase
La búsqueda de coincidencias no es entre mayúsculas y minúsculas.
Multiline Indica el modo multilínea.
ExplicitCapture No para cubrir los grupos sin nombre. Only valid selections — explícitamente el nombre o número de grupos en el formato (?<name> subexpressio).
Singleline Indica el modo de línea única.
IgnorePatternWhitespace Elimina espacios en blanco de un patrón sin secuencia de escape y permite comentarios marcados con carácter '#'.
RightToLeft Indica que la búsqueda se realizará de derecha a izquierda, no de izquierda a derecha.
Debug Indica que el programa trabaja con depurador.
ECMAScript Permite el comportamiento compatible con ECMAScript para la expresión. Este valor puede utilizarse sólo con IgnoreCase y Multiline.

 

Estas opciones se utilizan para crear un nuevo objeto de la clase Regex o al llamar a sus métodos estáticos.

Los ejemplos de la utilización de todas estas clases, puntero y enumeración pueden encontrarse en el código fuente de la Tests.mq5 del EA.

3. Como en la versión .Net de Framework, se implementa un almacenamiento (memoria estática de caché) de las expresiones regulares. Todas las expresiones regulares que no se crean explícitamente (ejemplos de la clase Regex) se colocan en este almacenamiento. Tal enfoque acelera el funcionamiento de los scripts, ya que no es necesario construir expresiones regulares desde cero, si coinciden con uno de los patrones existentes. El tamaño de almacenamiento por defecto es igual a 15. El método Regex::CacheSize() devuelve o especifica un número máximo de registros en el almacenamiento de memoria caché estática actual de expresiones regulares compiladas.

4. El almacenamiento mencionado debe ser borrado. Se llama para este propósito a la función estática Regex::ClearCache(). Es recomendable borrar el almacenamiento después de terminar de trabajar con expresiones regulares, de lo contrario existe un alto riesgo de eliminar los punteros y los objetos que pueden necesitar.

5. La sintaxis de C# permite colocar el caracter ' @' antes de cadenas para ignorar todas las señales de este formato. El MQL5 no controla este enfoque, por lo tanto todos los caracteres en el patrón de expresiones regulares debe ser explícitamente especificado.



3. Ejemplo de análisis de hitorico de trade

Las siguientes operaciones se implican en este ejemplo.

  1. Lectura del historial de trades desde un entorno limitado en formato .html.
  2. Selección de una tabla de "Órdenes" o "Pedidos" para un trabajo posterior.
  3. Elegir filtros para una tabla.
  4. Presentación gráfica de una tabla filtrada.
  5. Breve Estadística matemática basada en una tabla filtrada.
  6. Opción de guardar la tabla filtrada.

Estos 6 puntos se aplican en el EA de TradeHistoryParsing.mq5.

En primer lugar, cuando se trabaje con un Asesor Experto, se debe descargar un historico de trades. Por lo tanto, en el terminal MetaTrader 5 nos vamos al panel "Toolbox", pestaña "Historial" y haga clic para abrir una ventana de diálogo, seleccione "Reporte" y HTML (Internet Explorer).

Guardamos el archivo en la caja de la arena (\MetaTrader 5\MQL5\Files).

Ahora, mientras se ejecuta el Asesor Experto en la ventana de diálogo ir a la pestaña "Entradas" y escriba el nombre de nuestro archivo en el campo file_name:

Después de pulsar "OK", aparecerá la interfaz del EA:

Como se mencionó anteriormente, ambas tablas se presentan en el EA en forma de dos listas tipificadas: list<OrderRecord*> y List<DealRecord*>.

Para las clases OrderRecord y DealRecord los constructores usan matriz de cadenas como un parámetro que es un solo registro de la tabla.

Para crear estas matrices que vamos a necesitar expresiones regulares. El análisis entero del historial se realiza en el constructor de la clase TradeHistory, donde se presentan en ambas columnas donde son alamcenadas y los métodos son implementados por su filtro. El constructor de esta clase toma un parámetro — path, en nuestro caso es un nombre del archivo del historial .html:

                TradeHistory(const string path)
{
 m_file_name=path;
 m_handel= FileOpen(path,FILE_READ|FILE_TXT);
 m_list1 = new List<OrderRecord*>();
 m_list2 = new List<DealRecord*>();
 Regex *rgx=new Regex("(>)([^<>]*)(<)");
 while(!FileIsEnding(m_handel))
   {
    string str=FileReadString(m_handel);
    MatchCollection *matches=rgx.Matches(str);
    if(matches.Count()==23)
      {
       string in[11];
       for(int i=0,j=1; i<11; i++,j+=2)
         {
          in[i]=StringSubstr(matches[j].Value(),1,StringLen(matches[j].Value())-2);
         }
       m_list1.Add(new OrderRecord(in));
      }
    else if(matches.Count()==27)
      {
       string in[13];
       for(int i=0,j=1; i<13; i++,j+=2)
         {
          in[i]=StringSubstr(matches[j].Value(),1,StringLen(matches[j].Value())-2);
         }
       m_list2.Add(new DealRecord(in));
      }
    delete matches;
   }
 FileClose(m_handel);
 delete rgx;
 Regex::ClearCache();
}

El código de este constructor muestra que se utiliza solamente una expresión regular con un patrón "(>)([^<>]*)(<)" para analizar el historial de trades. Consideremos cuidadosamente este patrón:

(>) Búsqueda del carácter '>'
(^[<>]*) Cualquier caracter aparte de '>' y '<', que se repite cero o más veces
(<) Búsqueda del carácter '<'

 

Esta expresión regular busca a través de todas las subcadenas que comienzan con '>' y terminan con '<'. El texto entre ellos no debe comenzar con ' <' o ' '>'. En otras palabras, obtenemos el texto entre etiquetas en el archivo .html. Habrá soportes innecesarios en los lados, pero se quitarán pronto. Todos las subcadenas de direcciones encontradas se almacenan en MatchCollection, que es una colección de todas las subcadenas que satisfacen el patrón de expresión regular y se encuentran en la cadena fuente. Debido a la estructura del archivo .html, podemos determinar con exactitud, si la cadena es un registro de la tabla de órdenes, la tabla de ofertas o en otra cadena, simplemente calculando el total de coincidencias. De esta manera, la cadena es un registro de la tabla de órdenes, si el número de coincidencias es igual a 23, o de la tabla de precios sobre el resultado de 27 coincidencias. En otros casos, no estamos interesados en esta cadena. Ahora, extraemos todos los elementos incluso (cadenas "><" de elementos impares) de nuestra colección, recortar el primero y el último carácter y grabar la cadena dispuesta en la matriz:

in[i]=StringSubstr(matches[j].Value(),1,StringLen(matches[j].Value())-2);

Cada vez cuando leyendo una cadena nueva, se suprime una colección de coincidencias. Después de leer todo el archivo, debemos cerrar, eliminar la expresión regular y borrar el búfer.

Ahora, debemos implementar el filtro de la tabla, específicamente, mediante la selección de una columna y cierto valor de ella para obtener una tabla recortada. En nuestro caso, una lista debe generar una sublista. Para ello podemos crear una nueva lista, arreglar iteración completa de todos los elementos de la lista vieja, y si satisface las condiciones especificadas, agregará a una lista nueva.

También hay otra manera basada en el método FindAll(Predicate match) para list<T>. Extrae todos los elementos que satisfagan las condiciones del predicado especificado que es un puntero de la función:

typedef bool (*Predicate)(IComparable*);

Hemos mencionado antes la interfaz IComparable.

Queda por implementar la función real match , donde ya sabemos la regla aplicada para aceptar o rechazar la lista. En nuestro caso se trata del número de columna y su valor interior. Para resolver este problema se aplican dos métodos estáticos SetIndex(const int index) y SetValue(const string value) en la clase de registro descendiente de las clases de OrderRecord y DealRecord. Aceptar y guardar el número y valor de la columna. Esta información se utilizará para poner en práctica nuestro método de búsqueda:

static bool FindRecord(IComparable *value)
  {
   Record *record=dynamic_cast<Record*>(value);
   if(s_index>=ArraySize(record.m_data) || s_index<0)
     {
      Print("Iindex out of range.");
      return(false);
     }
   return (record.m_data[s_index] == s_value);
  }

Aquí, s_index es una variable estática con el valor establecido por el método SetIndex y s_value es una variable estática con el valor de SetValue.

Ahora, al especificar los valores necesarios del número de la columna y el valor interior, fácilmente obtendremos la versión reducida de nuestra lista:

Record::SetValue(value);
Record::SetIndex(columnIndex);
List<Record*> *new_list = source_list.FindAll(Record::FindRecord);

Estas listas filtradas se mostrarán en la interfaz gráfica del EA.

Si es necesario, hay una opción para guardar estas tablas filtradas en archivos .csv. También se guardará el archivo en el sand box llamada Result.csv.

¡IMPORTANTE! Se utilizará el mismo nombre al guardar los archivos. De esta manera, si es necesario para salvar a dos o más columnas, debemos guardarlos uno por uno y por consiguient cambiar su nombre. De lo contrario, acabaremos re-escribiendo el mismo archivo. 



4. Ejemplo de análisis de resultados de optimización del EA

Este ejemplo controla el archivo .xml del resultado de la optimización del EA desde la terminal del MetaTrader 5. Tiene una presentación gráfica de datos obtenidos durante la optimización y una opción para filtrarla. Todos los datos se dividen en dos tablas:

  • "Tabla de Probador de resultados" — contiene datos estadísticos obtenidos durante las pruebas;
  •  "Tabla de parámetros de entrada" — almacena todos los valores de los parámetros de entrada. Se aplica a esta tabla un límite de diez parámetros de entrada. No se mostrará el exceso del número permitido de parámetros .

Con el fin de establecer un filtro de una de las tabals, debemos seleccionar el nombre de columna y establecer un rango de valores.

A continuación se muestra una interfaz gráfica del ejemplo:

Esta imagen muestra la "tabla de resultados del probador" con columnas activadas "Paso", "Resultado", "Factor de beneficio", "Factor de recuperación", y dos filtros:

  1. Los valores en la columna "Paso" deben pertenecer al intervalo [0; 10] de los valores;
  2. Los valores en la columna "Factor de beneficio" deben pertenecer a [0,4; 0,5] rango de valores.

5. Breve descripción de las muestras de la libreria RegularExpressions para MQL5

Excepto dos EAs descritos, la biblioteca RegularExpressions MQL5 ofrece 20 ejemplos. Presentan la implementación de varias funciones de expresiones regulares y esta lobrería. Todos están ubicados en el EA del Tests.mq5:

Tendremos en cuenta que las características específicas y las opciones de la librería se aplican en cada ejemplo.

  1. MatchExamples — muestra dos posibles opciones de iteración de todas las coincidencias mediante la creación de MatchCollection o utilizando el método de Match.NextMatch().
  2. MatchGroups — muestra la forma de obtener resultados de otro grupo de captura (Group) y una operación más con ellos.
  3. MatchResult — muestra el uso del método Match.Result(string) que devuelve la extensión del modelo de reemplazo especificado.
  4. RegexConstructor — muestra 3 diferentes opciones de creación de la clase Regex: basado en el patrón, patrón con parámetros especificados, patrón con parámetros y el valor que indica cuánto tiempo debe tratar de encontrar una coincidencia el método de comparación con el patrón, antes de que caduque el tiempo de espera.
  5. RegexEscape — muestra la operación del método Regex::Escape(string).
  6. RegexExample — indica el proceso de creación de expresiones regulares y su manejo posterior.
  7. RegexGetGroupNames — proporciona el ejemplo del método Regex.GetGroupNames(string);
  8. RegexGetGroupNumbers — proporciona el ejemplo del método Regex.GetGroupNumbers(int);
  9. RegexGroupNameFromNumber — proporciona el ejemplo del método Regex.GroupNameFromNumber(int);
  10. RegexIsMatch — proporciona el ejemplo de la utilización de todas las opciones del método estático Regex::IsMatch();
  11. RegexReplace — proporciona el ejemplo de la utilización de las opciones principales del método estático Regex::Replace();
  12. RegexSplit — proporciona el ejemplo de la utilización de las opciones principales del método estático Regex::Split();
  13. Captura — ejemplo de funcionamiento con un resultado de una captura exitosa de la expresión (captura).
  14. CaptureCollection — ejemplo de operación con un conjunto de capturas hechas por un grupo de captura (CaptureCollection).
  15. Group: ejemplo de funcionamiento con los resultados de un Group separado.
  16. GroupCollection — ejemplo de operación con un conjunto de grupos capturados en un partido único de búsqueda (GroupCollection).
  17. MatchCollectionItem — crear MatchCollection con el método estático Regex::Matches (string,string);
  18. MatchEvaluator — ejemplo de crear y utilizar un puntero de la función del tipo MatchEvaluator.
  19. RegexMatchCollectionCount — demostración del método MatchCollection.Count();
  20. RegexOptions — demostración del impacto del parámetro RegexOptions para manejar una expresión regular.

La mayoría de ejemplos tiene una funcionalidad similar y sirve principalmente para probar el funcionamiento de la librería.

Conclusión

Este artículo describe brevemente las características y uso de expresiones regulares. Para más información recomendamos la lectura de artículos disponibles desde los siguientes enlaces. La sintaxis de expresiones regulares en .net tiene mucho en común con la implementación en MQL5, por lo tanto, la información de ayuda de Microsoft será relevante al menos en parte. Lo mismo se aplica a las clases de la carpeta interna.

Referencias

  1. http://professorweb.ru/my/csharp/charp_theory/level4/4_10.php
  2. https://habrahabr.ru/post/115825/
  3. https://habrahabr.ru/post/115436/
  4. https://msdn.microsoft.com/en-us/library/hs600312.aspx
  5. https://msdn.microsoft.com/en-us/library/ae5bf541.aspx