simple_regex/lib.rs
1//!# Simple Regex Library
2//!
3//!A simple Rust library for building regular expressions.
4//!
5//!## Features
6//!
7//!- **Expressive Builder Pattern:** Easily construct regular expressions using a chainable builder pattern.
8//!- **Concise API:** The API is designed to be concise and intuitive, making it easy to build complex regex patterns.
9//!- **Modifier Support:** Add modifiers like case-insensitive, global search, multiline, and dot-all to your regex patterns.
10//!- **Quantifiers:** Use quantifiers like zero or more, one or more, zero or one, exact repetitions, minimum repetitions, and range repetitions.
11//!- **Ansi Formatting:** Includes an ANSI formatting module for adding color to terminal output.
12//!
13//!## ANSI Module
14//!
15//!### Colors
16//!
17//!- `fg_black(text: String) -> String`: Formats the given text with black foreground color.
18//!- `fg_red(text: String) -> String`: Formats the given text with red foreground color.
19//!- `fg_green(text: String) -> String`: Formats the given text with green foreground color.
20//!- `fg_yellow(text: String) -> String`: Formats the given text with yellow foreground color.
21//!- `fg_blue(text: String) -> String`: Formats the given text with blue foreground color.
22//!- `fg_purple(text: String) -> String`: Formats the given text with purple foreground color.
23//!- `fg_cyan(text: String) -> String`: Formats the given text with cyan foreground color.
24//!- `fg_white(text: String) -> String`: Formats the given text with white foreground color.
25//!
26//!## RegexBuilder Struct
27//!
28//!Builder for constructing regular expressions.
29//!
30//!### Methods
31//!
32//!| Function | Description | Example | Result |
33//!| -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------ |
34//!| `new() -> Self` | Creates a new instance of `RegexBuilder`. | `RegexBuilder::new()` | `RegexBuilder` instance |
35//!| `literal(char) -> Self` | Appends a literal character to the regex. | `.literal('a')` | "a" |
36//!| `dot() -> Self` | Appends a dot (.) to the regex, matching any single character. | `.dot()` | "." |
37//!| `escape(char) -> Self` | Appends an escaped character to the regex. | `.escape('[')` | "\\[" |
38//!| `start_of_line() -> Self` | Appends the start of line anchor (^) to the regex. | `.start_of_line()` | "^" |
39//!| `end_of_line() -> Self` | Appends the end of line anchor ($) to the regex. | `.end_of_line()` | "$" |
40//!| `character_class(chars: &str) -> Self` | Appends a character class to the regex. | `.character_class("abc")` | "\[abc\]" |
41//!| `negated_character_class(chars: &str) -> Self` | Appends a negated character class to the regex. | `.negated_character_class("abc")` | "\[^abc\]" |
42//!| `range_character_class(start: char, end: char) -> Self` | Appends a range character class to the regex. | `.range_character_class('a', 'z')` | "\[a-z\]" |
43//!| `digit() -> Self` | Appends a digit character class to the regex. | `.digit()` | "\\d" |
44//!| `non_digit() -> Self` | Appends a non-digit character class to the regex. | `.non_digit()` | "\\D" |
45//!| `word_character() -> Self` | Appends a word character class to the regex. | `.word_character()` | "\\w" |
46//!| `non_word_character() -> Self` | Appends a non-word character class to the regex. | `.non_word_character()` | "\\W" |
47//!| `whitespace() -> Self` | Appends a whitespace character class to the regex. | `.whitespace()` | "\\s" |
48//!| `non_whitespace() -> Self` | Appends a non-whitespace character class to the regex. | `.non_whitespace()` | "\\S" |
49//!| `zero_or_more(regex: RegexBuilder) -> Self` | Appends a zero or more quantifier to the regex. | `.zero_or_more(RegexBuilder::new().character_class("a"))` | "\[a\]\*" |
50//!| `one_or_more(regex: RegexBuilder) -> Self` | Appends a one or more quantifier to the regex. | `.one_or_more(RegexBuilder::new().character_class("a"))` | "\[a\]+" |
51//!| `zero_or_one(regex: RegexBuilder) -> Self` | Appends a zero or one quantifier to the regex. | `.zero_or_one(RegexBuilder::new().character_class("a"))` | "\[a\]?" |
52//!| `exact_repetitions(regex: RegexBuilder, n: usize) -> Self` | Appends an exact repetitions quantifier to the regex. | `.exact_repetitions(RegexBuilder::new().digit(), 3)` | "\\d{3}" |
53//!| `min_repetitions(regex: RegexBuilder, n: usize) -> Self` | Appends a minimum repetitions quantifier to the regex. | `.min_repetitions(RegexBuilder::new().digit(), 3)` | "\\d{3,}" |
54//!| `range_repetitions(regex: RegexBuilder, n: usize, m: usize) -> Self` | Appends a range repetitions quantifier to the regex. | `.range_repetitions(RegexBuilder::new().digit(), 3, 5)` | "\\d{3,5}" |
55//!| `group(regex: RegexBuilder) -> Self` | Appends a group to the regex. | `.group(RegexBuilder::new().character_class("ab"))` | "(?:\[ab\])" |
56//!| `backreference(group_number: usize) -> Self` | Appends a backreference to a capturing group in the regex. | `.backreference(1)` | "\\1" |
57//!| `word_boundary() -> Self` | Appends a word boundary anchor (\b) to the regex. | `.word_boundary()` | "\\b" |
58//!| `non_word_boundary() -> Self` | Appends a non-word boundary anchor (\B) to the regex. | `.non_word_boundary()` | "\\B" |
59//!| `case_insensitive(regex: RegexBuilder) -> Self` | Appends a case-insensitive modifier to the regex. | `.case_insensitive(RegexBuilder::new().character_class("a"))` | "(?i\[a\])" |
60//!| `global_search(regex: RegexBuilder) -> Self` | Appends a global search modifier to the regex. | `.global_search(RegexBuilder::new().character_class("a"))` | "(?g\[a\])" |
61//!| `multiline(regex: RegexBuilder) -> Self` | Appends a multiline modifier to the regex. | `.multiline(RegexBuilder::new().character_class("a"))` | "(?m\[a\])" |
62//!| `dot_all(regex: RegexBuilder) -> Self` | Appends a dot-all modifier to the regex, allowing '.' to match newline characters. | `.dot_all(RegexBuilder::new().character_class("a"))` | "(?s\[a\])" |
63//!| `alternative(regex1: RegexBuilder, regex2: RegexBuilder) -> Self` | Appends an alternative (\|) to the regex, allowing either of the provided patterns to match. | `.alternative(RegexBuilder::new().character_class("a"), RegexBuilder::new().character_class("b"))` | "\[a\]\|\[b\]" |
64//!| `capturing_group(regex: RegexBuilder) -> Self` | Appends a capturing group to the regex. | `.capturing_group(RegexBuilder::new().character_class("a"))` | "(\[a\])" |
65//!| `to_regex()` | Converts the current `RegexBuilder` into a `Regex` object. | | "Returns a `Result<Regex, regex::Error>`." |
66//!| `to_regex_or_panic()` | Converts the current `RegexBuilder` into a `Regex` object or panics if an error occurs. | | "Returns a `Regex` object." |
67//!
68//!### Examples
69//!
70//!```rust
71//!use simple_regex::RegexBuilder;
72//!
73//!let regex = RegexBuilder::new().literal('a').build();
74//!assert_eq!(regex, "a");
75//!```
76//!
77//!Please make sure to adjust the version number in the dependency based on the latest release.
78
79
80use regex::Regex;
81
82pub mod ansi {
83 const ANSI_RESET: &str = "\x1b[0m";
84 const ANSI_BLACK: &str = "\x1b[30m";
85 const ANSI_RED: &str = "\x1b[31m";
86 const ANSI_GREEN: &str = "\x1b[32m";
87 const ANSI_YELLOW: &str = "\x1b[33m";
88 const ANSI_BLUE: &str = "\x1b[34m";
89 const ANSI_PURPLE: &str = "\x1b[35m";
90 const ANSI_CYAN: &str = "\x1b[36m";
91 const ANSI_WHITE: &str = "\x1b[37m";
92
93 /// Formats the given text with black foreground color.
94 pub fn fg_black(text: String) -> String {
95 format!("{}{}{}", ANSI_BLACK, text, ANSI_RESET)
96 }
97
98 /// Formats the given text with red foreground color.
99 pub fn fg_red(text: String) -> String {
100 format!("{}{}{}", ANSI_RED, text, ANSI_RESET)
101 }
102
103 /// Formats the given text with green foreground color.
104 pub fn fg_green(text: String) -> String {
105 format!("{}{}{}", ANSI_GREEN, text, ANSI_RESET)
106 }
107
108 /// Formats the given text with yellow foreground color.
109 pub fn fg_yellow(text: String) -> String {
110 format!("{}{}{}", ANSI_YELLOW, text, ANSI_RESET)
111 }
112
113 /// Formats the given text with blue foreground color.
114 pub fn fg_blue(text: String) -> String {
115 format!("{}{}{}", ANSI_BLUE, text, ANSI_RESET)
116 }
117
118 /// Formats the given text with purple foreground color.
119 pub fn fg_purple(text: String) -> String {
120 format!("{}{}{}", ANSI_PURPLE, text, ANSI_RESET)
121 }
122
123 /// Formats the given text with cyan foreground color.
124 pub fn fg_cyan(text: String) -> String {
125 format!("{}{}{}", ANSI_CYAN, text, ANSI_RESET)
126 }
127
128 /// Formats the given text with white foreground color.
129 pub fn fg_white(text: String) -> String {
130 format!("{}{}{}", ANSI_WHITE, text, ANSI_RESET)
131 }
132}
133
134/// Builder for constructing regular expressions.
135#[derive(Clone)]
136pub struct RegexBuilder {
137 pub value: String
138}
139
140impl RegexBuilder {
141 /// Creates a new instance of `RegexBuilder`.
142 pub fn new() -> Self {
143 Self {
144 value: String::new()
145 }
146 }
147 /// Converts the current `RegexBuilder` into a `Regex` object.
148 ///
149 /// # Example
150 ///
151 /// ```
152 /// use simple_regex::RegexBuilder;
153 /// use regex::Regex;
154 ///
155 /// let regex_builder = RegexBuilder::new().literal('a');
156 /// let regex_result = regex_builder.to_regex();
157 ///
158 /// match regex_result {
159 /// Ok(regex) => {
160 /// // Use the regex object
161 /// assert!(regex.is_match("a"));
162 /// }
163 /// Err(e) => {
164 /// // Handle the error if the regex is invalid
165 /// eprintln!("Error creating regex: {}", e);
166 /// }
167 /// }
168 /// ```
169 pub fn to_regex(&self) -> Result<Regex, regex::Error> {
170 Regex::new(&self.build())
171 }
172
173 /// Converts the current `RegexBuilder` into a `Regex` object or panics if an error occurs.
174 ///
175 /// # Panics
176 ///
177 /// Panics if the regex construction fails.
178 ///
179 /// # Example
180 ///
181 /// ```
182 /// use simple_regex::RegexBuilder;
183 /// use regex::Regex;
184 ///
185 /// let regex_builder = RegexBuilder::new().literal('a');
186 /// let regex = regex_builder.to_regex_or_panic();
187 ///
188 /// // Use the regex object
189 /// assert!(regex.is_match("a"));
190 /// ```
191 pub fn to_regex_or_panic(&self) -> Regex {
192 self.to_regex().unwrap()
193 }
194
195
196 /// Appends a literal character to the regular expression.
197 ///
198 /// # Example
199 ///
200 /// ```
201 /// use simple_regex::RegexBuilder;
202 ///
203 /// let regex = RegexBuilder::new().literal('a').build();
204 /// assert_eq!(regex, "\\a");
205 /// ```
206 pub fn literal(&mut self, char_: char) -> Self {
207 self.value.push('\\');
208 self.value.push(char_);
209 self.clone()
210 }
211
212
213 /// Appends a string to the regular expression.
214 ///
215 /// # Example
216 ///
217 /// ```
218 /// use simple_regex::RegexBuilder;
219 ///
220 /// let regex = RegexBuilder::new().string("word").build();
221 /// assert_eq!(regex, "word");
222 /// ```
223 pub fn string(&mut self, string: &str) -> Self {
224 self.value.push_str(string);
225 self.clone()
226 }
227
228 /// Appends a dot (.) to the regular expression, matching any single character.
229 ///
230 /// # Example
231 ///
232 /// ```
233 /// use simple_regex::RegexBuilder;
234 ///
235 /// let regex = RegexBuilder::new().dot().build();
236 /// assert_eq!(regex, ".");
237 /// ```
238 pub fn dot(&mut self) -> Self {
239 self.value.push('.');
240 self.clone()
241 }
242
243 /// Appends an escaped character to the regular expression.
244 ///
245 /// # Example
246 ///
247 /// ```
248 /// use simple_regex::RegexBuilder;
249 ///
250 /// let regex = RegexBuilder::new().escape('[').build();
251 /// assert_eq!(regex, "\\[");
252 /// ```
253 pub fn escape(&mut self, char_: char) -> Self {
254 self.value.push('\\');
255 self.value.push(char_);
256 self.clone()
257 }
258
259 /// Appends the start of line anchor (^) to the regular expression.
260 ///
261 /// # Example
262 ///
263 /// ```
264 /// use simple_regex::RegexBuilder;
265 ///
266 /// let regex = RegexBuilder::new().start_of_line().build();
267 /// assert_eq!(regex, "^");
268 /// ```
269 pub fn start_of_line(&mut self) -> Self {
270 self.value.push('^');
271 self.clone()
272 }
273
274 /// Appends the end of line anchor ($) to the regular expression.
275 ///
276 /// # Example
277 ///
278 /// ```
279 /// use simple_regex::RegexBuilder;
280 ///
281 /// let regex = RegexBuilder::new().end_of_line().build();
282 /// assert_eq!(regex, "$");
283 /// ```
284 pub fn end_of_line(&mut self) -> Self {
285 self.value.push('$');
286 self.clone()
287 }
288
289 /// Appends a character class to the regular expression.
290 ///
291 /// # Example
292 ///
293 /// ```
294 /// use simple_regex::RegexBuilder;
295 ///
296 /// let regex = RegexBuilder::new().character_class("abc").build();
297 /// assert_eq!(regex, "[abc]");
298 /// ```
299 pub fn character_class(&mut self, chars: &str) -> Self {
300 self.value.push('[');
301 self.value.push_str(chars);
302 self.value.push(']');
303 self.clone()
304 }
305
306 /// Appends a negated character class to the regular expression.
307 ///
308 /// # Example
309 ///
310 /// ```
311 /// use simple_regex::RegexBuilder;
312 ///
313 /// let regex = RegexBuilder::new().negated_character_class("abc").build();
314 /// assert_eq!(regex, "[^abc]");
315 /// ```
316 pub fn negated_character_class(&mut self, chars: &str) -> Self {
317 self.value.push('[');
318 self.value.push('^');
319 self.value.push_str(chars);
320 self.value.push(']');
321 self.clone()
322 }
323
324 /// Appends a range character class to the regular expression.
325 ///
326 /// # Example
327 ///
328 /// ```
329 /// use simple_regex::RegexBuilder;
330 ///
331 /// let regex = RegexBuilder::new().range_character_class('a', 'z').build();
332 /// assert_eq!(regex, "[a-z]");
333 /// ```
334 pub fn range_character_class(&mut self, start: char, end: char) -> Self {
335 self.value.push('[');
336 self.value.push(start);
337 self.value.push('-');
338 self.value.push(end);
339 self.value.push(']');
340 self.clone()
341 }
342
343 /// Appends a digit character class to the regular expression.
344 ///
345 /// # Example
346 ///
347 /// ```
348 /// use simple_regex::RegexBuilder;
349 ///
350 /// let regex = RegexBuilder::new().digit().build();
351 /// assert_eq!(regex, "\\d");
352 /// ```
353 pub fn digit(&mut self) -> Self {
354 self.value.push_str("\\d");
355 self.clone()
356 }
357
358 /// Appends a non-digit character class to the regular expression.
359 ///
360 /// # Example
361 ///
362 /// ```
363 /// use simple_regex::RegexBuilder;
364 ///
365 /// let regex = RegexBuilder::new().non_digit().build();
366 /// assert_eq!(regex, "\\D");
367 /// ```
368 pub fn non_digit(&mut self) -> Self {
369 self.value.push_str("\\D");
370 self.clone()
371 }
372
373 /// Appends a word character class to the regular expression.
374 ///
375 /// # Example
376 ///
377 /// ```
378 /// use simple_regex::RegexBuilder;
379 ///
380 /// let regex = RegexBuilder::new().word_character().build();
381 /// assert_eq!(regex, "\\w");
382 /// ```
383 pub fn word_character(&mut self) -> Self {
384 self.value.push_str("\\w");
385 self.clone()
386 }
387
388 /// Appends a non-word character class to the regular expression.
389 ///
390 /// # Example
391 ///
392 /// ```
393 /// use simple_regex::RegexBuilder;
394 ///
395 /// let regex = RegexBuilder::new().non_word_character().build();
396 /// assert_eq!(regex, "\\W");
397 /// ```
398 pub fn non_word_character(&mut self) -> Self {
399 self.value.push_str("\\W");
400 self.clone()
401 }
402
403 /// Appends a whitespace character class to the regular expression.
404 ///
405 /// # Example
406 ///
407 /// ```
408 /// use simple_regex::RegexBuilder;
409 ///
410 /// let regex = RegexBuilder::new().whitespace().build();
411 /// assert_eq!(regex, "\\s");
412 /// ```
413 pub fn whitespace(&mut self) -> Self {
414 self.value.push_str("\\s");
415 self.clone()
416 }
417
418 /// Appends a non-whitespace character class to the regular expression.
419 ///
420 /// # Example
421 ///
422 /// ```
423 /// use simple_regex::RegexBuilder;
424 ///
425 /// let regex = RegexBuilder::new().non_whitespace().build();
426 /// assert_eq!(regex, "\\S");
427 /// ```
428 pub fn non_whitespace(&mut self) -> Self {
429 self.value.push_str("\\S");
430 self.clone()
431 }
432
433 /// Appends a zero or more quantifier to the regular expression.
434 ///
435 /// # Example
436 ///
437 /// ```
438 /// use simple_regex::RegexBuilder;
439 ///
440 /// let regex = RegexBuilder::new()
441 /// .zero_or_more(RegexBuilder::new().character_class("a"))
442 /// .build();
443 /// assert_eq!(regex, "[a]*");
444 /// ```
445 pub fn zero_or_more(&mut self, regex: RegexBuilder) -> Self {
446 self.value.push_str(®ex.build());
447 self.value.push('*');
448 self.clone()
449 }
450
451 /// Appends a one or more quantifier to the regular expression.
452 ///
453 /// # Example
454 ///
455 /// ```
456 /// use simple_regex::RegexBuilder;
457 ///
458 /// let regex = RegexBuilder::new()
459 /// .one_or_more(RegexBuilder::new().character_class("a"))
460 /// .build();
461 /// assert_eq!(regex, "[a]+");
462 /// ```
463 pub fn one_or_more(&mut self, regex: RegexBuilder) -> Self {
464 self.value.push_str(®ex.build());
465 self.value.push('+');
466 self.clone()
467 }
468
469 /// Appends a zero or one quantifier to the regular expression.
470 ///
471 /// # Example
472 ///
473 /// ```
474 /// use simple_regex::RegexBuilder;
475 ///
476 /// let regex = RegexBuilder::new()
477 /// .zero_or_one(RegexBuilder::new().character_class("a"))
478 /// .build();
479 /// assert_eq!(regex, "[a]?");
480 /// ```
481 pub fn zero_or_one(&mut self, regex: RegexBuilder) -> Self {
482 self.value.push_str(®ex.build());
483 self.value.push('?');
484 self.clone()
485 }
486
487 /// Appends an exact repetitions quantifier to the regular expression.
488 ///
489 /// # Example
490 ///
491 /// ```
492 /// use simple_regex::RegexBuilder;
493 ///
494 /// let regex = RegexBuilder::new()
495 /// .exact_repetitions(RegexBuilder::new().digit(), 3)
496 /// .build();
497 /// assert_eq!(regex, "\\d{3}");
498 /// ```
499 pub fn exact_repetitions(&mut self, regex: RegexBuilder, n: usize) -> Self {
500 self.value.push_str(&format!("{}{{{}}}", regex.build(), n));
501 self.clone()
502 }
503
504 /// Appends a minimum repetitions quantifier to the regular expression.
505 ///
506 /// # Example
507 ///
508 /// ```
509 /// use simple_regex::RegexBuilder;
510 ///
511 /// let regex = RegexBuilder::new()
512 /// .min_repetitions(RegexBuilder::new().digit(), 3)
513 /// .build();
514 /// assert_eq!(regex, "\\d{3,}");
515 /// ```
516 pub fn min_repetitions(&mut self, regex: RegexBuilder, n: usize) -> Self {
517 self.value.push_str(&format!("{}{{{},}}", regex.build(), n));
518 self.clone()
519 }
520
521 /// Appends a range repetitions quantifier to the regular expression.
522 ///
523 /// # Example
524 ///
525 /// ```
526 /// use simple_regex::RegexBuilder;
527 ///
528 /// let regex = RegexBuilder::new()
529 /// .range_repetitions(RegexBuilder::new().digit(), 3, 5)
530 /// .build();
531 /// assert_eq!(regex, "\\d{3,5}");
532 /// ```
533 pub fn range_repetitions(&mut self, regex: RegexBuilder, n: usize, m: usize) -> Self {
534 self.value.push_str(&format!("{}{{{},{}}}", regex.build(), n, m));
535 self.clone()
536 }
537
538 /// Appends a group to the regular expression.
539 ///
540 /// # Example
541 ///
542 /// ```
543 /// use simple_regex::RegexBuilder;
544 ///
545 /// let regex = RegexBuilder::new()
546 /// .group(RegexBuilder::new().character_class("ab"))
547 /// .build();
548 /// assert_eq!(regex, "(?:[ab])");
549 /// ```
550 pub fn group(&mut self, regex: RegexBuilder) -> Self {
551 self.value.push_str("(?:");
552 self.value.push_str(®ex.build());
553 self.value.push(')');
554 self.clone()
555 }
556
557 /// Appends a backreference to a capturing group in the regular expression.
558 ///
559 /// # Example
560 ///
561 /// ```
562 /// use simple_regex::RegexBuilder;
563 ///
564 /// let regex = RegexBuilder::new()
565 /// .capturing_group(RegexBuilder::new().character_class("ab"))
566 /// .backreference(1)
567 /// .build();
568 /// assert_eq!(regex, "([ab])\\1");
569 /// ```
570 pub fn backreference(&mut self, group_number: usize) -> Self {
571 self.value.push_str(&format!("\\{}", group_number));
572 self.clone()
573 }
574
575 /// Appends a word boundary anchor (\b) to the regular expression.
576 ///
577 /// # Example
578 ///
579 /// ```
580 /// use simple_regex::RegexBuilder;
581 ///
582 /// let regex = RegexBuilder::new().word_boundary().build();
583 /// assert_eq!(regex, "\\b");
584 /// ```
585 pub fn word_boundary(&mut self) -> Self {
586 self.value.push_str("\\b");
587 self.clone()
588 }
589
590 /// Appends a non-word boundary anchor (\B) to the regular expression.
591 ///
592 /// # Example
593 ///
594 /// ```
595 /// use simple_regex::RegexBuilder;
596 ///
597 /// let regex = RegexBuilder::new().non_word_boundary().build();
598 /// assert_eq!(regex, "\\B");
599 /// ```
600 pub fn non_word_boundary(&mut self) -> Self {
601 self.value.push_str("\\B");
602 self.clone()
603 }
604
605 /// Appends a case-insensitive modifier to the regular expression.
606 ///
607 /// # Example
608 ///
609 /// ```
610 /// use simple_regex::RegexBuilder;
611 ///
612 /// let regex = RegexBuilder::new()
613 /// .case_insensitive(RegexBuilder::new().character_class("a"))
614 /// .build();
615 /// assert_eq!(regex, "(?i[a])");
616 /// ```
617 pub fn case_insensitive(&mut self, regex: RegexBuilder) -> Self {
618 self.value.push_str(&format!("(?i[{}]", regex.build()));
619 self.clone()
620 }
621
622 /// Appends a global search modifier to the regular expression.
623 ///
624 /// # Example
625 ///
626 /// ```
627 /// use simple_regex::RegexBuilder;
628 ///
629 /// let regex = RegexBuilder::new()
630 /// .global_search(RegexBuilder::new().character_class("a"))
631 /// .build();
632 /// assert_eq!(regex, "(?g[a])");
633 /// ```
634 pub fn global_search(&mut self, regex: RegexBuilder) -> Self {
635 self.value.push_str(&format!("(?g[{}]", regex.build()));
636 self.clone()
637 }
638
639 /// Appends a multiline modifier to the regular expression.
640 ///
641 /// # Example
642 ///
643 /// ```
644 /// use simple_regex::RegexBuilder;
645 ///
646 /// let regex = RegexBuilder::new()
647 /// .multiline(RegexBuilder::new().character_class("a"))
648 /// .build();
649 /// assert_eq!(regex, "(?m[a])");
650 /// ```
651 pub fn multiline(&mut self, regex: RegexBuilder) -> Self {
652 self.value.push_str(&format!("(?m[{}]", regex.build()));
653 self.clone()
654 }
655
656 /// Appends a dot-all modifier to the regular expression, allowing '.' to match newline characters.
657 ///
658 /// # Example
659 ///
660 /// ```
661 /// use simple_regex::RegexBuilder;
662 ///
663 /// let regex = RegexBuilder::new()
664 /// .dot_all(RegexBuilder::new().character_class("a"))
665 /// .build();
666 /// assert_eq!(regex, "(?s[a])");
667 /// ```
668 pub fn dot_all(&mut self, regex: RegexBuilder) -> Self {
669 self.value.push_str(&format!("(?s[{}]", regex.build()));
670 self.clone()
671 }
672
673 /// Appends an alternative (|) to the regular expression, allowing either of the provided patterns to match.
674 ///
675 /// # Example
676 ///
677 /// ```
678 /// use simple_regex::RegexBuilder;
679 ///
680 /// let regex = RegexBuilder::new()
681 /// .alternative(RegexBuilder::new().character_class("a"), RegexBuilder::new().character_class("b"))
682 /// .build();
683 /// assert_eq!(regex, "[a]|[b]");
684 /// ```
685 pub fn alternative(&mut self, regex1: RegexBuilder, regex2: RegexBuilder) -> Self {
686 self.value.push_str(&format!("{}|{}", regex1.build(), regex2.build()));
687 self.clone()
688 }
689
690 /// Appends a capturing group to the regular expression.
691 ///
692 /// # Example
693 ///
694 /// ```
695 /// use simple_regex::RegexBuilder;
696 ///
697 /// let regex = RegexBuilder::new()
698 /// .capturing_group(RegexBuilder::new().character_class("ab"))
699 /// .build();
700 /// assert_eq!(regex, "([ab])");
701 /// ```
702 pub fn capturing_group(&mut self, regex: RegexBuilder) -> Self {
703 self.value.push('(');
704 self.value.push_str(®ex.build());
705 self.value.push(')');
706 self.clone()
707 }
708
709 /// Appends a non-capturing group to the regular expression.
710 ///
711 /// # Example
712 ///
713 /// ```
714 /// use simple_regex::RegexBuilder;
715 ///
716 /// let regex = RegexBuilder::new()
717 /// .non_capturing_group(RegexBuilder::new().character_class("ab"))
718 /// .build();
719 /// assert_eq!(regex, "(?:[ab])");
720 /// ```
721 pub fn non_capturing_group(&mut self, regex: RegexBuilder) -> Self {
722 self.value.push_str("(?:");
723 self.value.push_str(®ex.build());
724 self.value.push(')');
725 self.clone()
726 }
727
728 /// Appends a word boundary anchor (\b) to the regular expression, asserting the position between a word character and a non-word character.
729 ///
730 /// # Example
731 ///
732 /// ```
733 /// use simple_regex::RegexBuilder;
734 ///
735 /// let regex = RegexBuilder::new()
736 /// .bound_word(RegexBuilder::new().character_class("a"))
737 /// .build();
738 /// assert_eq!(regex, "\\b[a]\\b");
739 /// ```
740 pub fn bound_word(&mut self, regex: RegexBuilder) -> Self {
741 self.value.push_str(&format!("\\b[{}]\\b", regex.build()));
742 self.clone()
743 }
744
745 /// Appends a negative word boundary anchor (\B) to the regular expression, asserting a position where a word character is not followed by another word character.
746 ///
747 /// # Example
748 ///
749 /// ```
750 /// use simple_regex::RegexBuilder;
751 ///
752 /// let regex = RegexBuilder::new()
753 /// .negative_word_boundary(RegexBuilder::new().character_class("a"))
754 /// .build();
755 /// assert_eq!(regex, "\\B[a]\\B");
756 /// ```
757 pub fn negative_word_boundary(&mut self, regex: RegexBuilder) -> Self {
758 self.value.push_str(&format!("\\B[{}]\\B", regex.build()));
759 self.clone()
760 }
761
762 /// Appends a positive lookahead assertion to the regular expression, asserting that the given pattern can match next at the current position.
763 ///
764 /// # Example
765 ///
766 /// ```
767 /// use simple_regex::RegexBuilder;
768 ///
769 /// let regex = RegexBuilder::new()
770 /// .positive_lookahead(RegexBuilder::new().character_class("a"))
771 /// .build();
772 /// assert_eq!(regex, "(?=[a])");
773 /// ```
774 pub fn positive_lookahead(&mut self, regex: RegexBuilder) -> Self {
775 self.value.push_str(&format!("(?={})", regex.build()));
776 self.clone()
777 }
778
779 /// Appends a negative lookahead assertion to the regular expression, asserting that the given pattern cannot match next at the current position.
780 ///
781 /// # Example
782 ///
783 /// ```
784 /// use simple_regex::RegexBuilder;
785 ///
786 /// let regex = RegexBuilder::new()
787 /// .negative_lookahead(RegexBuilder::new().character_class("a"))
788 /// .build();
789 /// assert_eq!(regex, "(?![a])");
790 /// ```
791 pub fn negative_lookahead(&mut self, regex: RegexBuilder) -> Self {
792 self.value.push_str(&format!("(?!{})", regex.build()));
793 self.clone()
794 }
795
796 /// Appends a positive lookbehind assertion to the regular expression, asserting that the given pattern can match preceding at the current position.
797 ///
798 /// # Example
799 ///
800 /// ```
801 /// use simple_regex::RegexBuilder;
802 ///
803 /// let regex = RegexBuilder::new()
804 /// .positive_lookbehind(RegexBuilder::new().character_class("a"))
805 /// .build();
806 /// assert_eq!(regex, "(?<=a)");
807 /// ```
808 pub fn positive_lookbehind(&mut self, regex: RegexBuilder) -> Self {
809 self.value.push_str(&format!("(?<={})", regex.build()));
810 self.clone()
811 }
812
813 /// Appends a negative lookbehind assertion to the regular expression, asserting that the given pattern cannot match preceding at the current position.
814 ///
815 /// # Example
816 ///
817 /// ```
818 /// use simple_regex::RegexBuilder;
819 ///
820 /// let regex = RegexBuilder::new()
821 /// .negative_lookbehind(RegexBuilder::new().character_class("a"))
822 /// .build();
823 /// assert_eq!(regex, "(?<!a)");
824 /// ```
825 pub fn negative_lookbehind(&mut self, regex: RegexBuilder) -> Self {
826 self.value.push_str(&format!("(?<!{})", regex.build()));
827 self.clone()
828 }
829
830 /// Appends an optional pattern to the regular expression, allowing the given pattern to match zero or one time.
831 ///
832 /// # Example
833 ///
834 /// ```
835 /// use simple_regex::RegexBuilder;
836 ///
837 /// let regex = RegexBuilder::new()
838 /// .optional(RegexBuilder::new().literal('a'))
839 /// .build();
840 /// assert_eq!(regex, "(a)?");
841 /// ```
842 pub fn optional(&mut self, regex: RegexBuilder) -> Self {
843 self.value.push_str(&format!("({})?", regex.build()));
844 self.clone()
845 }
846
847 /// Appends to the regular expression the character class `[-\s]`.
848 ///
849 /// # Example
850 ///
851 /// ```
852 /// use my_regex_builder::RegexBuilder;
853 ///
854 /// let regex = RegexBuilder::new()
855 /// .literal('-')
856 /// .dash_space_character_class()
857 /// .literal('a')
858 /// .build();
859 /// assert_eq!(regex, "-[-\\s]a");
860 /// ```
861 pub fn dash_space_character_class(&mut self) -> Self {
862 self.value.push_str("[-\\s]");
863 self.clone()
864 }
865
866 /// Builds the regular expression as a string.
867 ///
868 /// # Example
869 ///
870 /// ```
871 /// use simple_regex::RegexBuilder;
872 ///
873 /// let regex = RegexBuilder::new()
874 /// .literal('a')
875 /// .character_class("bc")
876 /// .zero_or_more(RegexBuilder::new().digit())
877 /// .build();
878 /// assert_eq!(regex, "a[bc]*\\d*");
879 /// ```
880 pub fn build(&self) -> String {
881 self.value.clone()
882 }
883}