Log in

View Full Version : Convert URL Function Regex to Email



Webiter
10-27-2011, 12:08 AM
I want to convert a Website URL entry field to an email entry field and ensure proper validation.

The field (function) that I have at the moment is as follows:


function validateURL($str)
{
return preg_match('/(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?/i',$str);

The field (function) that I want to convert to looks something like the following:


function validate email($str)
{
return preg_match(^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$',$str);

Does this Regex conversion look correct ?:o

djr33
10-27-2011, 01:01 AM
I'm not great with regex so I can't tell you if that's correct, but why haven't you searched for this? There are about 4 million results from google searching for "regex email" :) and many of the examples look like they'll work-- when I need one I use that. I haven't actually figured out what is the "best" way, but they all seem to work in most cases. Be sure it's a fairly complicated one so that it doesn't exclude, for example "a.b@c.d.e" because of the extra dots.

bluewalrus
10-27-2011, 04:05 AM
Are you trying to allow all email addresses or specific ones to your domain? Emails can have more than just A-0 and still be valid.

The simplest regex I can think of would be something like (untested)


preg_match('.*?@.*?\...*', $str)

This requires something before an @, something else after, a period, and some character after it. As djr33 has stated there are hundreds of examples of these on google. If you find one and want it more specific or altered in someway please post that.

james438
10-27-2011, 06:30 AM
Regex does have certain limitations. One limitation is that it does not work well with validating email addresses. It is like trying to find a perpetual motion device or reaching absolute 0. You just can't do it. You can't even get close.

The closer you get to matching 80% of emails the more impractical it becomes, because then you have extremely long expressions. If you have a regex that matches 50% or so of the more common emails then count yourself lucky.

emails do have a certain format that they must follow: RFC 2822 (http://www.faqs.org/rfcs/rfc2822.html). (The link is too long to read, but I wanted to post it as a reference)

The best one I have goes something like this:


<?php
$test='abc@domain.info';
if(preg_match('/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/i',
$test)) {echo "YES";}
else {echo "NO";}
?>

I have not tested it very extensively, but it works well enough. I have modified the original version somewhat.

Here is a post from the regex experts that has been the most useful in explaining this issue: http://regexadvice.com/forums/thread/35974.aspx (http://regexadvice.com/forums/thread/35974.aspx)

These people are the most knowledgeable and experienced I have come across when it comes to regular expressions in all programming languages.

NOTE: a.b@c.d.e will fail, but most of the other common emails will not. You probably could edit my little script a little to get it to work though.

djr33
10-27-2011, 06:57 AM
It depends on what you want. Validating an email to some extent is not too difficult: make sure there's some content then @ then some more content that contains a . in the middle. That's it. That won't necessarily block all invalid emails, but it will be close. And unless you absolutely can only have valid addresses, that will work for practical purposes. The main problem, as I see it, is that some try to be too specific (eg a-z0-9).

You can probably eliminate some characters, such as (I believe) Chinese characters in the address. But I'm actually not sure about that, and I think that there's some thought about allowing extended character ranges for domains at some point, so maybe soon that won't work.

And the biggest problem is that even if an email is in a valid format you can't be sure it's real or that it works, or that the person submitting it actually has access to it.
There is a solution to that and one that will prove it exists: send a validation message to that address and include a code; if the user can then insert that code on your page, that means they received the email. It's a common method and it's the only way to prove an email is valid.

But if you're just checking to be sure that an address looks valid, the basics should be fine. I'd recommend against a script that is too precise, though, because I agree that it will miss some things. In my opinion, it's better to let a few fake formats through and not reject any real ones.

Webiter
10-27-2011, 11:08 AM
Thanks Guys for the extensive comment,

I searched and found the expression

^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$

and then installed it as I presented above. My query arose as I do have concerns about the beginning and end as sometimes the preg_match has requirements for some additional characters to be introduced at the beginning and or end. However I could be incorrect.:o

I do like the point about keeping the valadation short and simple and maybe short has more value.:)

Webiter
10-27-2011, 03:00 PM
What is it in this conversion that is causing the operational failure.:mad:

I have used the short form Regex for the email. Hopefully less is more.:)

I am converting from this thankyou.php script which has a field set to accept URL details. Not everyone will have a URL so that is why I am seeking the change to an email facility! The original page with the Donation (http://tutorialzine.com/2010/05/donation-center-php-mysql-paypal-api/) download package is as follows:


<!--thankyou.php with the website field installed-->
<?php

require "config.php";
require "connect.php";

if(isset($_POST['submitform']) && isset($_POST['txn_id']))
{
$_POST['nameField'] = esc($_POST['nameField']);
$_POST['websiteField'] = esc($_POST['websiteField']);
$_POST['messageField'] = esc($_POST['messageField']);

$error = array();

if(mb_strlen($_POST['nameField'],"utf-8")<2)
{
$error[] = 'Please fill in a valid name.';
}

if(mb_strlen($_POST['messageField'],"utf-8")<2)
{
$error[] = 'Please fill in a longer message.';
}

if(!validateURL($_POST['websiteField']))
{
$error[] = 'The URL you entered is invalid.';
}

$errorString = '';
if(count($error))
{
$errorString = join('<br />',$error);
}
else
{
mysql_query(" INSERT INTO dc_comments (transaction_id, name, url, message)
VALUES (
'".esc($_POST['txn_id'])."',
'".$_POST['nameField']."',
'".$_POST['websiteField']."',
'".$_POST['messageField']."'
)");

if(mysql_affected_rows($link)==1)
{
$messageString = '<a href="donate.php">You were added to our donor list! &raquo;</a>';
}
}
}

?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Thank you!</title>

<link rel="stylesheet" type="text/css" href="styles.css" />

</head>

<body class="thankyouPage">

<div id="main">
<h1>Thank you!</h1>
<h2>Add Yourself to our Donor List. You will have you name included in the publication as having provided support.</h2>

<div class="lightSection">
<form action="" method="post">
<div class="field">
<label for="nameField">Name</label>
<input type="text" id="nameField" name="nameField" />
</div>

<div class="field">
<label for="websiteField">Web Site</label>
<input type="text" id="websiteField" name="websiteField" />
</div>

<div class="field">
<label for="messageField">Message</label>
<textarea name="messageField" id="messageField"></textarea>
</div>

<div class="button">
<input type="submit" value="Submit" />
<input type="hidden" name="submitform" value="1" />
<input type="hidden" name="txn_id" value="<?php echo $_POST['txn_id']?>" />
</div>
</form>

<?php
if($errorString)
{
echo '<p class="error">'.$errorString.'</p>';
}
else if($messageString)
{
echo '<p class="success">'.$messageString.'</p>';
}
?>

</div>


</body>
</html>


<?php

function esc($str)
{
global $link;

if(ini_get('magic_quotes_gpc'))
$str = stripslashes($str);

return mysql_real_escape_string(htmlspecialchars(strip_tags($str)),$link);
}

function validateURL($str)
{
return preg_match('/(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:\/~\+#]*[\w\-\@?^=%&amp;\/~\+#])?/i',$str);
}
?>

I have made changes as follows including changing the URL in the mySql tables.sql to 'email'


<!--thankyou.php with the email field installed-->
<?php

require "config.php";
require "connect.php";

if(isset($_POST['submitform']) && isset($_POST['txn_id']))
{
$_POST['nameField'] = esc($_POST['nameField']);
$_POST['emailField'] = esc($_POST['emailField']);
$_POST['messageField'] = esc($_POST['messageField']);

$error = array();

if(mb_strlen($_POST['nameField'],"utf-8")<2)
{
$error[] = 'Please fill in a valid name.';
}

if(mb_strlen($_POST['messageField'],"utf-8")<2)
{
$error[] = 'Please fill in a longer message.';
}

if(!validate_email($_POST['emailField']))
{
$error[] = 'The email you entered may be invalid! Please check same.';
}

$errorString = '';
if(count($error))
{
$errorString = join('<br />',$error);
}
else
{
mysql_query(" INSERT INTO dc_comments (transaction_id, name, email, message)
VALUES (
'".esc($_POST['txn_id'])."',
'".$_POST['nameField']."',
'".$_POST['emailField']."',
'".$_POST['messageField']."'
)");

if(mysql_affected_rows($link)==1)
{
$messageString = '<a href="donate.php">You were added to our donor list! &raquo;</a>';
}
}
}

?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Thank you!</title>

<link rel="stylesheet" type="text/css" href="styles.css" />

</head>

<body class="thankyouPage">

<div id="main">
<h1>Thank you for your support!</h1>
<h2>Add your name to the donor list. </h2>

<div class="lightSection">
<form action="" method="post">
<div class="field">
<label for="nameField">Name</label>
<input type="text" id="nameField" name="nameField" />
</div>

<div class="field">
<label for="emailField">Email</label>
<input type="text" id="websiteField" name="websiteField" />
</div>

<div class="field">
<label for="messageField">Message</label>
<textarea name="messageField" id="messageField"></textarea>
</div>

<div class="button">
<input type="submit" value="Submit" />
<input type="hidden" name="submitform" value="1" />
<input type="hidden" name="txn_id" value="<?php echo $_POST['txn_id']?>" />
</div>
</form>

<?php
if($errorString)
{
echo '<p class="error">'.$errorString.'</p>';
}
else if($messageString)
{
echo '<p class="success">'.$messageString.'</p>';
}
?>

</div>


</body>
</html>


<?php

function esc($str)
{
global $link;

if(ini_get('magic_quotes_gpc'))
$str = stripslashes($str);

return mysql_real_escape_string(htmlspecialchars(strip_tags($str)),$link);
}

function validate_email($str)
{
return preg_match('.*?@.*?\...*', $str);
}
?>

I then ftp'ed and browsed to the Thank You Page (http://www.support.webitry.net/thankyou.php) that I set up on this trial position. When send is clicked I hit wall! The wall being 500 - Internal server error.
There is a problem with the resource you are looking for, and it cannot be displayed.

What is it in this conversion that is causing the operational failure.:mad:

james438
10-27-2011, 05:03 PM
My last post could have been a little more friendly and helpful. Sorry about that.

djr33, in reference to allowing chinese characters in web addresses are you referring to this http://www.icann.org/en/announcements/announcement-30oct09-en.htm ? I'm not sure if this has been enacted yet or not though.

As far as a practical email regex, I'd say that is plausible if you consider that the majority use gmail, hotmail and the like. There are a great deal of fringe email addresses, which will fail. The operative word in the last sentence was "fringe" as in very uncommon.

Here is another small post from Twey on the issue: http://www.dynamicdrive.com/forums/showthread.php?t=39725