@@ -59,14 +59,14 @@ public struct CharacterClass: Hashable {
5959 var op : SetOperator
6060 var rhs : CharacterSetComponent
6161
62- public func matches( _ c: Character ) -> Bool {
62+ public func matches( _ c: Character , with options : MatchingOptions ) -> Bool {
6363 switch op {
6464 case . intersection:
65- return lhs. matches ( c) && rhs. matches ( c)
65+ return lhs. matches ( c, with : options ) && rhs. matches ( c, with : options )
6666 case . subtraction:
67- return lhs. matches ( c) && !rhs. matches ( c)
67+ return lhs. matches ( c, with : options ) && !rhs. matches ( c, with : options )
6868 case . symmetricDifference:
69- return lhs. matches ( c) != rhs. matches ( c)
69+ return lhs. matches ( c, with : options ) != rhs. matches ( c, with : options )
7070 }
7171 }
7272 }
@@ -87,14 +87,28 @@ public struct CharacterClass: Hashable {
8787 . setOperation( . init( lhs: lhs, op: op, rhs: rhs) )
8888 }
8989
90- public func matches( _ character: Character ) -> Bool {
90+ public func matches( _ character: Character , with options : MatchingOptions ) -> Bool {
9191 switch self {
92- case . character( let c) : return c == character
93- case . range( let range) : return range. contains ( character)
92+ case . character( let c) :
93+ if options. isCaseInsensitive {
94+ return c. lowercased ( ) == character. lowercased ( )
95+ } else {
96+ return c == character
97+ }
98+ case . range( let range) :
99+ if options. isCaseInsensitive {
100+ let newLower = range. lowerBound. lowercased ( )
101+ let newUpper = range. upperBound. lowercased ( )
102+ // FIXME: Is failing this possible? Is this the right behavior if so?
103+ guard newLower <= newUpper else { return false }
104+ return ( newLower... newUpper) . contains ( character. lowercased ( ) )
105+ } else {
106+ return range. contains ( character)
107+ }
94108 case . characterClass( let custom) :
95109 let str = String ( character)
96- return custom. matches ( in: str, at: str. startIndex) != nil
97- case . setOperation( let op) : return op. matches ( character)
110+ return custom. matches ( in: str, at: str. startIndex, with : options ) != nil
111+ case . setOperation( let op) : return op. matches ( character, with : options )
98112 }
99113 }
100114 }
@@ -135,21 +149,26 @@ public struct CharacterClass: Hashable {
135149
136150 /// Returns the end of the match of this character class in `str`, if
137151 /// it matches.
138- public func matches( in str: String , at i: String . Index ) -> String . Index ? {
152+ public func matches( in str: String , at i: String . Index , with options : MatchingOptions ) -> String . Index ? {
139153 switch matchLevel {
140154 case . graphemeCluster:
141155 let c = str [ i]
142156 var matched : Bool
143157 switch cc {
144158 case . any, . anyGrapheme: matched = true
145- case . digit: matched = c. isNumber
146- case . hexDigit: matched = c. isHexDigit
159+ case . digit:
160+ matched = c. isNumber && ( c. isASCII || !options. usesASCIIDigits)
161+ case . hexDigit:
162+ matched = c. isHexDigit && ( c. isASCII || !options. usesASCIIDigits)
147163 case . horizontalWhitespace: fatalError ( " Not implemented " )
148- case . newlineSequence: matched = c. isNewline
164+ case . newlineSequence:
165+ matched = c. isNewline && ( c. isASCII || !options. usesASCIISpaces)
149166 case . verticalWhitespace: fatalError ( " Not implemented " )
150- case . whitespace: matched = c. isWhitespace
151- case . word: matched = c. isWordCharacter
152- case . custom( let set) : matched = set. any { $0. matches ( c) }
167+ case . whitespace:
168+ matched = c. isWhitespace && ( c. isASCII || !options. usesASCIISpaces)
169+ case . word:
170+ matched = c. isWordCharacter && ( c. isASCII || !options. usesASCIIWord)
171+ case . custom( let set) : matched = set. any { $0. matches ( c, with: options) }
153172 }
154173 if isInverted {
155174 matched. toggle ( )
@@ -161,13 +180,17 @@ public struct CharacterClass: Hashable {
161180 switch cc {
162181 case . any: matched = true
163182 case . anyGrapheme: fatalError ( " Not matched in this mode " )
164- case . digit: matched = c. properties. numericType != nil
165- case . hexDigit: matched = Character ( c) . isHexDigit
183+ case . digit:
184+ matched = c. properties. numericType != nil && ( c. isASCII || !options. usesASCIIDigits)
185+ case . hexDigit:
186+ matched = Character ( c) . isHexDigit && ( c. isASCII || !options. usesASCIIDigits)
166187 case . horizontalWhitespace: fatalError ( " Not implemented " )
167188 case . newlineSequence: fatalError ( " Not implemented " )
168189 case . verticalWhitespace: fatalError ( " Not implemented " )
169- case . whitespace: matched = c. properties. isWhitespace
170- case . word: matched = c. properties. isAlphabetic || c == " _ "
190+ case . whitespace:
191+ matched = c. properties. isWhitespace && ( c. isASCII || !options. usesASCIISpaces)
192+ case . word:
193+ matched = ( c. properties. isAlphabetic || c == " _ " ) && ( c. isASCII || !options. usesASCIIWord)
171194 case . custom: fatalError ( " Not supported " )
172195 }
173196 if isInverted {
@@ -495,21 +518,22 @@ extension CharacterClass {
495518 func isBoundary(
496519 _ input: String ,
497520 at pos: String . Index ,
498- bounds: Range < String . Index >
521+ bounds: Range < String . Index > ,
522+ with options: MatchingOptions
499523 ) -> Bool {
500524 // FIXME: How should we handle bounds?
501525 // We probably need two concepts
502526 if input. isEmpty { return false }
503527 if pos == input. startIndex {
504- return self . matches ( in: input, at: pos) != nil
528+ return self . matches ( in: input, at: pos, with : options ) != nil
505529 }
506530 let priorIdx = input. index ( before: pos)
507531 if pos == input. endIndex {
508- return self . matches ( in: input, at: priorIdx) != nil
532+ return self . matches ( in: input, at: priorIdx, with : options ) != nil
509533 }
510534
511- let prior = self . matches ( in: input, at: priorIdx) != nil
512- let current = self . matches ( in: input, at: pos) != nil
535+ let prior = self . matches ( in: input, at: priorIdx, with : options ) != nil
536+ let current = self . matches ( in: input, at: pos, with : options ) != nil
513537 return prior != current
514538 }
515539
0 commit comments