Expressões regulares para traders

MetaQuotes | 12 setembro, 2016

 

Introdução

As expressões regulares proporcionam uma linguagem formal para manipular textos de acordo com um modelo definido. Esse modelo também é chamado de padrão ou máscara de expressões regulares. O conjunto de metacaracteres e as regras são definidos pela sintaxe das expressões regulares.y 

As expressões regulares são capazes de executar duas tarefas básicas:

  • pesquisa de padrão na cadeia de caracteres;
  • substituição do padrão encontrado.

Ao criar padrões para expressões regulares, usam-se símbolos especiais, metacaracteres e classes (conjuntos) de símbolos. Isso significa que a expressão regular consiste em uma simples cadeia de caracteres, o que faz com que, nela, todos os símbolos não-especiais (não-reservados) sejam considerados normais. 

Especificamente, a pesquisa do padrão definido, na cadeia de caracteres, é realizada pelo manipulador de expressões regulares.  Na .NET Framework, e, portanto, na biblioteca RegularExpressions para MQL5, o manipulador de expressões regulares executa a pesquisa com retorno para expressões regulares. Ele é uma variação da tradicional máquina AFND (autômato finito não-determinístico), semelhante às usadas em Perl, Python, Emacs e Tcl. A substituição das correspondências encontradas na cadeia de caracteres é precisamente realizada por ele.



1. Noções básicas de expressões regulares

Os metacaracteres são símbolos especiais que definem comandos e controlam seqüências que funcionam como os controles de seqüências MQL5 e C#. Esses símbolos são precedidos por uma barra invertida (\) que tem uma finalidade específica.

Nas tabelas a seguir, os metacaracteres de expressões regulares MQL5 e C# são agrupados por significado.


1.1. Classes de caracteres:

CaractereValorExemploCorrespondências
[...]Quaisquer carateres exibidos entre parênteses[a-z]A cadeia de caracteres fonte pode ter quaisquer carateres do alfabeto inglês
em letras minúsculas
[^...]Quaisquer carateres não exibidos entre parênteses[^0-9]A cadeia de caracteres fonte pode ter quaisquer carateres, exceto dígitos
.Qualquer caractere, exceto a alimentação de linha ou outro separador de cadeia Unicodeta.d"trad" na cadeia de caracteres "trade"
\wQualquer caractere de texto que não seja espaço, tabulação, etc.\w"M","Q","L","5" na cadeia de caracteres "MQL 5"
\WQualquer caractere que não seja um caractere de palavra\W" ", "." na cadeia de caracteres "MQL 5."
\sQualquer espaço em branco a partir do conjunto Unicode\w\s"L " na cadeia de caracteres "MQL 5"
\SQualquer caractere que não seja um espaço em branco a partir do conjunto Unicode. Observe o seguinte,
os carateres \w e \S não são a mesma coisa
\S"M", "Q", "L", "5", "." na cadeia de caracteres
"MQL 5."
\dQuaisquer dígitos ASCII. Equivalente a [0-9]\d"5" na "MQL 5."

 

1.2. Caracteres de repetição:

CaractereValorExemploCorrespondências
{n,m}Corresponde ao padrão anterior repetido não menos do que n e não mais do que m vezess{2,4}"Press", "ssl", "progressss"
{n,}Corresponde ao padrão anterior repetido n ou mais vezess{1,}"ssl"
{n}Corresponde exatamente a n instâncias do padrão anteriors{2}"Press", "ssl", mas não "progressss"
?Corresponde a zero ou uma instância do padrão anterior;
o padrão anterior é opcional
Equivalente a {0,1}
+Corresponde a um ou mais instâncias do padrão anteriorEquivalente a {1,}
*Corresponde a zero ou mais instâncias do padrão anteriorEquivalente a {0,}

 

1.3. Carateres de expressões regulares de seleção:

CaractereValorExemploCorrespondências
|Corresponde tanto a sub-expressão à direita como a sub-expressão à esquerda (analógico da operação lógica OU).1(1|2)0"110", "120" na cadeia de caracteres
"100, 110, 120, 130"
(...)Agrupamento. Agrupa elementos como um conjunto que pode ser utilizado com os caracteres *, +, ?, | etc.
Também se lembra dos símbolos que correspondem a esse grupo para uso em referências posteriores.


