Correspondência de expressão regular para testar um ano válido


92

Dado um valor, quero validá-lo para verificar se é um ano válido. Meus critérios são simples, onde o valor deve ser um número inteiro com 4caracteres. Sei que essa não é a melhor solução, pois não permitirá anos antes 1000e permitirá anos como 5000. Este critério é adequado para meu cenário atual.

O que eu inventei é

\d{4}$

Embora funcione, também permite valores negativos.

Como posso garantir que apenas números inteiros positivos sejam permitidos?


fwiw Eu criei um projeto node.js, to-regex-range para criar automaticamente esses intervalos. É mais difícil do que pode parecer se você precisar gerar a regex para testar por um intervalo de anos.
jonschlinkert

Por que limitar sua validação a anos de 4 dígitos? longnow.org
Dan Temple

Respostas:


78

Você precisa adicionar uma âncora inicial ^como:

^\d{4}$

Seu regex \d{4}$corresponderá a strings que terminam com 4 dígitos . Portanto, entradas como -1234serão aceitas.

Ao adicionar a âncora de início, você associa apenas as strings que começam e terminam com 4 dígitos, o que efetivamente significa que devem conter apenas 4 dígitos.


2
Droga! O meu era tão defeituoso que teria até aceitado whateverblahblah2323. Agora eu entendo porque um pouco de aprendizado é perigoso: O
Ranhiru Jude Cooray

62
Isso acontecerá no ano 10.000.
sferik

16
@sferik: Não importa. O pôster original afirmou especificamente que queria verificar se havia quatro personagens. Ele não afirmou que queria que o ano 10.000 fosse uma entrada válida, então aceitar 10000seria um bug.
markusk

4
@sferik: O programa terá desaparecido por séculos. Do contrário, é melhor se preocupar com 9.000 anos no futuro. Seguindo o princípio de YAGNI, a abordagem é válida.
Phil

183

Anos de 1000 a 2999

^[12][0-9]{3}$

Para 1900-2099

^(19|20)\d{2}$

14
Esta é uma solução muito melhor
mk_89

10
É melhor usar o grupo sem captura:^(?:19|20)\d{2}$
Eldar Agalarov

Como eu validaria um ano de 4 dígitos entre 2011 e 2099?
Mcquaim

Como posso adicionar (19|20)\d{2}ao meu regex para validar um formato de data de nascimento? Esta é a minha regex /^[0-9]{1,2}\/(0[1-9])|(1[0-2])\/[0-9]{4}$/. Quero garantir que o ano sempre tenha 4 dígitos e comece a murchar 19 ** ou 20 **
ltdev

Use ^ (19 | 2 [0-9]) \ d {2} $ para os anos 1900 - 2999
MarcoZen

22

A resposta "aceita" a esta pergunta é incorreta e míope.

É incorreto porque corresponderá a strings como 0001, que não é um ano válido.

É míope porque não corresponderá a nenhum valor acima de 9999. Já esquecemos as lições do Y2K ? Em vez disso, use a expressão regular:

^[1-9]\d{3,}$

Se você precisar corresponder anos no passado, além de anos no futuro, poderá usar esta expressão regular para corresponder a qualquer número inteiro positivo:

^[1-9]\d*$

Mesmo que você não espere datas do passado, você pode querer usar esta expressão regular de qualquer maneira, apenas no caso de alguém inventar uma máquina do tempo e quiser levar seu software de volta com eles.

Nota: Esta expressão regular corresponderá a todos os anos, incluindo aqueles anteriores ao ano 1, uma vez que eles são normalmente representados com uma designação BC em vez de um número inteiro negativo. Claro, essa convenção pode mudar nos próximos milênios, então sua melhor opção é combinar qualquer número inteiro - positivo ou negativo - com a seguinte expressão regular:

^-?[1-9]\d*$

3
Não, provavelmente não vai. Mas alguém (arqueólogo? Historiador?) Pode precisar comparar anos com 8.000 anos atrás. : D E Doc Brown pode precisar ...
Jaime

