OLD | NEW |
| (Empty) |
1 // Copyright 2013 Google Inc. All Rights Reserved. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 | |
15 /** | |
16 * This library contains utilities for working with [RegExp]s and other | |
17 * [Pattern]s. | |
18 */ | |
19 library quiver.pattern; | |
20 | |
21 part 'src/pattern/glob.dart'; | |
22 | |
23 // From the PatternCharacter rule here: | |
24 // http://ecma-international.org/ecma-262/5.1/#sec-15.10 | |
25 final _specialChars = new RegExp(r'([\\\^\$\.\|\+\[\]\(\)\{\}])'); | |
26 | |
27 /** | |
28 * Escapes special regex characters in [str] so that it can be used as a | |
29 * literal match inside of a [RegExp]. | |
30 * | |
31 * The special characters are: \ ^ $ . | + [ ] ( ) { } | |
32 * as defined here: http://ecma-international.org/ecma-262/5.1/#sec-15.10 | |
33 */ | |
34 String escapeRegex(String str) => str.splitMapJoin(_specialChars, | |
35 onMatch: (Match m) => '\\${m.group(0)}', onNonMatch: (s) => s); | |
36 | |
37 /** | |
38 * Returns a [Pattern] that matches against every pattern in [include] and | |
39 * returns all the matches. If the input string matches against any pattern in | |
40 * [exclude] no matches are returned. | |
41 */ | |
42 Pattern matchAny(Iterable<Pattern> include, {Iterable<Pattern> exclude}) => | |
43 new _MultiPattern(include, exclude: exclude); | |
44 | |
45 class _MultiPattern extends Pattern { | |
46 final Iterable<Pattern> include; | |
47 final Iterable<Pattern> exclude; | |
48 | |
49 _MultiPattern(Iterable<Pattern> this.include, | |
50 {Iterable<Pattern> this.exclude}); | |
51 | |
52 Iterable<Match> allMatches(String str, [int start = 0]) { | |
53 var _allMatches = []; | |
54 for (var pattern in include) { | |
55 var matches = pattern.allMatches(str, start); | |
56 if (_hasMatch(matches)) { | |
57 if (exclude != null) { | |
58 for (var excludePattern in exclude) { | |
59 if (_hasMatch(excludePattern.allMatches(str, start))) { | |
60 return []; | |
61 } | |
62 } | |
63 } | |
64 _allMatches.add(matches); | |
65 } | |
66 } | |
67 return _allMatches.expand((x) => x); | |
68 } | |
69 | |
70 Match matchAsPrefix(String str, [int start = 0]) { | |
71 return allMatches(str).firstWhere((match) => match.start == start, | |
72 orElse: () => null); | |
73 } | |
74 } | |
75 | |
76 /** | |
77 * Returns true if [pattern] has a single match in [str] that matches the whole | |
78 * string, not a substring. | |
79 */ | |
80 bool matchesFull(Pattern pattern, String str) { | |
81 var match = pattern.matchAsPrefix(str); | |
82 return match != null && match.end == str.length; | |
83 } | |
84 | |
85 bool _hasMatch(Iterable<Match> matches) => matches.iterator.moveNext(); | |
OLD | NEW |