I'm using Symfony 1.4 and am a little stuck regarding form validation. I have a validator like the one below:
$this->setValidator('mobile_number', new sfValidatorAnd(array(
new sfValidatorString(array('max_length' => 13)),
new sfValidatorRegex(array('pattern' => '/^07\d{9}$/'),
array('invalid' => 'Invalid mobile number.')),
)
));
That is a simple regex for matching a UK mobile phone number.
However my problem is that if someone submitted a string like this: "07 90 44 65 48 1" the regex would fail but they have given a valid number if a the string was cleaned to remove whitespace first.
My problem is that I don't know where within the symfony form framework I would accomplish this.
I need to strip everything but numbers from the user input and then use my mobile_number validator.
Any ideas would be greatly appreciated. Thanks.
You may be able to do this with a combination of standard validators, but it might well be easiest to construct your own custom validator. There is a guide to this on the symfony website: http://www.symfony-project.org/more-with-symfony/1_4/en/05-Custom-Widgets-and-Validators#chapter_05_building_a_simple_widget_and_validator
I think it should probably look something like this:
class sfValidatorMobilePhone extends sfValidatorBase
{
protected function doClean($value)
{
$value = preg_replace('/\s/','',$value);
if (
(0 !== strpos($value, '07')) ||
(13 < strlen($value)) ||
(0 !== preg_match('/[^\d]/', $value))
)
{
throw new sfValidatorError($this, 'invalid', array('value' => $value));
}
else
{
return $value;
}
}
}
Save this as lib/validator/sfValidatorMobilePhone.class.php. You could then call it as
$this->setValidator('mobile_number', new sfValidatorMobilePhone());
I don't know Symfony, so I don't know how you would go about cleaning the input. If you can do a regex-based search-and-replace somehow, you can search for /\D+/ and replace that with nothing - this will remove everything except digits from your string. Careful, it would also remove a leading + which might be relevant (?).
If you can't do a "cleaning step" before the validation, you could try validating it like this:
/^\D*07(?:\d*\d){9}\D*$/
This will match any string that contains exactly 11 numbers (and arbitrarily many non-number characters), the first two of which need to be 07.
Related
I'm using email validation of zend framework and when I give email address as abcde#gester.tech and it responded with invalid validation. Then I modifed the validation as below.
$emailValidator= new Validator\EmailAddress(Validator\Hostname::ALLOW_DNS | Validator\Hostname::ALLOW_LOCAL);
$emailRegex= new Validator\Regex(
array(
'pattern' => '/^(?:(?:[^<>()\[\]\\.,;:\s#"]+(?:\.[^<>()\[\]\\.,;:\s#"]+)*)|(?:".+"))#(?:(?:\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(?:(?:[a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/',
'messages'=>array(
'regexNotMatch'=>'Make sure your email pattern is correct'
)
)
);
$emailInp->getValidatorChain()->addValidator($emailValidator)->addValidator($emailRegex);
Now am able to pass the email address (abcde#gester.tech) with out validation error. But if I give the input as abcde#gester it also take as valid input. But I want to restrict that and I think this can be implemented by adding regex to this validation. May I know how to implement that.
$emailValidator= new Validator\EmailAddress(
Validator\Hostname::ALLOW_DNS |
Validator\Hostname::ALLOW_LOCAL);
$emailRegex= Validator\Regex(array('pattern' => '/^(?:(?:[^<>()\[\]\\.,;:\s#"]+(?:\.[^<>()\[\]\\.,;:\s#"]+)*)|(?:".+"))#(?:(?:\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(?:(?:[a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/'));
$emailInp->getValidatorChain()->addValidator($emailValidator->addValidator($emailRegex));
There is a Regex Validator support in Zend framework which facilitates matching the user-defined regex pattern. There is a pattern option which sets the regular expression pattern for the given validator.
You can use it to match the user-defined validator i.e. the pattern that suits your need.
SYNTAX:
$validator = new Zend\Validator\Regex(array('pattern' => '/your_desired_regex_pattern_here/'));
For matching the valid email address that suits your need you can fill in the pattern with available regex validators for email addresses. Also as per the Zend docs; the regex validator uses PCRE(php) syntax, so you can use PCRE regex flavor.
A sample example:
$validator = new Zend\Validator\Regex(array('pattern' => '/^(?:(?:[^<>()\[\]\\.,;:\s#"]+(?:\.[^<>()\[\]\\.,;:\s#"]+)*)|(?:".+"))#(?:(?:\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(?:(?:[a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/'));
$validator->isValid("abcde#gester.tech"); // returns true
$validator->isValid("abcde#gester"); // returns false
$validator->isValid("Someemail#someDomain.com"); // returns true
If you want to chain multiple validators on a single input data you can also use the below syntax:
$validatorChain = new Zend_Validate();
$validatorChain->addValidator(
new Zend\Validator\Regex(array('pattern' => '/^(?:(?:[^<>()\[\]\\.,;:\s#"]+(?:\.[^<>()\[\]\\.,;:\s#"]+)*)|(?:".+"))#(?:(?:\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(?:(?:[a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/'))
->addValidator(new Zend_Validate_Alnum()); // Second validator...You can chain multiple
if ($validatorChain->isValid($input_email)) {
// email passed validation
} else {
// email failed validation; print reasons
foreach ($validatorChain->getMessages() as $message) {
echo "$message\n";
}
}
You can find the demo of the above regex in here.
Reference: The regex for validating email address is taken from this answer.
I need to send a custom email message to every User of a list ( List < User > ) I have. (I'm using C# .NET)
What I would need to do is to replace all the expressions (that start with "[?&=" have "variableName" in the middle and then ends with "]") with the actual User property value.
So for example if I have a text like this:
"Hello, [?&=Name]. A gift will be sent to [?&=Address], [?&=Zipcode], [?&=Country].
If [?&=Email] is not your email address, please contact us."
I would like to get this for the user:
"Hello, Mary. A gift will be sent to Boulevard Spain 918, 11300, Uruguay.
If marytech#gmail.com is not your email address, please contact us."
Is there a practical and clean way to do this with Regex?
This is a good place to apply regex.
The regular expression you want looks like this /\[\?&=(\w*)\]/ example
You will need to do a replace on the input string using a method that allows you to use a custom function for replacement values. Then inside that function use the first capture value as the Key so to say and pull the correct corresponding value.
Since you did not specify what language you are using I will be nice and give you an example in C# and JS that I made for my own projects just recently.
Pseudo-Code
Loop through matches
Key is in first capture group
Check if replacements dict/obj/db/... has value for the Key
if Yes, return Value
else return ""
C#
email = Regex.Replace(email, #"\[\?&=(\w*)\]",
match => //match contains a Key & Replacements dict has value for that key
match?.Groups[1].Value != null
&& replacements.ContainsKey(match.Groups[1].Value)
? replacements[match.Groups[1].Value]
: "");
JS
var content = text.replace(/\[\?&=(\w*)\]/g,
function (match, p1) {
return replacements[p1] || "";
});
I am trying to enforce strong(er) passwords in my Kohana application using Auth, by using the following regex to require at least one upper case letter, one lower case, one number, one non-alphanum (special character), and a minimum of 8 characters.
^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[^A-Za-z0-9]).{8,}$
The regex is working, as can be seen on Rubular. Here's the code I'm using in Kohana's Model_Auth_User, which extends ORM.
public function rules() {
return array(
'password' => array(
array('not_empty'),
array('min_length', array(':value', 8)),
array('regex', array(':value', '/^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[^A-Za-z0-9]).{8,}$/'))
)
);
}
However, when creating a new user account, or changing the password of an existing one, this regex seems to be completely ignored. The min_length from the line above is working fine though!
It will stop me from using test as a password because it's less than 8 characters, but testing123 doesn't give any sort of error message.
Any ideas why this is happening and a way around it?
Figured it out - you have to add the regex to the get_password_validation function (in the same Model) or it doesn't output any error message.
public static function get_password_validation($values) {
return Validation::factory($values)
->rule('password', 'min_length', array(':value', 8))
->rule('password', 'regex', array(':value', '/^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[^A-Za-z0-9]).{8,}$/'))
->rule('password_confirm', 'matches', array(':validation', ':field', 'password'));
}
If added, the regex in the rules() function needs to be removed or it's not possible to login as it runs the regex check on the hashed string, which doesn't contain any special characters.
Hope this helps someone.
Before i insert the email into the database -> i validate the adress with
if (filter_var($emailAdress, FILTER_VALIDATE_EMAIL))
{
....
}
.. but is this maybe a security flaw?
$userAccObj = $db->user->findOne( array('email' => array('$regex' => '^'.$emailAdress.'$', '$options' => 'i') ));
Schould i do this? or is it not necessary?
$emailAdress= preg_replace("/\#/", '\#', $emailAdress);
$emailAdress= preg_replace("/\-/", '\-', $emailAdress);
$emailAdress= preg_replace("/\./", '\.', $emailAdress);
if (filter_var($emailAdress, FILTER_VALIDATE_EMAIL))
Is a good way to vlaidate an email address in PHP, however, it does use regexes but so far, those have proven to be the best.
$userAccObj = $db->user->findOne( array('email' => array('$regex' => '^'.$emailAdress.'$', '$options' => 'i') ));
The only real problem with that is the . which is a special character which will effect how the regex works, but do you really need to do a regex here? You have checked it is a full email address as such you just need to check for where that exact email address exists (or better yet make a unique index on the field).
As I such I think you can take out the regex and do an exact match.
I have a URL validation method which works pretty well except that this url passes: "http://". I would like to ensure that the user has entered a complete url like: "http://www.stackoverflow.com".
Here is the pattern I'm currently using:
"^(https?://)"
+ "?(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+#)?" //user#
+ #"(([0-9]{1,3}\.){3}[0-9]{1,3}" // IP- 199.194.52.184
+ "|" // allows either IP or domain
+ #"([0-9a-z_!~*'()-]+\.)*" // tertiary domain(s)- www.
+ #"([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\." // second level domain
+ "[a-z]{2,6})" // first level domain- .com or .museum
+ "(:[0-9]{1,4})?" // port number- :80
+ "((/?)|" // a slash isn't required if there is no file name
+ "(/[0-9a-z_!~*'().;?:#&=+$,%#-]+)+/?)$"
Any help to change the above to ensure that the user enters a complete and valid url would be greatly appreciated.
Why not use a urlparsing library? Let me list out some preexisting url parsing libraries for languages:
Python: http://docs.python.org/library/urlparse.html
Perl: http://search.cpan.org/dist/URI/URI/Split.pm
Ruby: http://www.ensta.fr/~diam/ruby/online/ruby-doc-stdlib/libdoc/uri/rdoc/classes/URI.html#M001444
PHP: http://php.net/manual/en/function.parse-url.php
Java: http://download.oracle.com/javase/1.4.2/docs/api/java/net/URI.html#URI(java.lang.String)
C#: http://msdn.microsoft.com/en-us/library/system.uri.aspx
Ask if I'm missing a language.
This way, you could first parse the uri, then check to make sure that it passes your own verification rules. Here's an example in Python:
url = urlparse.urlparse(user_url)
if not (url.scheme and url.path):
raise ValueError("User did not enter a correct url!")
Since you said you were using C# on asp.net, here's an example (sorry, my c# knowledge is limited):
user_url = "http://myUrl/foo/bar";
Uri uri = new Uri(user_url);
if (uri.Scheme == Uri.UriSchemeHttp && Uri.IsWellFormedUriString(user_url, UriKind.RelativeOrAbsolute)) {
Console.WriteLine("I have a valid URL!");
}
This is pretty much a FAQ. You could simply try a search with [regex] +validate +url or just look at this answer: What is the best regular expression to check if a string is a valid URL
I use this regex. It works fine for me.
/((([A-Za-z]{3,9}:(?://)?)(?:[-;:&=+\$,\w]+#)?[A-Za-z0-9.-]+|(?:www.|[-;:&=+\$,\w]+#)[A-Za-z0-9.-]+)((?:/[+~%/.\w-]*)?\??(?:[-+=&;%#.\w])#?(?:[\w]))?)/