1
Eu usei isso para limitar o intervalo de 1000-9999 ^ [1-9] \\ d {3} $ isso porque o aplicativo para o qual temos que fornecer dados, aceita apenas números de 4 dígitos :(
MatPag

Resposta incrível. Eu faria o seguinte para aceitar o ano 0 também: ^ (-? [1-9] \ d * | 0) $
Kosta Kontos

10

Isso funciona de 1900 a 2099:

/(?:(?:19|20)[0-9]{2})/

me parece que só iria para 2099. BTW, o OP está perguntando como permitir apenas números positivos de 4 dígitos.
DeanOC 01 de

bah, 2099 é o que eu quis dizer. obrigado. e agora vejo a parte dos inteiros positivos.
jonschlinkert 01 de

Eu criei um projeto, to-regex-range para criar automaticamente esses intervalos
jonschlinkert

5

Com base na resposta @ r92, para os anos 1970-2019:

(19[789]\d|20[01]\d)

Sua resposta permite197999
avalanche1

Acho que não ... A primeira parte da regex corresponde a um número começando com 19, depois qualquer um de 7,8 ou 9, seguido por um ÚNICO número. A regex 19[789]\d\d\dpermitiria197999
Renaud,

1
/(19[789]\d|20[01]\d)/.test(1970324) >> true
avalanche1 de

sim, corresponderá aos 4 primeiros números ( 1970), não aos 3 últimos (19[789]\d|20[01]\d)[^0-9]. Isso combinaria, 1970 324mas não1970324
Renaud

1
Achei este útil para encontrar o ano do filme a partir de um nome de arquivo ... neste caso, queremos coisas de 1930 em diante ... mas, em seguida, excluímos o 1024 que foi adicionado ao final para qualidade de vídeo
Adrian Hum

2

Para testar um ano em uma string que contém outras palavras junto com o ano, você pode usar o seguinte regex: \ b \ d {4} \ b


Isso era exatamente o que eu precisava, a resposta aceita não parece ser PCRE válida.
Prometheus

2

Em teoria, a opção de 4 dígitos está certa. Mas, na prática, pode ser melhor ter uma faixa de 1900-2099.

Além disso, ele precisa ser um grupo sem captura. Muitos comentários e respostas propõem capturar o agrupamento que não é IMHO adequado. Porque para correspondência pode funcionar, mas para extrair correspondências usando regex, ele extrairá números de 4 dígitos e números de dois dígitos (19 e 20) também por causa do parêntese.

Isso funcionará para correspondência exata usando grupos de não captura:

(?:19|20)\d{2}


1

você pode ir com sth como [ ^-]\d{4}$: você evita que o sinal de menos -fique antes de seus 4 dígitos.
você também pode usar ^\d{4}$com ^para pegar o início da string. Na verdade, depende do seu cenário ...



0

Você pode converter seu inteiro em uma string. Como o sinal de menos não coincide com os dígitos, você não terá anos negativos.


0

Eu uso este regex em Java ^(0[1-9]|1[012])[/](0[1-9]|[12][0-9]|3[01])[/](19|[2-9][0-9])[0-9]{2}$

Funciona de 1900 a 9999


0

/ ^ \ d {4} $ / Isto irá verificar se uma string consiste em apenas 4 números. Neste cenário, para inserir o ano 989, você pode fornecer 0989.


0

Se precisar corresponder YYYY ou YYYYMMDD, você pode usar:

^((?:(?:(?:(?:(?:[1-9]\d)(?:0[48]|[2468][048]|[13579][26])|(?:(?:[2468][048]|[13579][26])00))(?:0?2(?:29)))|(?:(?:[1-9]\d{3})(?:(?:(?:0?[13578]|1[02])(?:31))|(?:(?:0?[13-9]|1[0-2])(?:29|30))|(?:(?:0?[1-9])|(?:1[0-2]))(?:0?[1-9]|1\d|2[0-8])))))|(?:19|20)\d{2})$

0

Você também pode usar este.

([0-2][0-9]|3[0-1])\/([0-1][0-2])\/(19[789]\d|20[01]\d)

Eles querem combinar apenas o ano. Além disso, suas correspondências de regex 00/00/2000ou 31/02/1999e muitas outras datas falsas.
Toto de

Isso pode ajudá-lo ([0-2] [0-9] | 3 [0-1]) \ / ([0-1] [0-2]) \ / (19 [789] \ d | 20 [01 ] \ d)
Ranjeet Chouhan

(0[1-9]|1[0-2])é uma expressão muito melhor para o mês
EZ-C

0

No meu caso, eu queria combinar uma string que terminasse com um ano (4 dígitos) como este, por exemplo:

Oct 2020
Nov 2020
Dec 2020
Jan 2021

Ele vai voltar truecom este:

var sheetName = 'Jan 2021';
var yearRegex = new RegExp("\\d{4}$");
var isMonthSheet = yearRegex.test(sheetName);
Logger.log('isMonthSheet = ' + isMonthSheet);

O código acima é usado no Apps Script .


Isso, não só vai combinar, Oct 2020mas também Oct 20202, Oct20202
Ranhiru Jude Cooray
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.