(?:...)Apenas o agrupamento. Agrupa elementos em um conjunto, mas não se lembra dos caracteres que correspondem a este grupo.

 

1.4. Carateres de ancoragem de expressões regulares:

CaractereValorExemploCorrespondências
^Corresponde ao início da expressão de cadeia de caracteres ou início da cadeia ao ter uma cadeia de caracteres múltipla de pesquisa.^Hello"Hello, world", mas não "Ok, Hello world", pois, nesta cadeia, a palavra
"Hello" não está no início
$Corresponde ao final da cadeia de caracteres da expressão ou final da cadeia ao ter uma cadeia de caracteres múltipla de pesquisa.Hello$"World, Hello"
\bCorresponde ao limite da palavra, ou seja, corresponde à posição entre os caracteres \w e \W
ou entre o caractere \w e o início ou final da cadeia de caracteres.
\b(my)\bNa cadeia "Hello my world" escolhe a palavra "my"

Você pode explorar mais detalhes sobre os elementos de expressões regulares, lendo o artigo no site oficial da Microsoft.



2. Características da implementação de expressões regulares para MQL5

2.1. Os arquivos de terceiros são armazenados na pasta Internal

Para alcançar uma implementação tão próxima quanto possível da RegularExpressions para MQL5, tivemos de transferir parte dos arquivos de terceiros para o código fonte .Net. Todos eles estão armazenados na pasta Internal.

Consideremos mais de perto o conteúdo da pasta Internal.

  1. Generic — nesta pasta estão os arquivos para implementar coleções fortemente tipadas, enumeradores e interfaces para eles. Abaixo será dada uma descrição mais detalhada.
  2. TimeSpan — arquivos para implementar a estrutura TimeSpan, ela representa o intervalo de tempo.
  3. Array.mqh — nesse arquivo, é implementada a classe Array, para a qual, por sua vez, existe uma série de métodos estáticos de trabalho com matrizes. Por exemplo: classificação, busca binária, recepção de enumerados, recepção de índice do elemento, etc.
  4. DynamicMatrix.mqh — neste arquivo estão dois classes base para implementar matrizes dinâmicas multi-dimensionais. Essas classes são padrões e, por tanto, são apropriadas para tipos padrão e ponteiros de classe.
  5. IComparable.mqh — arquivo que implementa a interface IComparable, necessária para suporte da série de métodos nas coleções tipadas.
  6. Wrappers.mqh — invólucros para tipos padrão e métodos para encontrar código hash.

Na pasta Generic, foram implementadas três coleções fortemente tipadas:

  1. List<T> representa uma lista fortemente tipada de objetos que estão disponíveis no índice. Ele suporta métodos para pesquisa por lista, execução de classificação e outras operações com listas.
  2. Dictionary<TKey,TValue> presenta uma coleção de chaves e valores.
  3. LinkedList<T>  presenta uma lista duplamente ligada.

Consideremos o uso da List<T> a partir de Expert Advisor TradeHistoryParsing. Esse EA lê o histórico de negociação a partir do arquivo .html e filtra-o segundo as colunas selecionadas e registros. O histórico de negociação consta de duas tabelas: Transações e Ordens. As classes OrderRecord e DealRecord interpretam um registro (tupla) a partir da tabela Ordens e transações, respetivamente. Por conseguinte, cada uma das tabelas pode ser representada como a lista das suas entradas:

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

Como a classe List<T> suporta métodos de classificação, os objetos do tipo T devem ser comparados entre si. Em outras palavras, para este tipo são implementadas as operações  <,>,==. Se precisarmos criar a List<T>, onde T é o ponteiro para a classe personalizada, obteremos um erro. É possível resolver este problema de duas maneiras. Em primeiro lugar, em nossa classe, podemos sobrecarregar explicitamente os operadores de comparação. Outra solução seria fazer a classe o herdeiro da interface IComparable. A segunda variante é muito mais curta na implementação, além disso, viola a validade da classificação. Quando for necessário realizar a classificação para classes personalizadas, nós deveremos sobrecarregar todos os operadores e, adicionalmente, se possível, implementar a herança.

Isto é apenas uma das caraterísticas da classe List<T>. Abaixo consideraremos mais detalhes.

