Error formatting ZIP code

Asked

Viewed 5,031 times

3

I’m having problems with my script, when the zip code field is already formatted, it clears the field by clicking again on the button. How do I make it not to accuse as invalid format or not clear the field when it is already formatted?

Script

window.onload=function(){
	document.getElementById("botao").onclick=function(){
		var strCEP = document.getElementById("cep").value;

		cep.value = formatarCEP(strCEP);
	}
}

function formatarCEP(str){
	var re = /^([\d]{2})([\d]{3})([\d]{3})|^[\d]{2}.[\d]{3}-[\d]{3}/;

	if(re.test(str)){
		return str.replace(re,"$1.$2-$3");
	}else{
		alert("CEP inválido!");
	}
	
	return "";
}
<!DOCTYPE html>
<html lang="pt-BR">
	<head>
		<meta charset="utf-8"/>
		<title>Página Teste</title>
		<script type="text/javascript" src="js/script.js"></script>
	</head>
	<body>
		<div>
			<label for="cep">CEP: <input type="text" id="cep" maxlength="8" /></label>
		</div>
		<p>
			<button id="botao">Testar</button>
		</p>
	</body>
</html>

3 answers

5


The problem is in your Regex:

/^([\d]{2})([\d]{3})([\d]{3})|^[\d]{2}.[\d]{3}-[\d]{3}/

When there are only digits, the capture groups $1, $2 and $3 are taken by the parentheses, in condition before the |:

/^([\d]{2})([\d]{3})([\d]{3})/
     $1       $2       $3

However, with the formatted number, you fall into this part of Regex:

/^[\d]{2}.[\d]{3}-[\d]{3}/

that has no group, so $1, $2 and $2 are empty.

Taking the two conditions, I merged into one, making the point and the dash optional, through the operator *. See below:

window.onload=function(){
	document.getElementById("botao").onclick=function(){
		var strCEP = document.getElementById("cep").value;

		cep.value = formatarCEP(strCEP);
	}
}

function formatarCEP(str){
	var re = /^([\d]{2})\.*([\d]{3})-*([\d]{3})/; // Pode usar ? no lugar do *

	if(re.test(str)){
		return str.replace(re,"$1.$2-$3");
	}else{
		alert("CEP inválido!");
	}
	
	return "";
}
<!DOCTYPE html>
<html lang="pt-BR">
	<head>
		<meta charset="utf-8"/>
		<title>Página Teste</title>
		<script type="text/javascript" src="js/script.js"></script>
	</head>
	<body>
		<div>
			<label for="cep">CEP: <input type="text" id="cep" maxlength="8" /></label>
		</div>
		<p>
			<button id="botao">Testar</button>
		</p>
	</body>
</html>

Important to note that this use of Regex is very limited. I probably in its place would work on these points:

  1. Accept more characters in the field, making it easier for the user to use copy & Paste, that often comes with extra spaces, and undue characters.

  2. Discard every character that is not a digit, since it will be formatted anyway.

  3. Would not use Regex. Regex is a resource that serves when simpler solutions do not solve. In your case, it can be solved with string operations.

  • I like your example. Very good, my intention would be to use both Regex and compare using "|", but it didn’t even occur to me to use "*". Thanks for the help!

2

Change the regular expression to that form:

/^([\d]{2})\.?([\d]{3})\-?([\d]{3})/

Where the metacharacter ? indicates in this expression that the existence of characters . e - are not required for validation of it, but are optional, with occurrence of zero or a character.

You could also use this way below with the metacharacter *, it would work, but it would have a small error, where ZIP codes such as this 11...000--000 will also be valid, because the quantifier metacharacter * checks to be the string has the occurrence of zero the most characters.

In your code snippet do not realize this error because of the character limitation of input text.

/^([\d]{2})\.*([\d]{3})\-*([\d]{3})/

window.onload=function(){
	document.getElementById("botao").onclick=function(){
		var strCEP = document.getElementById("cep").value;

		cep.value = formatarCEP(strCEP);
	}
}

function formatarCEP(str){
	var re = /^([\d]{2})\.?([\d]{3})\-?([\d]{3})/;

	if(re.test(str)){
		return str.replace(re,"$1.$2-$3");
	}else{
		alert("CEP inválido!");
	}
	
	return '';
}
<!DOCTYPE html>
<html lang="pt-BR">
	<head>
		<meta charset="utf-8"/>
		<title>Página Teste</title>
		<script type="text/javascript" src="js/script.js"></script>
	</head>
	<body>
		<div>
			<label for="cep">CEP: <input type="text" id="cep" maxlength="8" /></label>
		</div>
		<p>
			<button id="botao">Testar</button>
		</p>
	</body>
</html>

  • Yure, I thought it was cool that you switched the quantifiers. I actually saw this mistake that you mentioned, but I didn’t know how to fix it. Thank you for your help!

1

follows the validation of the zip code in JQUERY

----------HTML

<div>
            <label for="cep">CEP: <input type="text" id="cep" ></label>
        </div>
        <p>
            <button id="botao">Testar</button>
        </p>

------------SCRIPT

function validarCep()
{
    var patt = new RegExp(/^([\d]{2})([\d]{3})([\d]{3})|^[\d]{2}.[\d]{3}-[\d]{3}/);
    str = $('#cep').val();    
    var res = patt.test(str);    

    if (!res)    
    {
        alert(res);   
        return false;
    }else{


        return true;    
        }
}

$("#botao").click(function(event) {

var ok = validarCep();

    if (ok == true)
    {
        alert("CEP VALIDO. ESCREVA SEU CODIGO AQUI............");
    }

});
  • Leandro I liked your example, it’s very practical. I’ll leave it in favorites for projects I use jQuery. It’s very simple and objective. Thank you!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.