11import Regex.Regex.Matches
22import Regex.Regex.Captures
33
4- open String (Pos )
4+ open String (ValidPos Slice )
55
66namespace Regex
77
@@ -12,7 +12,7 @@ Finds the first match of a regex pattern in a string.
1212* `haystack`: The input string to search in
1313* Returns: An optional substring representing the match, or `none` if no match is found
1414 -/
15- def find (regex : Regex) (haystack : String) : Option Substring :=
15+ def find (regex : Regex) (haystack : String) : Option Slice :=
1616 regex.matches haystack |>.next? |>.map Prod.fst
1717
1818/--
@@ -22,14 +22,14 @@ Finds all matches of a regex pattern in a string.
2222* `haystack`: The input string to search in
2323* Returns: An array of all matched substrings
2424 -/
25- def findAll (regex : Regex) (haystack : String) : Array Substring :=
25+ def findAll (regex : Regex) (haystack : String) : Array Slice :=
2626 go (regex.matches haystack) #[]
2727where
28- go (m : Matches) (accum : Array Substring ) : Array Substring :=
28+ go (m : Matches haystack ) (accum : Array Slice ) : Array Slice :=
2929 match _h : m.next? with
3030 | some (pos, m') => go m' (accum.push pos)
3131 | none => accum
32- termination_by m.remaining
32+ termination_by m
3333
3434/--
3535Transforms the first match of a regex pattern using its capture groups.
@@ -39,11 +39,13 @@ Transforms the first match of a regex pattern using its capture groups.
3939* `transformer`: The rule yielding the string to replace the match with
4040* Returns: The modified string, or the original string if no match is found
4141 -/
42- def transform (regex : Regex) (haystack : String) (transformer : CapturedGroups → String) : String :=
42+ def transform (regex : Regex) (haystack : String) (transformer : CapturedGroups haystack → String) : String :=
4343 match h : (regex.captures haystack).next? with
44- | some (g,_) =>
45- let s := g.get 0 |>.get (Captures.zeroth_group_some_of_next?_some h)
46- Pos.Raw.extract haystack 0 s.startPos ++ transformer g ++ Pos.Raw.extract haystack s.stopPos haystack.endPos
44+ | some (g, _) =>
45+ match h' : g.get 0 , Captures.zeroth_group_some_of_next?_some h with
46+ | some s, _ =>
47+ have eq : s.str = haystack := CapturedGroups.get_str_eq_some h'
48+ ValidPos.extract haystack.startValidPos (s.startInclusive.cast eq) ++ transformer g ++ ValidPos.extract (s.endExclusive.cast eq) haystack.endValidPos
4749 | none => haystack
4850
4951/--
@@ -54,17 +56,19 @@ Transforms all matches of a regex pattern using its capture groups.
5456* `transformer`: The rule yielding the string to replace the match with
5557* Returns: The modified string, or the original string if no matches are found
5658 -/
57- def transformAll (regex : Regex) (haystack : String) (transformer : CapturedGroups → String) : String :=
58- go (regex.captures haystack) "" 0
59+ def transformAll (regex : Regex) (haystack : String) (transformer : CapturedGroups haystack → String) : String :=
60+ go (regex.captures haystack) "" haystack.startValidPos
5961where
60- go (c : Captures) (accum : String) (endPos : Pos.Raw ) : String :=
62+ go (c : Captures haystack ) (accum : String) (endPos : ValidPos haystack ) : String :=
6163 match h : c.next? with
6264 | some (g, c') =>
63- let s := g.get 0 |>.get (Captures.zeroth_group_some_of_next?_some h)
64- go c' (accum ++ Pos.Raw.extract haystack endPos s.startPos ++ transformer g) s.stopPos
65+ match h' : g.get 0 , Captures.zeroth_group_some_of_next?_some h with
66+ | some s, _ =>
67+ have eq : s.str = haystack := CapturedGroups.get_str_eq_some h'
68+ go c' (accum ++ ValidPos.extract endPos (s.startInclusive.cast eq) ++ transformer g) (s.endExclusive.cast eq)
6569 | none =>
66- accum ++ Pos.Raw. extract haystack endPos haystack.endPos
67- termination_by c.remaining
70+ accum ++ ValidPos. extract endPos haystack.endValidPos
71+ termination_by c
6872
6973/--
7074Replaces the first match of a regex pattern with a replacement string.
@@ -96,7 +100,7 @@ Captures the first match of a regex pattern in a string, including capture group
96100* Returns: An optional `CapturedGroups` containing the match and its capture groups,
97101 or `none` if no match is found
98102 -/
99- def capture (regex : Regex) (haystack : String) : Option CapturedGroups :=
103+ def capture (regex : Regex) (haystack : String) : Option ( CapturedGroups haystack) :=
100104 regex.captures haystack |>.next? |>.map Prod.fst
101105
102106/--
@@ -106,14 +110,14 @@ Captures all matches of a regex pattern in a string, including capture groups.
106110* `haystack`: The input string to search in
107111* Returns: An array of `CapturedGroups`, each containing a match and its capture groups
108112 -/
109- def captureAll (regex : Regex) (haystack : String) : Array CapturedGroups :=
113+ def captureAll (regex : Regex) (haystack : String) : Array ( CapturedGroups haystack) :=
110114 go (regex.captures haystack) #[]
111115where
112- go (m : Captures) (accum : Array CapturedGroups) : Array CapturedGroups :=
116+ go (m : Captures haystack ) (accum : Array ( CapturedGroups haystack)) : Array ( CapturedGroups haystack) :=
113117 match _h : m.next? with
114118 | some (groups, m') => go m' (accum.push groups)
115119 | none => accum
116- termination_by m.remaining
120+ termination_by m
117121
118122/--
119123Extracts the first regex match in a string.
@@ -123,7 +127,7 @@ Extracts the first regex match in a string.
123127* Returns: An optional string if a the match is found, or `none` otherwise
124128 -/
125129def extract (regex : Regex) (haystack : String) : Option String :=
126- regex.find haystack |>.map Substring.toString
130+ regex.find haystack |>.map Slice.copy
127131
128132/--
129133Extracts all regex matches in a string.
@@ -133,7 +137,7 @@ Extracts all regex matches in a string.
133137* Returns: an array containing all regex matches occuring in a string
134138 -/
135139def extractAll (regex : Regex) (haystack : String) : Array String :=
136- regex.findAll haystack |>.map Substring.toString
140+ regex.findAll haystack |>.map Slice.copy
137141
138142/--
139143Tests if a regex matches a string.
@@ -162,15 +166,21 @@ Splits a string using regex matches as breakpoints.
162166* `haystack`: The input string to search in
163167* Returns: an array containing the substrings in between the regex matches
164168 -/
165- def split (regex : Regex) (haystack : String) : Array Substring :=
166- go (regex.matches haystack) #[] 0
169+ def split (regex : Regex) (haystack : String) : Array Slice :=
170+ go (regex.matches haystack) #[] haystack.startValidPos
167171where
168- go (m : Matches) (accum : Array Substring ) (endPos : Pos.Raw ) : Array Substring :=
169- match _h : m.next? with
172+ go (m : Matches haystack ) (accum : Array Slice ) (endPos : ValidPos haystack ) : Array Slice :=
173+ match h : m.next? with
170174 | some (s, m') =>
171- go m' (accum.push ⟨haystack, endPos, s.startPos⟩) s.stopPos
175+ have eq : s.str = haystack := Matches.str_eq_of_next?_some h
176+ let startPos := s.startInclusive.cast eq
177+ if le : endPos ≤ startPos then
178+ go m' (accum.push ⟨haystack, endPos, startPos, le⟩) (s.endExclusive.cast eq)
179+ else
180+ -- This should never happen
181+ go m' accum (s.endExclusive.cast eq)
172182 | none =>
173- accum.push ⟨ haystack, endPos, haystack.endPos⟩
174- termination_by m.remaining
183+ accum.push ( haystack.replaceStart endPos)
184+ termination_by m
175185
176186end Regex
0 commit comments