12
12
@_implementationOnly import _RegexParser
13
13
@_spi ( RegexBuilder) import _StringProcessing
14
14
15
+ /// A regex component that matches a specific condition at a particular position
16
+ /// in an input string.
17
+ ///
18
+ /// You can use anchors to guarantee that a match only occurs at certain points
19
+ /// in an input string, such as at the beginning of the string or at the end of
20
+ /// a line.
15
21
@available ( SwiftStdlib 5 . 7 , * )
16
22
public struct Anchor {
17
23
internal enum Kind {
@@ -53,14 +59,24 @@ extension Anchor: RegexComponent {
53
59
54
60
@available ( SwiftStdlib 5 . 7 , * )
55
61
extension Anchor {
62
+ /// An anchor that matches at the start of the input string.
63
+ ///
64
+ /// This anchor is equivalent to `\A` in regex syntax.
56
65
public static var startOfSubject : Anchor {
57
66
Anchor ( kind: . startOfSubject)
58
67
}
59
-
68
+
69
+ /// An anchor that matches at the end of the input string or at the end of
70
+ /// the line immediately before the the end of the string.
71
+ ///
72
+ /// This anchor is equivalent to `\Z` in regex syntax.
60
73
public static var endOfSubjectBeforeNewline : Anchor {
61
74
Anchor ( kind: . endOfSubjectBeforeNewline)
62
75
}
63
-
76
+
77
+ /// An anchor that matches at the end of the input string.
78
+ ///
79
+ /// This anchor is equivalent to `\z` in regex syntax.
64
80
public static var endOfSubject : Anchor {
65
81
Anchor ( kind: . endOfSubject)
66
82
}
@@ -70,33 +86,67 @@ extension Anchor {
70
86
// Anchor(kind: resetStartOfMatch)
71
87
// }
72
88
89
+ /// An anchor that matches at the first position of a match in the input
90
+ /// string.
73
91
public static var firstMatchingPositionInSubject : Anchor {
74
92
Anchor ( kind: . firstMatchingPositionInSubject)
75
93
}
76
94
95
+ /// An anchor that matches at a grapheme cluster boundary.
96
+ ///
97
+ /// This anchor is equivalent to `\y` in regex syntax.
77
98
public static var textSegmentBoundary : Anchor {
78
99
Anchor ( kind: . textSegmentBoundary)
79
100
}
80
101
102
+ /// An anchor that matches at the start of a line, including the start of
103
+ /// the input string.
104
+ ///
105
+ /// This anchor is equivalent to `^` in regex syntax when the `m` option
106
+ /// has been enabled or `anchorsMatchLineEndings(true)` has been called.
81
107
public static var startOfLine : Anchor {
82
108
Anchor ( kind: . startOfLine)
83
109
}
84
110
111
+ /// An anchor that matches at the end of a line, including at the end of
112
+ /// the input string.
113
+ ///
114
+ /// This anchor is equivalent to `$` in regex syntax when the `m` option
115
+ /// has been enabled or `anchorsMatchLineEndings(true)` has been called.
85
116
public static var endOfLine : Anchor {
86
117
Anchor ( kind: . endOfLine)
87
118
}
88
119
120
+ /// An anchor that matches at a word boundary.
121
+ ///
122
+ /// Word boundaries are identified using the Unicode default word boundary
123
+ /// algorithm by default. To specify a different word boundary algorithm,
124
+ /// see the `RegexComponent.wordBoundaryKind(_:)` method.
125
+ ///
126
+ /// This anchor is equivalent to `\b` in regex syntax.
89
127
public static var wordBoundary : Anchor {
90
128
Anchor ( kind: . wordBoundary)
91
129
}
92
130
131
+ /// The inverse of this anchor, which matches at every position that this
132
+ /// anchor does not.
133
+ ///
134
+ /// For the `wordBoundary` and `textSegmentBoundary` anchors, the inverted
135
+ /// version corresponds to `\B` and `\Y`, respectively.
93
136
public var inverted : Anchor {
94
137
var result = self
95
138
result. isInverted. toggle ( )
96
139
return result
97
140
}
98
141
}
99
142
143
+ /// A regex component that allows a match to continue only if its contents
144
+ /// match at the given location.
145
+ ///
146
+ /// A lookahead is a zero-length assertion that its included regex matches at
147
+ /// a particular position. Lookaheads do not advance the overall matching
148
+ /// position in the input string — once a lookahead succeeds, matching continues
149
+ /// in the regex from the same position.
100
150
@available ( SwiftStdlib 5 . 7 , * )
101
151
public struct Lookahead < Output> : _BuiltinRegexComponent {
102
152
public var regex : Regex < Output >
@@ -105,19 +155,48 @@ public struct Lookahead<Output>: _BuiltinRegexComponent {
105
155
self . regex = regex
106
156
}
107
157
158
+ /// Creates a lookahead from the given regex component.
108
159
public init < R: RegexComponent > (
109
- _ component: R ,
110
- negative: Bool = false
160
+ _ component: R
111
161
) where R. RegexOutput == Output {
112
- self . init ( node: . nonCapturingGroup(
113
- negative ? . negativeLookahead : . lookahead, component. regex. root) )
162
+ self . init ( node: . nonCapturingGroup( . lookahead, component. regex. root) )
114
163
}
164
+
165
+ /// Creates a lookahead from the regex generated by the given builder closure.
166
+ public init < R: RegexComponent > (
167
+ @RegexComponentBuilder _ component: ( ) -> R
168
+ ) where R. RegexOutput == Output {
169
+ self . init ( node: . nonCapturingGroup( . lookahead, component ( ) . regex. root) )
170
+ }
171
+ }
115
172
173
+ /// A regex component that allows a match to continue only if its contents
174
+ /// do not match at the given location.
175
+ ///
176
+ /// A negative lookahead is a zero-length assertion that its included regex
177
+ /// does not match at a particular position. Lookaheads do not advance the
178
+ /// overall matching position in the input string — once a lookahead succeeds,
179
+ /// matching continues in the regex from the same position.
180
+ @available ( SwiftStdlib 5 . 7 , * )
181
+ public struct NegativeLookahead < Output> : _BuiltinRegexComponent {
182
+ public var regex : Regex < Output >
183
+
184
+ init ( _ regex: Regex < Output > ) {
185
+ self . regex = regex
186
+ }
187
+
188
+ /// Creates a negative lookahead from the given regex component.
189
+ public init < R: RegexComponent > (
190
+ _ component: R
191
+ ) where R. RegexOutput == Output {
192
+ self . init ( node: . nonCapturingGroup( . negativeLookahead, component. regex. root) )
193
+ }
194
+
195
+ /// Creates a negative lookahead from the regex generated by the given builder
196
+ /// closure.
116
197
public init < R: RegexComponent > (
117
- negative: Bool = false ,
118
198
@RegexComponentBuilder _ component: ( ) -> R
119
199
) where R. RegexOutput == Output {
120
- self . init ( node: . nonCapturingGroup(
121
- negative ? . negativeLookahead : . lookahead, component ( ) . regex. root) )
200
+ self . init ( node: . nonCapturingGroup( . negativeLookahead, component ( ) . regex. root) )
122
201
}
123
202
}
0 commit comments