I have the below code for matching an email address using regular expression rules.
It works well, but I've recently noticed that it seems to match a "Blank" email address.
if (preg_match("/.* <.*#.*\..*>/i",$this->to,$matches)) {
$this->email_to = preg_replace("/.*<(.*)>.*/","$1",$this->to);
} else {
$this->email_to = $this->to;
}
My understanding of the preg_match is:-
Looks for any character, except a line break
< anycharacter#anything.anything >
Case-insensitive?
Following those rules, I can't quite work out why it matches a blank / no email address if someone can give some guidance.
Thank you.
No needs for preg_match + preg_replace.
if (empty($this->to)) {
$this->email_to = 'Is empty'; # assign what you want
} elseif (preg_match("/<(.+?#.+?\..+?)>/", $this->to, $matches)) {
$this->email_to = $matches[1];
} else {
$this->email_to = $this->to;
}
I don't know why it behaves like that but an easy solution is to ask if the string is blank
if (preg_match("/.* <.*#.*\..*>/i",$this->to,$matches)) {
if ($matches != ""){
$this->email_to = preg_replace("/.*<(.*)>.*/","$1",$this->to);
} else { $this->email_to = $this->to; }
} else {
$this->email_to = $this->to;
}
Related
I'm using this validator:
//validate postcode
function IsPostcode($postcode)
{
$postcode = strtoupper(str_replace(' ','',$postcode));
if(preg_match("/^[A-Z]{1,2}[0-9]{2,3}[A-Z]{2}$/",$postcode) || preg_match("/^[A-Z]{1,2}[0-9]{1}[A-Z]{1}[0-9]{1}[A-Z]{2}$/",$postcode) || preg_match("/^GIR0[A-Z]{2}$/",$postcode))
{
return true;
}
else
{
return false;
}
}
From this link.
But I want to be able to validate postcodes like ME20 and TN10 instead of a full blown ME20 4RN, TN0 4RN. This is the part of the postcode known as the 'outward code'.
Can someone help me out with the regex?
you can use my updated regex to solve you problem
it working from my end to validate UK zip code
<?php
function IsPostcode($postcode)
{
$postcode = strtoupper(str_replace(' ','',$postcode));
if(preg_match("/(^[A-Z]{1,2}[0-9R][0-9A-Z]?[\s]?[0-9][ABD-HJLNP-UW-Z]{2}$)/i",$postcode) || preg_match("/(^[A-Z]{1,2}[0-9R][0-9A-Z]$)/i",$postcode))
{
return true;
}
else
{
return false;
}
}
echo $result = IsPostcode('ME20');
?>
OUTPUT
1
Hope this will sure help you.
I am trying to read all lines from a file and than see if a given string contains any of these lines.
My code
$mails = file('blacklist.txt');
$email = "hendrik#anonbox.net";
$fail = false;
foreach($mails as $mail) {
if(strpos($email, $mail) > 0) {
$fail = true;
}
}
if($fail) {
echo "Fail";
} else {
echo "you can use that";
}
The blacklist.txt can be found here http://pastebin.com/aJyVkcNx.
I would expect strpos return a position for at least one string in the blacklist, but it does not. I am guessing that somehow I am generating not the kind of values within the $mails as I am expecting.
EDIT this is print_r($mails) http://pastebin.com/83ZqVwHx
EDIT2 some clarification: I want to see if a domain is within an email, even if the mail contains subdomain.domain.tld. And I tried to use !== false instead of my > 0 which yielded the same result.
You need to parse the email well since you're checking the domain of the email address if its inside the blacklist. Example:
$email = "hendrik#foo.anonbox.net";
if(filter_var($email, FILTER_VALIDATE_EMAIL)) {
preg_match('/#.*?([^.]+[.]\w{3}|[^.])$/', $email, $matches);
if(!empty($matches) && isset($matches[1])) {
$domain = $matches[1];
} else {
// not good email
exit;
}
// THIS IS FOR SAMPLES SAKE, i know youre using file()
$blacklist = explode("\n", file_get_contents('http://pastebin.com/raw.php?i=aJyVkcNx'));
foreach($blacklist as $email) {
if(stripos($email, $domain) !== false) {
echo 'you are blacklisted';
exit;
}
}
}
// his/her email is ok continue
strpos returns FALSE if the string was not found.'
Simply use this :
$fail = false;
foreach($mails as $mail) {
if(strpos($email, $mail) === false) {
$fail = true;
}
}
Or even better use this:
$blacklist = file_get_contents('blacklist.txt');
$email = "hendrik#anonbox.net";
if(strpos($email, $blacklist) === false){
echo "fail";
} else {
echo "This email is not blacklisted";
}
You have found the common pitfall with the strpos function. The return value of the strpos function refers to the position at which it found the string. In this instance, if the string begins at the first character, it will return 0. Note that 0 !== false.
The correct way to use the function is:
if(strpos($email, $mail) !== false){
// the string was found, potentially at position 0
}
However, this function may not be necessary at all; if you are simply checking if $mail is the same as $email, instead of seeing if the string exists within a larger string, then just use:
if($mail == $email){
// they are the same
}
Though you might still use foreach, that’s array reduce pattern:
function check_against($carry, $mail, $blacklisted) {
return $carry ||= strpos($mail, $blacklisted) !== false;
};
var_dump(array_reduce($mails, "check_against", $email_to_check));
Hope it helps.
Yet another way to solve this. Works fine:
$blacklist = file_get_contents('blacklist.txt');
$email = "hendrik#x.ip6.li";
$domain = substr(trim($email), strpos($email, '#')+1);
if(strpos($blacklist, $domain)){
echo "Your email has been blacklisted!";
}else{
echo "You are all good to go! not blacklisted :-)";
}
Goodluck!
I'm using the Contact Form 7 plugin on wordpress to collect data inputted in the fields, I'm now looking to set up some validation rules using this neat extension: http://code-tricks.com/contact-form-7-custom-validation-in-wordpress/
What I'm after is to only allow one word only in the text field (i.e. no whitespace) and this one word has to begin with the letter 'r' (not case sensitive).
I've written the no white space rule as follows:
//whitespace
if($name == 'WhiteSpace') {
$WhiteSpace = $_POST['WhiteSpace'];
if($WhiteSpace != '') {
if (!preg_match('/\s/',$WhiteSpace)){
$result['valid'] = true;
} else {
$result['valid'] = false;
$result['reason'][$name] = 'Invalid Entry.';
}
}
}
Is it possible to incorporate the second rule into this also? So no whitespace, and the word must begin with the letter 'r'? Any suggestions would be greatly appreciated!
EDIT:
seems core1024 answer does work, but only one of them:
//FirstField
if($name == 'FirstField') {
$FirstField = $_POST['FirstField'];
if($FirstField != '') {
if (!preg_match("/(^[^a]|\s)/i",$FirstField)){
$result['valid'] = true;
} else {
$result['valid'] = false;
$result['reason'][$name] = 'Invalid Entry.';
}
}
}
//__________________________________________________________________________________________________
//SecondField
if($name == 'SecondField') {
$SecondField = $_POST['SecondField'];
if($SecondField != '') {
if (!preg_match("/(^[^r]|\s)/i", $SecondField)) {
$result['valid'] = true;
} else {
$result['valid'] = false;
$result['reason'][$name] = 'Invalid Entry.';
}
}
}
I want to use this code twice, once to validate the first character being a on one field the second instance with the first character being r on another field. But it only seems the SecondField validation rule is working.
Try to use:
preg_match('/^r[^\s]*$/i',$WhiteSpace)
instead of:
!preg_match('/\s/',$WhiteSpace)
You need this:
if (!preg_match("/(^[^r]|\s)/i", $WhiteSpace)) {
It matches any string that doesn't start with r/R or contain space.
Here's a test:
$test = array(
'sad',
'rad',
'ra d'
);
foreach($test as $str) {
echo '"'.$str.'" -> '.preg_match('/(^[^r]|\s)/i', $str).'<br>';
}
And the result:
"sad" -> 1
"rad" -> 0
"ra d" -> 1
This question already has answers here:
How to validate an Email in PHP?
(7 answers)
How to validate an email address in PHP
(15 answers)
Closed 9 years ago.
I want to validate the e-mail domain but I don't want to worry about any possible subdomain that may appears.
For example:
#abc.com
#a.abc.com
#b.abc.com
...
These should all be valid.
Also, I have a list of domains to validate, such as abc.com, xyz.com... how is the best way to validate e-mail domains from a list, including subdomains?
Thanks.
I decided to rewrite this to be more friendly so that you aren't restricted on what type of domain scheme you whitelist.
$whitelist = array("abc.com", "xyz.com", "specific.subdomain.com", "really.specific.subdomain.com"); //You can add basically whatever you want here because it checks for one of these strings to be at the end of the $email string.
$email = "#d.xyz.com";
function validateEmailDomain($email, $domains) {
foreach ($domains as $domain) {
$pos = strpos($email, $domain, strlen($email) - strlen($domain));
if ($pos === false)
continue;
if ($pos == 0 || $email[(int) $pos - 1] == "#" || $email[(int) $pos - 1] == ".")
return true;
}
return false;
}
So, you'd use this like:
if (validateEmailDomain($email, $whitelist))
//Do something.
You can also validate the domain using dns:
function validEmail($email)
{
$allowedDomains = array('abc.com');
list($user, $domain) = explode('#', $email);
if (checkdnsrr($domain, 'MX') && in_array($domain, $allowedDomains))
{
return true;
}
return false;
}
I wrote this function a while back. It may fill the requirements on what you're looking for. It does two things, validates the email address is a valid address and then validates if the domain name is a valid name against it's MX record in DNS.
function validate_email($email) {
// Check email syntax
if(preg_match('/^([a-zA-Z0-9\._\+-]+)\#((\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,7}|[0-9]{1,3})(\]?))$/', $email, $matches)) {
$user = $matches[1];
$domain = $matches[2];
// Check availability of DNS MX records
if(getmxrr($domain, $mxhosts, $mxweight)) {
for($i=0;$i<count($mxhosts);$i++){
$mxs[$mxhosts[$i]] = $mxweight[$i];
}
// Sort the records
asort($mxs);
$mailers = array_keys($mxs);
} elseif(checkdnsrr($domain, 'A')) {
$mailers[0] = gethostbyname($domain);
} else {
$mailers = array();
}
$total = count($mailers);
// Added to still catch domains with no MX records
if($total == 0 || !$total) {
$error = "No MX record found for the domain.";
}
} else {
$error = "Address syntax not correct.";
}
return ($error ? $error : TRUE);
}
I wrote a simple example of the regular expression with the ability to check the list of domain.
<?php
$email = 'shagtv#a.xyz.com';
$domains = array('abc.com', 'xyz.com');
$pattern = "/^[a-z0-9._%+-]+#[a-z0-9.-]*(" . implode('|', $domains) . ")$/i";
if (preg_match($pattern, $email)) {
echo 'valid';
} else {
echo 'not valid';
}
?>
Well you should use some code like this:
<?php
$subject = "abcdef";
$pattern = '/^def/';
preg_match($pattern, substr($subject,3), $matches, PREG_OFFSET_CAPTURE);
print_r($matches);
?>
or this:
<?php
$email = "someone#exa mple.com";
if(!filter_var($email, FILTER_VALIDATE_EMAIL))
{
echo "E-mail is not valid";
}
else
{
echo "E-mail is valid";
}
?>
or this that you have to do a little modify with this page.
Hope it helps!
Very similar to this post: PHP Check domain of email being registered is a 'school.edu' address
However, you need to take it one step further. Once you have that split, look at parse_url
http://php.net/manual/en/function.parse-url.php and grab the HOST part.
i am trying this code for make a validation for a value. (regex from this site)
UPDATE:
Now i have
$value1=250;
$value2=10000;
if (!preg_match("/^(([^0]{1})([0-9])*|(0{1}))(\,\d{2}){0,1}€?$/", $form['salary']) || (!$form['salary'])>$value1."€" && (!$form['salary'])<$value2."€" ){
echo ("invalido");
return false;
}
else
echo ("valido");
return true;
the code works well, but 20€ is accepted, so the problem now is not the regex, but compare values like 200€ or 1000€.
this probably is wrong
(!$form['salary'])>$value1."€"
example some Input values:
200€
200
200.5
200.50€
limits - 250€ to 10000€
thanks
This code below solved my problem:
if (!preg_match("/^(([^0]{1})([0-9])*|(0{1}))(\,\d{2}){0,1}€?$/", $form['salary'])) {
echo "invalid";
return false;
} else {
$value1 = 400;
$value2 = 10000;
$salary = $form['salary'];
$salary = preg_replace('/[€]/i', '', $salary);
if($salary < $value1 || $salary > $value2) {
echo "bad values";
return false;
} else {
echo "valid";
return true;
}
}
The regex solution would look like this
^(?:10000|(?:(?:(?:2[5-9]\d)|[3-9]\d{2}|\d{4})(?:[,.]\d{2})?))€?$
See here online on Regexr
But it would be better for checking if a value belongs to a range, not to use a regex. You can extract the value easily and do a normal <> check on numbers outside.
My contribution. It works great.
final Pattern pattern = Pattern.compile("^([0-9]+)|((([1-9][0-9]*)|([0-9]))([.,])[0-9]{1,2})$");