diff --git a/lib/src/preset_matchers.dart b/lib/src/preset_matchers.dart index db1e614..db905fc 100644 --- a/lib/src/preset_matchers.dart +++ b/lib/src/preset_matchers.dart @@ -62,3 +62,24 @@ class TelMatcher extends TextMatcher { r')(?!\d)', ]); } + +/// A variant of [TextMatcher] for parsing strings that exactly match +/// any of the strings in the passed list. +/// +/// {@template textParser.ExactMatcher} +/// ```dart +/// TextParser( +/// matchers: [ +/// ExactMatcher(['e.g.', 'C++']), +/// ], +/// ) +/// ``` +/// {@endtemplate} +class ExactMatcher extends TextMatcher { + /// Creates an [ExactMatcher] for parsing strings that exactly match + /// any of the strings in the passed list. + /// + /// {@macro textParser.ExactMatcher} + ExactMatcher(Iterable strings) + : super(strings.map(RegExp.escape).join('|')); +} diff --git a/test/matchers/exact_matcher_test.dart b/test/matchers/exact_matcher_test.dart new file mode 100644 index 0000000..0fe7e40 --- /dev/null +++ b/test/matchers/exact_matcher_test.dart @@ -0,0 +1,29 @@ +import 'package:test/test.dart'; + +import 'package:text_parser/text_parser.dart'; + +extension on ExactMatcher { + RegExp toRegExp() { + return RegExp(pattern); + } +} + +void main() { + test('Strings using reserved characters match exactly same strings', () { + const input = 'Assembly BASIC C++? Dart (^*^)/'; + final regExp = ExactMatcher(const ['(^*^)/', 'C++']).toRegExp(); + final matches = regExp.allMatches(input).toList(); + expect(matches, hasLength(2)); + expect(input.substring(matches[0].start, matches[0].end), 'C++?'); + expect(input.substring(matches[1].start, matches[1].end), '(^*^)/'); + }); + + test('Reserved characters are escaped and used as ordinary characters', () { + const input = 'ABCDEF AB.DE+'; + final regExp = ExactMatcher(const ['B.D', 'E+']).toRegExp(); + final matches = regExp.allMatches(input).toList(); + expect(matches, hasLength(2)); + expect(input.substring(matches[0].start, matches[0].end), 'B.D'); + expect(input.substring(matches[1].start, matches[1].end), 'E+'); + }); +}