mirror of
https://github.com/rust-lang-nursery/rust-cookbook
synced 2024-11-25 13:00:21 +00:00
Cleaned up "Extract phone numbers from text" example
This commit is contained in:
parent
afcc46e5fc
commit
412b70e7b3
1 changed files with 45 additions and 57 deletions
102
src/basics.md
102
src/basics.md
|
@ -652,41 +652,36 @@ fn main() {
|
||||||
<a name="ex-phone"></a>
|
<a name="ex-phone"></a>
|
||||||
## Extract phone numbers from text
|
## Extract phone numbers from text
|
||||||
|
|
||||||
|
[![regex-badge]][regex] [![cat-text-processing-badge]][cat-text-processing]
|
||||||
|
|
||||||
Processes a string of text using [`Regex::captures_iter`] to capture multiple
|
Processes a string of text using [`Regex::captures_iter`] to capture multiple
|
||||||
phone numbers. The example here is for US convention phone numbers.
|
phone numbers. The example here is for US convention phone numbers.
|
||||||
|
|
||||||
```rust, no_run
|
```rust
|
||||||
# #[macro_use]
|
# #[macro_use]
|
||||||
# extern crate error_chain;
|
# extern crate error_chain;
|
||||||
extern crate regex;
|
extern crate regex;
|
||||||
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
#
|
||||||
# error_chain!{
|
# error_chain!{
|
||||||
# foreign_links {
|
# foreign_links {
|
||||||
# Regex(regex::Error);
|
# Regex(regex::Error);
|
||||||
# Io(std::io::Error);
|
# Io(std::io::Error);
|
||||||
# }
|
# }
|
||||||
# }
|
# }
|
||||||
#
|
|
||||||
#[derive(PartialEq, PartialOrd, Debug)]
|
struct PhoneNumber<'a> {
|
||||||
struct PhoneNumber {
|
area: &'a str,
|
||||||
area: &'static str,
|
exchange: &'a str,
|
||||||
exchange: &'static str,
|
subscriber: &'a str,
|
||||||
subscriber: &'static str,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allows printing phone numbers based on country convention.
|
// Allows printing phone numbers based on country convention.
|
||||||
impl fmt::Display for PhoneNumber {
|
impl<'a> fmt::Display for PhoneNumber<'a> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(
|
write!(f, "1 ({}) {}-{}", self.area, self.exchange, self.subscriber)
|
||||||
f,
|
|
||||||
"1 ({}) {}-{}",
|
|
||||||
&self.area,
|
|
||||||
&self.exchange,
|
|
||||||
&self.subscriber
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,56 +692,49 @@ fn run() -> Result<()> {
|
||||||
Alex 5553920011
|
Alex 5553920011
|
||||||
1 (800) 233-2010
|
1 (800) 233-2010
|
||||||
1.299.339.1020";
|
1.299.339.1020";
|
||||||
|
|
||||||
let re = Regex::new(
|
let re = Regex::new(
|
||||||
r"(?x)
|
r#"(?x)
|
||||||
(?:\+?1)? # Country Code Optional
|
(?:\+?1)? # Country Code Optional
|
||||||
[\s\.]?
|
[\s\.]?
|
||||||
(([2-9]\d{2})|\(([2-9]\d{2})\)) # Area Code
|
(([2-9]\d{2})|\(([2-9]\d{2})\)) # Area Code
|
||||||
[\s\.\-]?
|
[\s\.\-]?
|
||||||
([2-9]\d{2}) # Exchange Code
|
([2-9]\d{2}) # Exchange Code
|
||||||
[\s\.\-]?
|
[\s\.\-]?
|
||||||
(\d{4}) #Subscriber Number",
|
(\d{4}) # Subscriber Number"#,
|
||||||
)?;
|
)?;
|
||||||
let mut phone_numbers = re.captures_iter(phone_text).map(|cap| {
|
|
||||||
// Area code populates either capture group 2 or 3. Group 1 contains optional paranthesis.
|
let phone_numbers = re.captures_iter(phone_text).filter_map(|cap| {
|
||||||
PhoneNumber {
|
// Area code populates either capture group 2 or 3.
|
||||||
area: if cap.get(2) == None {
|
// Group 1 contains optional parenthesis.
|
||||||
cap.get(3).map_or("", |m| m.as_str())
|
let groups = (cap.get(2).or(cap.get(3)), cap.get(4), cap.get(5));
|
||||||
} else {
|
match groups {
|
||||||
cap.get(2).map_or("", |m| m.as_str())
|
(Some(area), Some(ext), Some(sub)) => Some(PhoneNumber {
|
||||||
},
|
area: area.as_str(),
|
||||||
exchange: cap.get(4).map_or("", |m| m.as_str()),
|
exchange: ext.as_str(),
|
||||||
subscriber: cap.get(5).map_or("", |m| m.as_str()),
|
subscriber: sub.as_str(),
|
||||||
|
}),
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
}); assert_eq!(
|
});
|
||||||
phone_numbers.next().map(|m| m.to_string()),
|
|
||||||
Some("1 (505) 881-9292".to_owned())
|
|
||||||
);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
phone_numbers.next().map(|m| m.to_string()),
|
phone_numbers.map(|m| m.to_string()).collect::<Vec<_>>(),
|
||||||
Some("1 (505) 778-2212".to_owned())
|
vec![
|
||||||
);
|
"1 (505) 881-9292",
|
||||||
assert_eq!(
|
"1 (505) 778-2212",
|
||||||
phone_numbers.next().map(|m| m.to_string()),
|
"1 (505) 881-9297",
|
||||||
Some("1 (505) 881-9297".to_owned())
|
"1 (202) 991-9534",
|
||||||
);
|
"1 (555) 392-0011",
|
||||||
assert_eq!(
|
"1 (800) 233-2010",
|
||||||
phone_numbers.next().map(|m| m.to_string()),
|
"1 (299) 339-1020",
|
||||||
Some("1 (202) 991-9534".to_owned())
|
]
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
phone_numbers.next().map(|m| m.to_string()),
|
|
||||||
Some("1 (555) 392-0011".to_owned())
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
phone_numbers.next().map(|m| m.to_string()),
|
|
||||||
Some("1 (800) 233-2010".to_owned())
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
#
|
#
|
||||||
# quick_main!(run);
|
# quick_main!(run);
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
[ex-sha-digest]: #ex-sha-digest
|
[ex-sha-digest]: #ex-sha-digest
|
||||||
|
|
Loading…
Reference in a new issue