O Dictionary<TKey,TValue> é uma espécie de dicionário a partir de um conjunto de valores e chaves únicas que correspondem a ele.  Além disso, uma chave pode estar ligada a vários valores. Os tipos de chaves e valores são definidos pelo usuário durante a criação do objeto. Como pode ser visto a partir da descrição, a classe Dictionary<TKey,TValue> é adequada para o papel da tabela de hash. Para acelerar o trabalho com o Dictionary<TKey,TValue>, é necessário criar uma nova classe, ela será herdeiro a partir da classe IEqualityComparer<T>, e sobrecarregar dois funções:

  • bool Equals(T x,T y) — a função retorna true, se x igual a y, e false , caso contrário.
  • int GetHashCode(T obj) — a função retorna o código de hash a partir do objeto obj.

Na biblioteca RegularExpresiions para MQL5, este recurso é utilizado para todos os dicionários, cujas chaves são as cadeias de caracteres.

Implementação de classe StringEqualityComparer:

class StringEqualityComparer : public IEqualityComparer<string>
  {
public:
   //--- Methods:
   //+------------------------------------------------------------------+
   //| Determines whether the specified objects are equal.              |
   //+------------------------------------------------------------------+   
   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));
     }
  };

Agora, ao criar um novo objeto que pertença à classe Dictionary<TKey,TValue>, onde as chaves são cadeias de caracteres, enviamos ao construtor o ponteiro para o objeto StringEqualityComparer como parâmetro:

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

LinkedList<T> — é uma estrutura de dados que inclui um número de elementos. Cada elemento contém uma parte de informação e dois ponteiros: para o anterior e os elementos a seguir. Por conseguinte, dois elementos adjacentes se referem mutuamente um ao outro. Os nós dessa lista são implementados pelos objetos LinkedListNode<T>. Cada um desses nós contém um conjunto padrão: um valor, um ponteiro para a lista e outro ponteiro para os nós vizinhos. 


Além disso, todas as três coleções descritas acima são implementadas por enumeradores. Um enumerador é um objeto que representa a interface genérica IEnumerator<T>. O IEnumerator<T> permite implementar um rasteamento completo na coleção, independentemente de sua estrutura.

Para obter a enumeração, é necessário chamar o método GetEnumerator() a partir do objeto, cuja classe implementa a interface 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;

Neste exemplo, podemos percorrer toda a lista e imprimir cada valor. Tudo isto poderia ser conseguido fazendo um simples ciclo for, mas, frequentemente, a abordagem com enumeradores é mais conveniente. Na verdade, esta solução é adequada ao realizar a passagem pelo Dictionary<TKey,TValue>.

2.2. Caraterísticas da biblioteca RegularExpressions para MQL5.

1. Para conectar toda a funcionalidade das expressões regulares, é necessário adicionar o seguinte trecho ao nosso projeto:

#include <RegularExpressions\Regex.mqh>

2. Na linguagem MQL5, devido à ausência de espaços de nomes e, portanto, do modificador de acesso internal, nós temos acesso a todas as classes internas da biblioteca e a muitos métodos para elas. Na verdade, não é necessário trabalhar com expressões regulares.

Para trabalhar com expressões regulares, vamos estar interessados​nas classes:

  • Capture — representa os resultados de um registro bem-sucedido de parte da expressão.
  • CaptureCollection — representa um conjunto de registros feitos por um grupo.
  • Grupo — representa os resultados de um único grupo de registro.
  • GroupCollection — retorna o conjunto de grupos registrados em uma correspondência.
  • Math — representa os resultados de uma correspondência separada de uma expressão regular.
  • MathCollection — representa o conjunto de correspondências bem-sucedidas encontradas aplicando iterativamente um padrão de expressão regular para a cadeia de caracteres de entrada.
  • Regex — representa uma expressão regular imutável.

Adicionalmente, usaremos:

  • MatchEvaluator — ponteiro para a função, ele é um método chamado cada vez que for encontrada uma correspondência de expressão regular.
  • RegexOptions — enumeração que fornece valores sob em parâmetro definido de expressões regulares.

RegexOptions — cópia incompleta da enumeração original a partir da .NET e inclui os seguintes elementos:

