1212@_implementationOnly import _RegexParser
1313@_spi ( RegexBuilder) import _StringProcessing
1414
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.
1521@available ( SwiftStdlib 5 . 7 , * )
1622public struct Anchor {
1723 internal enum Kind {
@@ -53,14 +59,24 @@ extension Anchor: RegexComponent {
5359
5460@available ( SwiftStdlib 5 . 7 , * )
5561extension Anchor {
62+ /// An anchor that matches at the start of the input string.
63+ ///
64+ /// This anchor is equivalent to `\A` in regex syntax.
5665 public static var startOfSubject : Anchor {
5766 Anchor ( kind: . startOfSubject)
5867 }
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.
6073 public static var endOfSubjectBeforeNewline : Anchor {
6174 Anchor ( kind: . endOfSubjectBeforeNewline)
6275 }
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.
6480 public static var endOfSubject : Anchor {
6581 Anchor ( kind: . endOfSubject)
6682 }
@@ -70,33 +86,67 @@ extension Anchor {
7086// Anchor(kind: resetStartOfMatch)
7187// }
7288
89+ /// An anchor that matches at the first position of a match in the input
90+ /// string.
7391 public static var firstMatchingPositionInSubject : Anchor {
7492 Anchor ( kind: . firstMatchingPositionInSubject)
7593 }
7694
95+ /// An anchor that matches at a grapheme cluster boundary.
96+ ///
97+ /// This anchor is equivalent to `\y` in regex syntax.
7798 public static var textSegmentBoundary : Anchor {
7899 Anchor ( kind: . textSegmentBoundary)
79100 }
80101
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.
81107 public static var startOfLine : Anchor {
82108 Anchor ( kind: . startOfLine)
83109 }
84110
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.
85116 public static var endOfLine : Anchor {
86117 Anchor ( kind: . endOfLine)
87118 }
88119
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.
89127 public static var wordBoundary : Anchor {
90128 Anchor ( kind: . wordBoundary)
91129 }
92130
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.
93136 public var inverted : Anchor {
94137 var result = self
95138 result. isInverted. toggle ( )
96139 return result
97140 }
98141}
99142
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.
100150@available ( SwiftStdlib 5 . 7 , * )
101151public struct Lookahead < Output> : _BuiltinRegexComponent {
102152 public var regex : Regex < Output >
@@ -105,19 +155,48 @@ public struct Lookahead<Output>: _BuiltinRegexComponent {
105155 self . regex = regex
106156 }
107157
158+ /// Creates a lookahead from the given regex component.
108159 public init < R: RegexComponent > (
109- _ component: R ,
110- negative: Bool = false
160+ _ component: R
111161 ) 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) )
114163 }
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+ }
115172
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.
116197 public init < R: RegexComponent > (
117- negative: Bool = false ,
118198 @RegexComponentBuilder _ component: ( ) -> R
119199 ) 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) )
122201 }
123202}
0 commit comments