Skip to content

Commit 6744559

Browse files
committed
Migrate Utilities to ValidPos
1 parent cb8eee8 commit 6744559

2 files changed

Lines changed: 48 additions & 29 deletions

File tree

regex/Regex/Regex/Matches.lean

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@ theorem lt_next?_some' {s : Slice} {m m' : Matches haystack} (h : m.next? = some
4949
unfold next? at h
5050
grind
5151

52+
theorem str_eq_of_next?_some {s : Slice} {m m' : Matches haystack} (h : m.next? = some (s, m')) :
53+
s.str = haystack := by
54+
unfold next? at h
55+
split at h <;> try contradiction
56+
split at h <;> try contradiction
57+
simp only [Option.some.injEq, Prod.mk.injEq] at h
58+
next h' =>
59+
simpa [←h] using searchNext_str_eq_some h'
60+
5261
def lt (m m' : Matches haystack) : Prop := m.currentPos < m'.currentPos
5362

5463
instance : LT (Matches haystack) := ⟨lt⟩

regex/Regex/Regex/Utilities.lean

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Regex.Regex.Matches
22
import Regex.Regex.Captures
33

4-
open String (Pos)
4+
open String (ValidPos Slice)
55

66
namespace 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) #[]
2727
where
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
/--
3535
Transforms 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
5961
where
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
/--
7074
Replaces 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) #[]
111115
where
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
/--
119123
Extracts 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
-/
125129
def extract (regex : Regex) (haystack : String) : Option String :=
126-
regex.find haystack |>.map Substring.toString
130+
regex.find haystack |>.map Slice.copy
127131

128132
/--
129133
Extracts 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
-/
135139
def extractAll (regex : Regex) (haystack : String) : Array String :=
136-
regex.findAll haystack |>.map Substring.toString
140+
regex.findAll haystack |>.map Slice.copy
137141

138142
/--
139143
Tests 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
167171
where
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

176186
end Regex

0 commit comments

Comments
 (0)