Pergunta

Eu não posso bastante colocar minha cabeça em torno do que a ^ está fazendo na minha preg_match.

 if (preg_match('~^(\d\d\d\d)(-(\d{1,2})(-(\d{1,2}))?)?$~', trim($date), $dateParts)) {
   echo the $dateparts and do some magic with them
 } else {
   tell me the date is formatted wrong
 }

A meu ver isso é olhando para ver se a data $ corresponde ao formato que li como 4 decimais - 1 ou 2 casas decimais - 1 ou 2 casas decimais

Se não existir correspondência, em seguida, a instrução if exibe a data, se isso não acontecer, então ele dá um erro de data incorreta formatação.

No entanto, apenas passando o ano $ Date = '1977' com mais nada (nenhum dia ou mês) ainda passa como verdadeiro e exibe os dateParts, eu pensei que iria lançar um erro?

Pode alguém apontar o que eu estou faltando na expressão regular? Eu estou supondo que é o ^ ou possivelmente o? $ No final pode significar apenas corresponder parte dela?

Foi útil?

Solução

Não há necessidade de grupo absolutamente tudo . Isso parece mais agradável e irá fazer o mesmo:

preg_match('~^\d{4}(-\d{1,2}(-\d{1,2})?)?$~', trim($date), $dateParts)

Isso também explica por que "1977" é aceito -. O mês eo dia partes são ambos opcional (o ponto de interrogação faz algo opcional)

Para fazer o que você diz ( "4 decimais - 1 ou 2 casas decimais - 1 ou 2 casas decimais"), você precisa remover ambos os grupos opcionais:

preg_match('~^\d{4}-\d{1,2}-\d{1,2}$~', trim($date), $dateParts)

O "^" e "$" não tem nada a ver com o problema que você está vendo. Eles estão apenas iniciar-de-corda e âncoras de fim-de-corda, certificando-se de que nada do que o padrão descreve é ??na cadeia marcada. Deixá-los fora e "blah 1977-01-01 blah" vai começar a corresponder.

Outras dicas

Tente isto:

'~^(\d\d\d\d)-(\d{1,2})-(\d{1,2})$~'

O problema foi o regex foi permitindo que o mês e dia como opcional pela '?' caráter.

^ e $ âncora seu padrão para o início eo fim, respectivamente, da cadeia passada. O ? é um multiplicador, combinando 0 ou 1 do padrão anterior (neste caso, o bit parenthesised).

O seu padrão corresponde a um ano ou um ano e um mês, ou um ano e um mês e data; se você seguir os parênteses, você verá o ? final está operando com os parênteses que cercam todo o padrão após o ano.

^    # beginning of string
    (\d\d\d\d)   #year
    (
        -(\d{1,2})   #month after a dash
        (
            -(\d{1,2}) #date after a dash
        )? #date optional
    )?   # month and date optional
$   # end of string

Ok, vamos quebrar isso para você:

  • '~ ^ (\ d \ d \ d \ d) (- (\ d {1,2}) (? - (\ d {1,2})))? $ ~'
  • ~ -. No início e final são RegExp-delimitadores, para que eles não são realmente parte da expressão regular
  • ^ - Meios "Este é o início da linha"
    • Evita partidas no meio da cadeia, e âncoras lo para que o início da string deve corresponder
  • (\ d \ d \ d \ d) - Partidas (e capturas) quatro dígitos, e não é opcional
    • Isto poderia também ser escrito como \ d {4}
  • (- (\ d {1,2}) (- (\ d {1,2}))?) -? Partidas (e capturas) um grupo opcional.
    • Ele diz que, se existe esse grupo, ele deve ser um traço, seguido de um ou dois dígitos (dia ou mês), seguido por um traço, seguido de um ou dois dígitos (dia ou mês)
  • $ -. Meios final da corda, de modo que este, juntamente com ^ no início dos meios de cordas que toda a cadeia tem de coincidir com o Regexp

Alguns exemplos do que este Regex irá corresponder a:

  • 1982/08/11
  • 1982-30-01
  • 8127-99-52

Alguns exemplos que não irá corresponder:

  • 82-08-11
  • 2009-10

Como você pode ver, esta regex vai aceitar alguns "datas" que não são realmente datas válidas, então eu provavelmente iria executá-lo através de algum tipo de função de manipulação de data também, como strtotime .

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