Pergunta

Qual é o padrão RegEx para DateTime (2008-09-01 12:35:45 )?

Eu recebo este erro:

Nenhum delimitador final '^' encontrado

Usando:

preg_match('(?n:^(?=\d)((?<day>31(?!(.0?[2469]|11))|30(?!.0?2)|29(?(.0?2)(?=.{3,4}(1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|(16|[2468][048]|[3579][26])00))|0?[1-9]|1\d|2[0-8])(?<sep>[/.-])(?<month>0?[1-9]|1[012])\2(?<year>(1[6-9]|[2-9]\d)\d{2})(?:(?=\x20\d)\x20|$))?(?<time>((0?[1-9]|1[012])(:[0-5]\d){0,2}(?i:\ [AP]M))|([01]\d|2[0-3])(:[0-5]\d){1,2})?$)', '2008-09-01 12:35:45');

Dá esse erro:

Aviso:preg_match() [função.preg-match]:Falha na compilação:nada para repetir no deslocamento 0 em E:\www\index.php na linha 19

Foi útil?

Solução

@Espo:Só tenho que dizer que o regex é incrível.Eu odiaria ter que escrever o código que fizesse algo útil com as correspondências, como se você quisesse realmente descobrir qual data e hora o usuário digitou.

Parece que a solução de Tom seria mais sustentável, pois é um zilhão de vezes mais simples e com a adição de alguns parênteses você pode facilmente obter os valores que o usuário digitou:

(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})

Se você estiver usando perl, poderá obter os valores com algo assim:

$year = $1;
$month = $2;
$day = $3;
$hour = $4;
$minute = $5;
$second = $6;

Outras línguas terão uma capacidade semelhante.Observe que você precisará fazer algumas pequenas modificações no regex se quiser aceitar valores como meses de um dígito.

Outras dicas

Uma versão simples que funcionará para o formato mencionado, mas não para todos os outros conforme @Espos:

(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) 

http://regexlib.com/REDetails.aspx?regexp_id=610

^(?=\d)(?:(?:31(?!.(?:0?[2469]|11))|(?:30|29)(?!.0?2)|29(? =.0?2.(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][ 26])|(?:(?:16|[2468][048]|[3579][26])00)))(?:\x20|$))|(?:2[0-8]| 1\d|0?[1-9]))([-./])(?:1[012]|0?[1-9])\1(?:1[6-9]|[2 -9]\d)?\d\d(?:(?=\x20\d)\x20|$))?(((0?[1-9]|1[012])(:[0- 5]\d){0,2}(\x20[AP]M))|([01]\d|2[0-3])(:[0-5]\d){1,2}) ?$


Isso valida as datas e/ou padrões de tempos.Dias em fevereirotambém são validados para anos bissextos.Datas:no formato dd/mm/yyyy ou d/m/yy entre 1/1/1600 - 31/12/9999.Os zeros principais são opcionais.Os separadores de data podem ser traços correspondentes (-), barras (/) ou períodos (.) Vezes:No formato HH: MM: SS AM/PM 12 horas (12:00 - 23:59:59) ou HH: MM: SS Formato de tempo militar (00:00 - 23:59:59).O formato de 12 horas:1) pode ter um zero líder durante a hora.2) Minutos e segundos são opcionais para o formato de 12 horas 3) são necessários ou PM e sensíveis ao caso.Tempo militar 1) deve ter um zero líder por todas as horas inferiores a 10.2) Minutos são mandatórios.3) segundos são opcionais.Data e hora:combinação dos formatos acima.Uma data primeiro e depois um tempo separado por um espaço.ex) dd/mm/yyyy hh: mm: ss


Editar:Certifique-se de copiar o RegEx do site regexlib.com, pois o StackOverflow às vezes remove/destrói caracteres especiais.

