diff --git a/src/basics.md b/src/basics.md
index ad78327..ac569bb 100644
--- a/src/basics.md
+++ b/src/basics.md
@@ -12,6 +12,7 @@
| [Filter a log file by matching multiple regular expressions][ex-regex-filter-log] | [![regex-badge]][regex] | [![cat-text-processing-badge]][cat-text-processing]
| [Declare lazily evaluated constant][ex-lazy-constant] | [![lazy_static-badge]][lazy_static] | [![cat-caching-badge]][cat-caching] [![cat-rust-patterns-badge]][cat-rust-patterns] |
| [Maintain global mutable state][ex-global-mut-state] | [![lazy_static-badge]][lazy_static] | [![cat-rust-patterns-badge]][cat-rust-patterns] |
+| [Verify and extract login from an email address][ex-verify-extract-email] | [![regex-badge]][regex] | [![cat-text-processing-badge]][cat-text-processing] |
| [Access a file randomly using a memory map][ex-random-file-access] | [![memmap-badge]][memmap] | [![cat-filesystem-badge]][cat-filesystem] |
| [Define and operate on a type represented as a bitfield][ex-bitflags] | [![bitflags-badge]][bitflags] | [![cat-no-std-badge]][cat-no-std] |
| [Extract a list of unique #Hashtags from a text][ex-extract-hashtags] | [![regex-badge]][regex] [![lazy_static-badge]][lazy_static] | [![cat-text-processing-badge]][cat-text-processing] |
@@ -473,6 +474,46 @@ fn run() -> Result<()> {
# quick_main!(run);
```
+[ex-verify-extract-email]: #ex-verify-extract-email
+
+## Verify and extract login from an email address
+
+[![regex-badge]][regex] [![cat-text-processing-badge]][cat-text-processing]
+
+Validates that an email address is formatted correctly, and extracts everything
+before the @ symbol.
+
+```rust
+#[macro_use]
+extern crate lazy_static;
+extern crate regex;
+
+use regex::Regex;
+
+fn extract_login(input: &str) -> Option<&str> {
+ lazy_static! {
+ static ref RE: Regex = Regex::new(r"(?x)
+ ^(?P[^@\s]+)@
+ ([[:word:]]+\.)*
+ [[:word:]]+$
+ ").unwrap();
+ }
+ RE.captures(input).and_then(|cap| {
+ cap.name("login").map(|login| login.as_str())
+ })
+}
+
+fn main() {
+ assert_eq!(extract_login(r"I❤email@example.com"), Some(r"I❤email"));
+ assert_eq!(
+ extract_login(r"sdf+sdsfsd.as.sdsd@jhkk.d.rl"),
+ Some(r"sdf+sdsfsd.as.sdsd")
+ );
+ assert_eq!(extract_login(r"More@Than@One@at.com"), None);
+ assert_eq!(extract_login(r"Not an email@email"), None);
+}
+```
+
[ex-random-file-access]: #ex-random-file-access
## Access a file randomly using a memory map
diff --git a/src/intro.md b/src/intro.md
index 107bcf3..6f7c23a 100644
--- a/src/intro.md
+++ b/src/intro.md
@@ -30,6 +30,7 @@ community. It needs and welcomes help. For details see
| [Filter a log file by matching multiple regular expressions][ex-regex-filter-log] | [![regex-badge]][regex] | [![cat-text-processing-badge]][cat-text-processing]
| [Declare lazily evaluated constant][ex-lazy-constant] | [![lazy_static-badge]][lazy_static] | [![cat-caching-badge]][cat-caching] [![cat-rust-patterns-badge]][cat-rust-patterns] |
| [Maintain global mutable state][ex-global-mut-state] | [![lazy_static-badge]][lazy_static] | [![cat-rust-patterns-badge]][cat-rust-patterns] |
+| [Verify and extract login from an email address][ex-verify-extract-email] | [![regex-badge]][regex] | [![cat-text-processing-badge]][cat-text-processing] |
| [Access a file randomly using a memory map][ex-random-file-access] | [![memmap-badge]][memmap] | [![cat-filesystem-badge]][cat-filesystem] |
| [Define and operate on a type represented as a bitfield][ex-bitflags] | [![bitflags-badge]][bitflags] | [![cat-no-std-badge]][cat-no-std] |
| [Extract a list of unique #Hashtags from a text][ex-extract-hashtags] | [![regex-badge]][regex] [![lazy_static-badge]][lazy_static] | [![cat-text-processing-badge]][cat-text-processing] |
@@ -268,6 +269,7 @@ Keep lines sorted.
[ex-invalid-csv]: encoding.html#ex-invalid-csv
[ex-paginated-api]: net.html#ex-paginated-api
[ex-parse-subprocess-output]: basics.html#ex-parse-subprocess-output
+[ex-verify-extract-email]: basics.html#ex-verify-extract-email
[ex-percent-encode]: encoding.html#ex-percent-encode
[ex-phone]: basics.html#ex-phone
[ex-rand-custom]: basics.html#ex-rand-custom