Parâmetros Descrição
Nenhum
Os parâmetros não estão definidos.
IgnoreCase
O registro não é levado em conta, ao pesquisar correspondências.
Multiline Indica o modo de cadeia de carateres múltipla.
ExplicitCapture Não capturar grupos sem nome. As únicas seleções válidas pressupõem grupos claramente nomeados ou enumerados no formato (?<nome> parte da expressão).
Singleline Indica o modo de linha única.
IgnorePatternWhitespace Remove do padrão os separadores e habilita os comentários marcados com o símbolo "#".
RightToLeft Indica que a pesquisa será realizada da direita para a esquerda, em vez de esquerda para a direita.
Debug Indica que o programa funciona usando o depurador.
ECMAScript Permite um comportamento compatível com ECMAScript para a expressão. Este valor pode ser utilizado apenas em conjunto com os valores IgnoreCase e Multiline.

 

Estas opções são usadas ao criar um novo objeto de classe Regex ou chamar seus métodos estáticos.

No código-fonte do EA Tests.mq5, você pode encontrar exemplos de uso para todas essas classes, ponteiro e enumeração.

3. Como na versão .Net, nessa biblioteca, é implementado um repositório (memória cache estática) de expressões regulares. Todas as expressões regulares criadas implicitamente (modelos da classe Regex) são inseridas neste repositório. Essa abordagem acelera o trabalho dos scripts, porque não há necessidade de re-construir as expressões regulares, se seu padrão corresponder a um dos já existentes. O tamanho do repositório é por defeito 15. O método Regex::CacheSize() retorna ou define o número máximo de registros na atual memória cache estática das expressões regulares compiladas.

4. O repositório acima mencionado deve ser limpo. Para fazer isso, é preciso chamar a função estática Regex::ClearCache(). É recomendável chamar essa função somente após terminar de trabalhar com expressões regulares, caso contrário, é muito provável que se esteja removendo ponteiros necessários e objetos.

5. A sintaxe da linguagem C# permite colocar diante das linhas o caractere '@' para ignorar todas as marcas de formatação nele. Na MQL5, tal abordagem ainda não tem sido coberta, de modo que todos os caracteres de controle, num padrão de expressão regular, devem ser descritos claramente.



3. Exemplo de análise do histórico de negociação

Atenção! Os exemplos mostrados neste artigo serão reproduzidos apenas na condição de que a biblioteca RegularExpressions para MQL5 já estiver instalada no seu computador.

Esse exemplo envolve as seguintes operações.

  1. Leitura do histórico de negociação a partir da área restrita em formato .html.
  2. Seleção de uma das duas tabelas ("Ordem" ou "Transação") para trabalho futuro com ela.
  3. Seleção de filtros para a tabela.
  4. Representação gráfica da tabela filtrada.
  5. Estatística breves sobre a tabela filtrada.
  6. Possibilidade de salvar a tabela filtrada.

Estes seis pontos são implementados no EA TradeHistoryParsing.mq5.

Em primeiro lugar, para trabalhar com o EA, é necessário fazer o download do histórico de negociação. Para fazer isso, no terminal de negociação MetaTrader5, na barra de ferramentas, na guia "Histórico", fazemos clique direito para abrir a caixa de diálogo, selecionamos o ponto "Relatórios" e, em seguida, HTML (InternetExplorer).

Salvamos o arquivo na área restrita (\MetaTrader 5\MQL5\Files).

Agora, ao executar o Expert Advisor, na caixa de diálogo, vamos para a guia "Parâmetros de entrada" e, no campo file_name, inserimos o nome de nosso arquivo:


Após pressionar "Ok", aparecerá a interface do EA:


Como foi mencionado anteriormente, ambas as tabelas são apresentadas, no EA, na forma de duas listas tipadas: List<OrderRecord*> e List<DealRecord*>.

Os construtores para as classes OrderRecord e DealRecord implementam como parâmetros a matriz - de cadeias de caracteres - que transpõe a partir um registro da tabela.

Para criar essas matrizes, necessitaremos expressões regulares. Toda a análise do histórico é realizada no construtor de classe TradeHistory, além disso, nesta classe, são armazenadas as representações de ambas as tabelas e implementados seus métodos de filtragem. O construtor dessa classe usa um parâmetro, em nosso caso, será o nome .html do arquivo do histórico:

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