^([2][0]\d{2}\/([0]\d|[1][0-2])\/([0-2]\d|[3][0-1]))$|^([2][0]\d{2}\/([0]\d|[1][0-2])\/([0-2]\d|[3][0-1])\s([0-1]\d|[2][0-3])\:[0-5]\d\:[0-5]\d)$
$date = "2014-04-01 12:00:00";

preg_match('/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/',$date, $matches);

print_r($matches);

$correspondências serão:

Array ( 
   [0] => 2014-04-01 12:00:00 
   [1] => 2014 
   [2] => 04 
   [3] => 01 
   [4] => 12 
   [5] => 00 
   [6] => 00
)

Uma maneira fácil de quebrar uma string formatada com data e hora.

Em relação à resposta de Imran a partir de 1º de setembro de 2008 às 12:33, está faltando:No padrão, os padrões corretos são

preg_match('/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/', '2008-09-01 12:35:45', $m1);
print_r( $m1 );
preg_match('/\d{4}-\d{2}-\d{2} \d{1,2}:\d{2}:\d{2}/', '2008-09-01 12:35:45', $m2);
print_r( $m2 );
preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', '2008-09-01 12:35:45', $m3);
print_r( $m3 );

isso retorna

Array ( [0] => 2008-09-01 12:35:45 )
Array ( [0] => 2008-09-01 12:35:45 )
Array ( [0] => 2008-09-01 12:35:45 ) 

Aqui está minha solução:

/^(2[0-9]{3})-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]) (0[0-9]|1[0-9]|2[0123])\:([012345][0-9])\:([012345][0-9])$/u

Eu modifiquei o padrão regex de http://regexlib.com/REDetails.aspx?regexp_id=610.O padrão a seguir deve corresponder ao seu caso.

^(?=\d)(?:(?:1[6-9]|[2-9]\d)?\d\d([-.\/])(?:1[012]|0?[1-9])\1(?:31(?<!.(?:0[2469]|11))|(?:30|29)(?<!.02)|29(?=.0?2.(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(?:\x20|$))|(?:2[0-8]|1\d|0?[1-9]))(?:(?=\x20\d)\x20|$))?(((0?[1-9]|1[012])(:[0-5]\d){0,2}(\x20[AP]M))|([01]\d|2[0-3])(:[0-5]\d){1,2})?$

AAAA-MM-DD HH:MM:SS

As funções preg do PHP precisam que seu regex seja encapsulado com um caractere delimitador, que pode ser qualquer caractere.Você não pode usar esse caractere delimitador sem escapar dentro da regex.Isso deve funcionar (aqui o caractere delimitador é /):

preg_match('/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/', '2008-09-01 12:35:45');

// or this, to allow matching 0:00:00 time too.
preg_match('/\d{4}-\d{2}-\d{2} \d{1,2}:\d{2}:\d{2}/', '2008-09-01 12:35:45');

Se você precisar combinar linhas que contenham apenas data e hora, adicione ^ e $ no início e no final da regex.

preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', '2008-09-01 12:35:45');

Link para preg_match() do Manual do PHP

Aqui está uma versão simplificada (originada da resposta de Espo).Ele verifica a exatidão da data (mesmo ano bissexto) e hh:mm:ss é opcional
Exemplos que funcionam:
- 31/12/2003 11:59:59
- 29-2-2004

^(?=\d)(?:(?:31(?!.(?:0?[2469]|11))|(?:30|29)(?!.0?2)|29(?=.0?2.(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(?:\x20|$))|(?:2[0-8]|1\d|0?[1-9]))([-./])(?:1[012]|0?[1-9])\1(?:1[6-9]|[2-9]\d)?\d\d(?:(?=\x20\d)\x20|$))(|([01]\d|2[0-3])(:[0-5]\d){1,2})?$

Aqui está minha solução:

[12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]) ([01][0-9]|2[0-3]):[0-5]\d

Regular expression visualization

Demonstração de Debuggex

https://regex101.com/r/lbthaT/4

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top