1 /**
2 This module implements functions for validating and extracting the parts of regular expressions
3 between '/'s.
4 
5 ────────────────────────────────────────────────────────────────────────────────
6 
7 Copyright (C) 2021 pillager86.rf.gd
8 
9 This program is free software: you can redistribute it and/or modify it under 
10 the terms of the GNU General Public License as published by the Free Software 
11 Foundation, either version 3 of the License, or (at your option) any later 
12 version.
13 
14 This program is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
16 PARTICULAR PURPOSE.  See the GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License along with 
19 this program.  If not, see <https://www.gnu.org/licenses/>.
20 */
21 module mildew.util.regex;
22 
23 import std.regex: regex, RegexException;
24 
25 /// Extract both parts from a regular expression described by e.g. /foo/g
26 string[] extract(string slashRegex)
27 {
28     if(slashRegex.length < 0 || slashRegex[0] != '/')
29         throw new Exception("Not a regular expression");
30     immutable size_t patternStart = 1;
31     size_t patternEnd;
32     for(auto i = slashRegex.length; i > 0; --i)
33     {
34         if(slashRegex[i-1] == '/')
35         {
36             patternEnd = i - 1;
37             break;
38         }
39     }
40     if(patternEnd == patternStart)
41         throw new Exception("Not a valid regular expression string");
42     string pattern = slashRegex[patternStart..patternEnd];
43     string flags = slashRegex[patternEnd+1..$];
44     return [pattern, flags];
45 }
46 
47 /// Returns true if a Regex is valid and compiles
48 bool isValid(string pattern, string flags)
49 {
50     try 
51     {
52         auto reg = regex(pattern, flags); // @suppress(dscanner.suspicious.unmodified)
53         return true;
54     }
55     catch(RegexException rex)
56     {
57         return false;
58     }
59 }