@@ -165,12 +165,28 @@ public function oneOf(string $chars)
165165 {
166166 $ this ->validateAndAddMethodType (self ::METHOD_TYPE_CHARACTER , self ::METHOD_TYPES_ALLOWED_FOR_CHARACTERS );
167167
168- $ chars = implode ( '' , array_map ([ $ this , ' escape ' ], str_split ($ chars)) );
169- $ chars = str_replace ([ ' - ' , ' ] ' ], [ '\\ - ' , '\\ ] ' ], $ chars );
168+ $ chars = $ this -> escape ($ chars );
169+ $ chars = $ this -> escapeRangeSpecificChars ( $ chars );
170170
171171 return $ this ->add ('[ ' . $ chars . '] ' );
172172 }
173173
174+ /**
175+ * Literally match anything but one of these characters.
176+ *
177+ * @param string $chars
178+ * @return Builder
179+ */
180+ public function notOneOf (string $ chars )
181+ {
182+ $ this ->validateAndAddMethodType (self ::METHOD_TYPE_CHARACTER , self ::METHOD_TYPES_ALLOWED_FOR_CHARACTERS );
183+
184+ $ chars = $ this ->escape ($ chars );
185+ $ chars = $ this ->escapeRangeSpecificChars ($ chars );
186+
187+ return $ this ->add ('[^ ' . $ chars . '] ' );
188+ }
189+
174190 /**
175191 * Literally match all of these characters in that order.
176192 *
@@ -181,7 +197,7 @@ public function literally(string $chars) : self
181197 {
182198 $ this ->validateAndAddMethodType (self ::METHOD_TYPE_CHARACTER , self ::METHOD_TYPES_ALLOWED_FOR_CHARACTERS );
183199
184- return $ this ->add ('(?: ' . implode ( '' , array_map ([ $ this , ' escape ' ], str_split ($ chars)) ) . ') ' );
200+ return $ this ->add ('(?: ' . $ this -> escape ($ chars ) . ') ' );
185201 }
186202
187203 /**
@@ -212,6 +228,20 @@ public function digit(int $min = 0, int $max = 9) : self
212228 return $ this ->add ("[ $ min- $ max] " );
213229 }
214230
231+ /**
232+ * Match anything but digit (in given span). Default will be a digit between 0 and 9.
233+ *
234+ * @param int $min
235+ * @param int $max
236+ * @return Builder
237+ */
238+ public function notDigit (int $ min = 0 , int $ max = 9 ) : self
239+ {
240+ $ this ->validateAndAddMethodType (self ::METHOD_TYPE_CHARACTER , self ::METHOD_TYPES_ALLOWED_FOR_CHARACTERS );
241+
242+ return $ this ->add ("[^ $ min- $ max] " );
243+ }
244+
215245 /**
216246 * Match any uppercase letter (between A to Z).
217247 *
@@ -238,6 +268,32 @@ public function letter(string $min = 'a', string $max = 'z') : self
238268 return $ this ->add ("[ $ min- $ max] " );
239269 }
240270
271+ /**
272+ * Match anything but uppercase letter (between A to Z).
273+ *
274+ * @param string $min
275+ * @param string $max
276+ * @return Builder
277+ */
278+ public function notUppercaseLetter (string $ min = 'A ' , string $ max = 'Z ' ) : self
279+ {
280+ return $ this ->notLetter ($ min , $ max );
281+ }
282+
283+ /**
284+ * Match anything but lowercase letter (between a to z).
285+ *
286+ * @param string $min
287+ * @param string $max
288+ * @return Builder
289+ */
290+ public function notLetter (string $ min = 'a ' , string $ max = 'z ' ) : self
291+ {
292+ $ this ->validateAndAddMethodType (self ::METHOD_TYPE_CHARACTER , self ::METHOD_TYPES_ALLOWED_FOR_CHARACTERS );
293+
294+ return $ this ->add ("[^ $ min- $ max] " );
295+ }
296+
241297 /**********************************************************/
242298 /* GROUPS */
243299 /**********************************************************/
@@ -508,17 +564,38 @@ public function until($toCondition) : self
508564 /* INTERNAL METHODS */
509565 /**********************************************************/
510566
567+ /**
568+ * Escape all characters in string.
569+ *
570+ * @param string $chars
571+ * @return string
572+ */
573+ protected function escape (string $ chars )
574+ {
575+ return implode ('' , array_map ([$ this , 'escapeChar ' ], str_split ($ chars )));
576+ }
577+
511578 /**
512579 * Escape specific character.
513580 *
514581 * @param string $char
515582 * @return string
516583 */
517- protected function escape (string $ char )
584+ protected function escapeChar (string $ char )
518585 {
519586 return (strpos (static ::NON_LITERAL_CHARACTERS , $ char ) !== false ? '\\' : '' ) . $ char ;
520587 }
521588
589+ /**
590+ * Escape '-' and ']' in string to be used in range.
591+ *
592+ * @return string
593+ */
594+ protected function escapeRangeSpecificChars (string $ chars )
595+ {
596+ return str_replace (['- ' , '] ' ], ['\\- ' , '\\] ' ], $ chars );
597+ }
598+
522599 /**
523600 * Get the raw regular expression without delimiter or modifiers.
524601 *
0 commit comments