easy_regex/group.rs
1//! Creates a group pattern in many different ways as desired.
2//!
3//! This module consists of methods needed to create a group in many different ways, having different options/settings.
4//! The main one is the [`group`](../struct.EasyRegex.html#method.group) method which takes an expression as argument
5//! and a set of meta as ```GroupSettings``` creates a group for it.
6//! Other methods starting with the ```into``` word followed by an underline makes all previously chained expressions into a group.
7//! They mostly take no arguments for settings and are useful to be added to the latter part of a method chain.
8
9use crate::{
10 settings::{GroupSettings, Settings, base::DEFAULT},
11 EasyRegex,
12};
13
14impl EasyRegex {
15 /// Creates a group of expressions.
16 ///
17 /// This method takes an expression (a segment of entire pattern) followed
18 /// by a set of settings (```GroupSettings``` struct) that will be concatenated/inserted to the expression itself,
19 /// outputing the previous pattern followed by this group.
20 ///
21 /// # Examples
22 ///
23 /// ```
24 /// use easy_regex::{EasyRegex, settings::group::OPTIONAL_GROUP};
25 ///
26 /// let result = EasyRegex::new_section().group("expression", &OPTIONAL_GROUP);
27 /// assert_eq!("(expression)?", result.get_regex().unwrap().as_str());
28 /// ```
29 pub fn group(self, expression: &str, group_sttings: &GroupSettings) -> Self {
30 let mut final_result = EasyRegex::new_section();
31
32 // to make the regex itself clearer, this extra if condition is added.
33 if group_sttings.other.flags.is_some() && group_sttings.is_non_capture {
34 final_result.0 = format!(
35 "({}:{})",
36 group_sttings.other.flags.unwrap().as_str(),
37 expression
38 );
39 } else {
40 final_result = final_result
41 .literal(
42 expression,
43 &Settings {
44 flags: group_sttings.other.flags,
45 ..Default::default()
46 },
47 )
48 .into_group(&Settings {
49 flags: None,
50 ..group_sttings.other
51 });
52 if group_sttings.is_non_capture {
53 final_result.0.insert_str(1, "?:");
54 }
55 }
56
57 self.literal(&final_result.0, &DEFAULT)
58 }
59
60 /// Same as the ```group``` method with the option to add a custom name to the group.
61 ///
62 /// # Examples
63 ///
64 /// ```
65 /// use easy_regex::{EasyRegex, settings::group::OPTIONAL_GROUP};
66 ///
67 /// let result = EasyRegex::new_section().named_group("my_group", "expression", &OPTIONAL_GROUP);
68 /// assert_eq!("(?P<my_group>expression)?", result.get_regex().unwrap().as_str());
69 /// ```
70 pub fn named_group(self, name: &str, expression: &str, group_settings: &GroupSettings) -> Self {
71 let final_result = format!("?P<{}>{}", name, expression);
72 self.group(&final_result, &group_settings)
73 }
74
75 /// Turns the previous expressions into a **capturing** group. It uses ```Settings``` struct for the settings parameter.
76 ///
77 /// # Examples
78 ///
79 /// ```
80 /// use easy_regex::{EasyRegex, settings::base::OPTIONAL};
81 ///
82 /// let result = EasyRegex::new(r"\d{3}").into_group(&OPTIONAL);
83 /// assert_eq!(r"(\d{3})?", result.get_regex().unwrap().as_str());
84 /// ```
85 pub fn into_group(self, settings: &Settings) -> Self {
86 let raw_result = format!("({})", self.0);
87 let final_result = EasyRegex(String::new()).literal(&raw_result, &settings);
88 final_result
89 }
90
91 /// A variation of ```into_group``` having *name* option **(?P\<name\>RegExp)**.
92 pub fn into_named_group(self, name: &str, settings: &Settings) -> Self {
93 let raw_result = format!("(?P<{}>{})", name, self.0);
94 let final_result = EasyRegex(String::new()).literal(&raw_result, &settings);
95 final_result
96 }
97
98 /// A variation of ```into_group``` having *non-capturing* option **(?:RegExp)**.
99 pub fn into_non_capturing(self) -> Self {
100 let result = format!("(?:{})", self.0);
101 EasyRegex(result)
102 }
103 ////////////////////////////////////////////////////////////////
104 /// A variation of ```into_group``` having *Insensitive* flag **(?i)**.
105 pub fn into_insensitive_group(self) -> Self {
106 let result = format!("((?i){})", self.0);
107 EasyRegex(result)
108 }
109
110 /// A variation of ```into_group``` having *Multiline* flag **(?m)**.
111 pub fn into_multline_group(self) -> Self {
112 let result = format!("((?m){})", self.0);
113 EasyRegex(result)
114 }
115
116 /// A variation of ```into_group``` having *Dot All* flag **(?s)**.
117 pub fn into_dot_match_newline_group(self) -> Self {
118 let result = format!("((?s){})", self.0);
119 EasyRegex(result)
120 }
121
122 /// A variation of ```into_group``` ignoring *whitespaces* **(?x)**.
123 pub fn into_ignore_whitespace_group(self) -> Self {
124 let result = format!("((?x){})", self.0);
125 EasyRegex(result)
126 }
127 ////////////////////////////////////////////////////////////////
128 /// A variation of ```into_non_capturing``` having *Insensitive* flag **(?i)**.
129 pub fn into_insensitive_non_capturing(self) -> Self {
130 let result = format!("(?i:{})", self.0);
131 EasyRegex(result)
132 }
133
134 /// A variation of ```into_non_capturing``` having *Multiline* flag **(?m)**.
135 pub fn into_multiline_non_capturing(self) -> Self {
136 let result = format!("(?m:{})", self.0);
137 EasyRegex(result)
138 }
139
140 /// A variation of ```into_non_capturing``` having *Dot All* flag **(?s)**.
141 pub fn into_dot_match_newline_non_capturing(self) -> Self {
142 let result = format!("(?s:{})", self.0);
143 EasyRegex(result)
144 }
145
146 /// A variation of ```into_non_capturing``` ignoring *whitespaces* **(?x)**.
147 pub fn into_ignore_whitespace_non_capturing(self) -> Self {
148 let result = format!("(?x:{})", self.0);
149 EasyRegex(result)
150 }
151 ////////////////////////////////////////////////////////////////
152 /// A variation of ```into_group``` having *Insensitive* flag cleared **(?-i)**.
153 pub fn into_sensitive_group(self) -> Self {
154 let result = format!("((?-i){})", self.0);
155 EasyRegex(result)
156 }
157
158 /// A variation of ```into_group``` having *Multiline* flag cleared **(?-m)**.
159 pub fn into_single_line_group(self) -> Self {
160 let result = format!("((?-m){})", self.0);
161 EasyRegex(result)
162 }
163
164 /// A variation of ```into_group``` having *Dot All* flag cleared **(?-s)**.
165 pub fn into_dot_dismatch_newline_group(self) -> Self {
166 let result = format!("((?-s){})", self.0);
167 EasyRegex(result)
168 }
169
170 /// A variation of ```into_group``` taking *whitespaces* into account **(?-x)**.
171 pub fn into_include_whitespace_group(self) -> Self {
172 let result = format!("((?-x){})", self.0);
173 EasyRegex(result)
174 }
175 ////////////////////////////////////////////////////////////////
176 /// A variation of ```into_non_capturing``` having *Insensitive* flag cleared **(?-i)**.
177 pub fn into_sensitive_non_capturing(self) -> Self {
178 let result = format!("(?-i:{})", self.0);
179 EasyRegex(result)
180 }
181
182 /// A variation of ```into_non_capturing``` having *Multiline* flag cleared **(?-m)**.
183 pub fn into_single_line_non_capturing(self) -> Self {
184 let result = format!("(?-m:{})", self.0);
185 EasyRegex(result)
186 }
187
188 /// A variation of ```into_non_capturing``` having *Dot All* flag cleared **(?-s)**.
189 pub fn into_dot_dismatch_newline_non_capturing(self) -> Self {
190 let result = format!("(?-s:{})", self.0);
191 EasyRegex(result)
192 }
193
194 /// A variation of ```into_non_capturing``` taking *whitespaces* into account **(?-x)**.
195 pub fn into_include_whitespace_non_capturing(self) -> Self {
196 let result = format!("(?-x:{})", self.0);
197 EasyRegex(result)
198 }
199}
200
201#[cfg(test)]
202mod tests {
203 use self::EasyRegex;
204 use super::*;
205 use crate::settings::group::{DEFAULT_GROUP, INSENSITIVE_GROUP, INSENSITIVE_NON_CAPTURE};
206
207 #[test]
208 fn group_works() {
209 let initial_exp = EasyRegex::new("initial_");
210 let result = initial_exp.group("group", &DEFAULT_GROUP);
211 assert_eq!("initial_(group)", result.0);
212 }
213
214 #[test]
215 fn optional_non_capture_group_works() {
216 let initial_exp = EasyRegex::start_of_line();
217 let group_settings = GroupSettings {
218 other: Settings {
219 is_optional: true,
220 ..Default::default()
221 },
222 is_non_capture: true,
223 };
224
225 let result = initial_exp.group("group", &group_settings);
226 assert_eq!("^(?:group)?", result.0);
227 }
228
229 #[test]
230 fn insensitive_group_works() {
231 let result = EasyRegex::start_of_line()
232 .group("group", &INSENSITIVE_GROUP)
233 .get_regex()
234 .unwrap();
235 assert_eq!("^((?i)group)", result.as_str());
236 }
237
238 #[test]
239 fn insensitive_non_capturing_group_works() {
240 let result = EasyRegex::start_of_line()
241 .group("group", &INSENSITIVE_NON_CAPTURE)
242 .get_regex()
243 .unwrap();
244 assert_eq!("^(?i:group)", result.as_str());
245 }
246
247 #[test]
248 fn into_group_works() {
249 let initial_exp = EasyRegex::new("group");
250 let result = initial_exp.into_group(&DEFAULT);
251
252 assert_eq!("(group)", result.0);
253 }
254
255 ////////////////////////////////////////////////// ERRORS /////////////////////////////////////////////////////
256 // #[test]
257 // fn into_negative_group_added_optional_exp_not_works() {
258 // let initial_exp = MetaFuncRegex::new("group");
259 // let result = initial_exp
260 // // .into_negative_group()
261 // .literal_exp(&String::new(), &OPTIONAL);
262 // let err = result.get_regex().unwrap_err();
263 // let re = regex::Regex::new("/(?!group)/").unwrap();
264 // // regex::Regex::is_matchbuild(&re).unwrap();
265 // // println!("{}", &after);
266 // assert_eq!(
267 // regex::Error::Syntax(
268 // "regex parse error:
269 // (?!group)?
270 // ^^^
271 // error: look-around, including look-ahead and look-behind, is not supported"
272 // .to_string()
273 // ),
274 // err
275 // );
276 // }
277
278 // #[test]
279 // fn optional_negative_group_not_works() {
280 // let initial_exp = MetaFuncRegex::new("^");
281 // let group_settings = GroupSettings {
282 // other: Settings {
283 // is_optional: true,
284 // ..Default::default()
285 // },
286 // is_non_capture: false,
287 // flags: None,
288 // };
289
290 // let result = initial_exp.group("group", &group_settings);
291 // let err = result.get_regex().unwrap_err();
292 // assert_eq!(
293 // regex::Error::Syntax(
294 // "regex parse error:
295 // ^(?!group)?
296 // ^^^
297 // error: look-around, including look-ahead and look-behind, is not supported"
298 // .to_string()
299 // ),
300 // err
301 // );
302 // }
303}