O código desse construtor mostra que nós usamos apenas uma expressão regular com um padrão "(>)([^<>]*)(<)". Vamos considerar este padrão cuidadosamente:

(>) Pesquisa do caractere '>'
(^[<>]*) Qualquer caractere, exceto '>' e '<', repetido zero ou mais vezes
(<) Pesquisa do caractere '<'

 

Essa expressão regular procura todas as subcadeias de caracteres que começam com '>' e terminam com '<'. O texto - localizado entre eles - não deve começar com '<' ou '>'. Por outras palavras, obtemos um teste entre as etiquetas no arquivo .html cujas bordas terão parênteses desnecessários que podemos remover mais tarde. Salvamos todas as subcadeias de carateres na MathcCollection, ela é uma coleção de todas as subcadeias que satisfazem o padrão da expressão regular e que se encontram na cadeia fonte de caracteres. Graças à estrutura .html do arquivo, nós podemos determinar com precisão contando o número de correspondências se nossa cadeia de caracteres é um registro a partir da tabela de Ordens ou tabela de Transações ou outra cadeia. Desse modo, a cadeia de caracteres é um registro da tabela de Ordens, se o número de correspondências é igual a 23, e, é um registro da tabela Transações, se o número de correspondências é igual a 27. Caso contrário, esta linha não nos deve interessar. Agora, de nossa coleção extraímos todos os elementos pares (nos impares estarão as cadeia de caracteres "><"), cortamos o primeiro e último caractere e armazenamos a cadeia pronta na matriz:

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

Além disso, após ler cada nova cadeia de caracteres, é necessário excluir a coleção de coincidências. Depois de ler o arquivo inteiro, é preciso fechá-lo, excluir a expressão regular e, finalmente, limpar o buffer.

Agora, precisamos implementar a filtragem de tabelas, isto é, após selecionar uma coluna e um valor definido a partir dela, devemos obter uma tabela truncada. No nosso caso, a partir da lista devemos obter uma sublista. Para fazer isso, nós podemos criar uma nova lista, organizar uma iteração completa de todos os elementos da lista velha e, se essa iteração satisfaz as condições especificadas, vamos adicioná-la à nova lista.

No entanto, existe outra maneira baseada no método FindAll(Predicate match) para a List<T>. Ela extrai todos os elementos que correspondem às condições do predicado especificado que é um ponteiro para uma função e tem a forma:

typedef bool (*Predicate)(IComparable*);

Sobre interface IComparable já foi discutido anteriormente.

Resta apenas implementar a função match, onde já é conhecida a regra segundo a qual nós aceitamos ou rejeitamos o elemento da lista. Neste caso, é o número da coluna e o valor nela. Para resolver esta tarefa, na classe Record (ela é herdeira para as classes OrderRecord e DealRecord), existem dois métodos estáticos SetIndex(const int index) e SetValue(const string value). Estes métodos aceitam e memorizam o número da coluna e os valores nela. Em seguida, esses dados são apenas para ser usado na implementação do nosso método de pesquisa:

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);
  }

Neste caso, a s_index é a variável estática, cujo valor é definido pelo método SetIndex, enquanto a s_value é a variável estática cujo valor é definido pelo método SetValue.

Agora, tendo definidos nossos valores de número de coluna e valores nela, podemos obter facilmente a versão truncada de nossa lista:

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

Estas listas filtradas serão exibidas na interface gráfica do EA.

Se necessário, é possível salvar essas tabelas filtradas em arquivos .csv. O arquivo será salvo na área restrita sob nome Result.csv.

IMPORTANTE! Quando você salva os arquivos, a eles é sempre atribuído o mesmo nome. Assim, se houver uma necessidade para manter duas ou mais tabelas, será necessário salvá-las uma por uma e renomeá-las. Caso contrário, acabaremos re-escrevendo o mesmo arquivo. 



4. Exemplo de analise de resultados da otimização do Expert Advisor

Esse exemplo processa o arquivo .xml do resultado da otimização do EA a partir do terminal MetaTrader5. Ele implementa uma representação gráfica para os dados obtidos durante a otimização, bem como a possibilidade de filtrá-los. Todos os dados são divididos em duas tabelas:

  • "Tester results table" — inclui todas as estatísticas recolhidas durante o teste;
  •  "Input parameters table" —  contém todos os valores das variáveis de entrada. Para esta tabela, está definido um limite de dez parâmetros de entrada. Se houver mais parâmetros, eles não serão exibidos.

