Regex para data em c++[RESOLVIDO]

1. Regex para data em c++[RESOLVIDO]

Jean César
dark777

(usa Linux Mint)

Enviado em 02/02/2018 - 23:03h

wiki.anon

boa noite galera beleza?

tenho a seguinte regex abaixo em um programa em c++:

"^(\\d{2}\\/[a-zA-Z]{3}\\/\\d{4}|\\d{2}\\/\\d{2}\\/\\d{4})$"

ela valida datas no seguinte formato abaixo:

dd/mm/yyyy ou dd/mes/yyyy

20/02/2000 ou 20/feb/2000

porem tentei adicionar outros separadores deixando assim:

"^(\\d{2}(?:/|-|.)[a-zA-Z]{3}(?:/|-|.)\\d{4}(?:/|-|.)|\\d{2}(?:/|-|.)\\d{2}(?:/|-|.)\\d{4})$"

mas agora ela valida formatos assim:

20/mm-2000
20-mm.2000
20.mm/2000
quando deveria validar somente da seguinte forma abaixo:

20/mm/2000
20-mm-2000
20.mm.2000

como eu faço para que isso dê certo?




  


2. Re: Regex para data em c++[AJUDA]

Jean César
dark777

(usa Linux Mint)

Enviado em 03/02/2018 - 17:25h

SamL escreveu:

Eu não manjo de regex, mas sei que regex é apenas a criação de uma máquina de estados. No seu caso eu acho muito mais simples fazê-la em C++ que em regex puro (opinião minha). Então, fica ai sugestão de usar uma máquina de estados programaticamente do que em regex.



acontece que eu ja tenho em uma maquina de estados mas estou estudando regex no c++ validar anos bisextos é o de menos no mais quero aprender a usar std::regex para tal em c++ ja tenho outras soluçoes de composição e outros para coisas parecidas...
wiki.anon


3. Re: Regex para data em c++[AJUDA]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 05/02/2018 - 01:16h

Use backreferences para obrigar o segundo separador a ser igual ao primeiro. Veja o exemplo abaixo (usando também raw strings, para diminuir a quantidade de barras invertidas).

R"(^(\d\d)([-./])(0[1-9]|1[0-2]|[[:alpha:]]{3})\2(\d{4,})$)"
// ^^^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^^
// |||| ||||| |||||||||||||||||||||||||||| || ||||||
// |||| ||||| |||||||||||||||||||||||||||| || Grupo 4: quatro dígitos ou mais para o ano
// |||| ||||| |||||||||||||||||||||||||||| Backreference ao valor do grupo 2
// |||| ||||| Grupo 3: meses numéricos de "01" a "09" ou "10" a "12", ou com três letras
// |||| Grupo 2: separador ("-", "." ou "/")
// Grupo 1: dois dígitos para o dia


Possíveis alterações:

  • Eu agrupei cada componente supondo que você possa querer validá-los individualmente após verificar a regex. Se você quiser apenas ver sua forma geral, pode remover o agrupamento dos grupos 1 e 4 (nesse caso, o separador será o novo grupo 1, e você terá de alterar a backreference).

  • Você pode querer levar a validação da regex um pouco mais a diante para os meses, fazendo no grupo 3 algo como “(0[1-9]|1[0-2]|jan|fev|mar|abr|mai|jun|jul|ago|set|out|nov|dez)” (nesse caso, ao criar a regex, você provavelmente vai querer ligar a opção de ignorar a diferença entre maiúsculas e minúsculas).

  • Semelhantemente, para o grupo dos dias, você poderia tentar “(0[1-9]|[12]\d|3[01])”.

  • Se você quiser dias ou meses de um dígito, pode incluir mais uma alternativa no grupo ou tornar o primeiro zero opcional (e.g., para o dia, “(0?[1-9]|[12]\d|3[01])”).

  • Considere usar strptime() (POSIX) ou outra função, classe ou biblioteca já pronta de conversão, tal como boost::date_time.


4. Re: Regex para data em c++[RESOLVIDO]

Jean César
dark777

(usa Linux Mint)

Enviado em 05/02/2018 - 14:36h

paulo1205 escreveu:

Use backreferences para obrigar o segundo separador a ser igual ao primeiro. Veja o exemplo abaixo (usando também raw strings, para diminuir a quantidade de barras invertidas).

R"(^(\d\d)([-./])(0[1-9]|1[0-2]|[[:alpha:]]{3})\2(\d{4,})$)"
// ^^^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^^
// |||| ||||| |||||||||||||||||||||||||||| || ||||||
// |||| ||||| |||||||||||||||||||||||||||| || Grupo 4: quatro dígitos ou mais para o ano
// |||| ||||| |||||||||||||||||||||||||||| Backreference ao valor do grupo 2
// |||| ||||| Grupo 3: meses numéricos de "01" a "09" ou "10" a "12", ou com três letras
// |||| Grupo 2: separador ("-", "." ou "/")
// Grupo 1: dois dígitos para o dia


Possíveis alterações:

  • Eu agrupei cada componente supondo que você possa querer validá-los individualmente após verificar a regex. Se você quiser apenas ver sua forma geral, pode remover o agrupamento dos grupos 1 e 4 (nesse caso, o separador será o novo grupo 1, e você terá de alterar a backreference).

  • Você pode querer levar a validação da regex um pouco mais a diante para os meses, fazendo no grupo 3 algo como “(0[1-9]|1[0-2]|jan|fev|mar|abr|mai|jun|jul|ago|set|out|nov|dez)” (nesse caso, ao criar a regex, você provavelmente vai querer ligar a opção de ignorar a diferença entre maiúsculas e minúsculas).

  • Semelhantemente, para o grupo dos dias, você poderia tentar “(0[1-9]|[12]\d|3[01])”.

  • Se você quiser dias ou meses de um dígito, pode incluir mais uma alternativa no grupo ou tornar o primeiro zero opcional (e.g., para o dia, “(0?[1-9]|[12]\d|3[01])”).

  • Considere usar strptime() (POSIX) ou outra função, classe ou biblioteca já pronta de conversão, tal como boost::date_time.


Interessante agora vou dar uma estudada nela pra ver se consigo fazer com que valide anos bissextos com base nisso.Sim futuramente pretendo aprender outras bibliotecas mas primeiro tenho que aprender como usar as padroes do c++...

wiki.anon






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts