I want to validate a email using clojure. How can I do it.
(defn validate-email [email]
)
I want to know how will be the function body writeen using regular expressions.
I want to validate a email using clojure. How can I do it.
(defn validate-email [email]
)
I want to know how will be the function body writeen using regular expressions.
Here is an example of a simple function that will check input email
string against simple regexp:
(defn validate-email [email]
(re-matches #".+\@.+\..+" email))
It will return input email
if it matches .+\@.+\..+
regexp and nil
otherwise:
(validate-email "foo@bar.baz") ;=> "foo@bar.baz"
(validate-email "invalid") ;=> nil
(if (validate-email "foo@bar.baz") :valid :invalid) ;=> :valid
(if (validate-email "invalid") :valid :invalid) ;=> :invalid
And if you need a good regexp to match emails against, see Using a regular expression to validate an email address.
(defn validate-email
[email]
(let [pattern #"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?"]
(and (string? email) (re-matches pattern email))))
As far as regular expressions in Clojure, this might help: http://www.lispcast.com/clojure-regex
Or, funcool/struct can be used to validate email, beside other things.
Note that using a regular expression to identify 'good' or legitimate email addresses is notoriously difficult to get right. There are a number of edge cases which are easily overlooked. It has gotten a lot easier since some of the more arcane mail routing approaches have dropped out of use, but it can still be tricky.
My advice would be to use something like bouncer which is a validation library which can be used on both the client and server side i.e. for clojure or clojurescript. It has built-in support for email validation. There are numerous other libs which do a similar thing.
This will get you up and running. You can also look at the source code to learn one way this problem can be solved. Later, once you have more experience, you can try doing something similar (but better :-) yourself
Clojure
has a very useful validation library, i.e. the valip
library
If you watch into the predicates.clj
file, you can see that there are the email-address?
and valid-email-domain?
functions and those are exactly for your porpuse.
So you can use it as follows
(defn validate-email [email]
(valid-email-domain? email))
You can use valid-email-domain
for both clojure, and email-address
for both clojure
and clojurescript
.
Here it's the link:
https://github.com/weavejester/valip/blob/master/src/valip/predicates.clj
with other useful validation functions.
There are plenty of discussions on SO and elsewhere of how to match email addresses with regular expressions. It seems to me that what you're asking is how to use regular expressions in Clojure.
The reader recognizes #"
as starting a literal regular expression, ending in "
. Example: #"(t)+"
.
You can also use re-pattern
to compile a regular expression from a string, so you could dynamically create a regular expression pattern like so: (re-pattern (str "^" my-var "$"))
.
If you are trying to use a regular expression to match a string in its entirety, you can use re-matches
. It returns nil
(no match), the original string (it matches), or a vector of [full-string, capture-1, capture-2, ...]
(re-matches #"abc" "abcdefg") ;; => nil
(re-matches #"abc.*" "abcdefg") ;; => "abcdefg"
(re-matches #"abc(.)(.*)" "abcdefg") ;; => ["abcdefg", "d", "efg"]
re-matcher
takes a regular expression and a string and returns a java.util.regex.Matcher
. You can use the find()
method to get the next match, or you can use Clojure's re-find
.
(def my-matcher (re-matcher #"[aeiou].[aeiou]" "alienate"))
(re-find my-matcher) ;; => "ali"
(re-find my-matcher) ;; => "ena"
(re-find my-matcher) ;; => nil
If you are using a Matcher, then you can use re-groups
to get the groups from the most recent match.
Another use of re-find
is with a regular expression and a string to return only the first match:
(re-find #"[aeiou].[aeiou]" "alienate") ;; => "ali"
For many cases, you will find re-seq
to be a more convenient alternative to re-find
with re-matcher
. It returns a lazy sequence of all matches:
(re-seq #"[aeiou].[aeiou]" "alienate") ;; => ("ali", "ena"), lazily
Finally, you can search and replace with replace
and replace-first
. re-quote-replacement
helps with the annoying matter of escaping characters correctly.