Para estabelecer o filtro em uma das tabelas, você deve selecionar o nome da coluna, na qual será realizada a filtragem, e definir um intervalo de valores.

A interface gráfica do exemplo é mostrada abaixo:

Nessa imagem, são exibidas as tabelas "Tester results table" com colunas ativas: "Pass", "Result", "Profit Factor", "Recovery Factor" e dois filtros:

  1. Na coluna "Pass", os valores devem pertencer ao intervalo de valores [0; 10];
  2. Na coluna "Profit Factor", os valores devem pertencer ao intervalo de valores [0.4; 0.5].

5. Breve descrição dos exemplos a partir da biblioteca RegularExpressions para MQL5

Além dos dois AE descritos, à biblioteca RegularExpressions para MQL5 são anexados 20 exemplos. Neles serão implementadas várias possibilidades de expressões regulares e essa biblioteca. Eles estão localizados no EA Tests.mq5:


Vamos considerar que características específicas e possibilidades da biblioteca são aplicadas em cada exemplo.

  1. MatchExamples — mostra dois possíveis opções de iteração de todas as correspondências (Match), criando a MatchCollection ou usando o método Match.NextMatch().
  2. MatchGroups — mostra a maneira de obter os resultados do grupo separado de registro (Group) e o trabalho futuro com ele.
  3. MatchResult — demonstra o uso do método Match.Result(string), ele retorna a extensão do padrão definido de substituição.
  4. RegexConstructor — mostra 3 opções diferentes para a criação de classe Regex: com base no padrão, o padrão com parâmetros definidos, o padrão com parâmetros e valores que indicam quanto tempo o método de comparação com o padrão deve tentar encontrar uma correspondência antes do tempo limite expirar.
  5. RegexEscape — demonstra o trabalho do método Regex::Escape(string).
  6. RegexExample — mostra o processo de criação de expressões regulares e seu tratamento subseqüente.
  7. RegexGetGroupNames — mostra o exemplo de uso do método Regex.GetGroupNames(string);
  8. RegexGetGroupNumbers — mostra o exemplo de uso do método Regex.GetGroupNumbers(int);
  9. RegexGroupNameFromNumber — mostra o exemplo de uso do método Regex.GroupNameFromNumber(int);
  10. RegexIsMatch — mostra o exemplo de uso de todos os métodos estáticos Regex::IsMatch();
  11. RegexReplace — mostra o exemplo de uso das principais variantes do método estático Regex::Replace();
  12. RegexSplit — mostra o exemplo de uso das principais variantes do método estático Regex::Split();
  13. Capture — exemplo de trabalho com o resultado de um registro bem-sucedido de parte da expressão(Capture).
  14. CaptureCollection — exemplo de trabalho com o conjunto de registros feitos por um grupo de registro (CaptureCollection).
  15. Group — exemplo de trabalho com o resultado do grupo separado de registro (Group).
  16. GroupCollection — exemplo de trabalho com o conjunto de grupos registrados em uma correspondência (GroupCollection).
  17. MatchCollectionItem — criação da MatchCollection pela método estático Regex::Matches(string,string);
  18. MatchEvaluator — exemplo de criação do ponteiro para a função do tipo MatchEvaluator e seu uso.
  19. RegexMatchCollectionCount — demonstração do método MatchCollection.Count();
  20. RegexOptions — demonstração da influência do parâmetro RegexOptions no tratamento da expressão regular.

A maioria dos exemplos se sobrepõem nas funcionalidades e servem principalmente para testar o funcionamento da biblioteca.

Conclusão

Este artigo descreve brevemente as possibilidades das expressões regulares e sua utilização. Para obter informações mais detalhadas, recomendamos ler os artigos nos links abaixo. A sintaxe de expressões regulares na .Net coincide em grande parte com a implementação na MQL5, por isso todos os guias da Microsoft serão relevantes, pelo menos parcialmente. O mesmo se aplica às classes de pasta interna.

Referências

  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/pt-pt/library/hs600312.aspx
  5. https://msdn.microsoft.com/pt-pt/library/ae5bf541.aspx