diff --git a/lib/src/parser.dart b/lib/src/parser.dart index d45c01e..569e4f7 100644 --- a/lib/src/parser.dart +++ b/lib/src/parser.dart @@ -37,16 +37,21 @@ class Parser { _matcherGroupRanges.clear(); var groupIndexStart = 2; + final patterns = []; + for (var i = 0; i < matchers.length; i++) { - assert( - matchers[i].pattern.isNotEmpty, - 'All matchers must have a non-empty pattern.', - ); + final groupName = '$_kMatcherGroupPrefix$i'; + _matcherGroupNames.add(groupName); - _matcherGroupNames.add('$_kMatcherGroupPrefix$i'); + var pattern = matchers[i].pattern; + if (pattern.isEmpty) { + // Expression that does not match anything. + pattern = '(?!)'; + } + patterns.add('(?<$groupName>$pattern)'); final regExp = RegExp( - '${matchers[i].pattern}|.*', + '$pattern|.*', multiLine: multiLine, caseSensitive: caseSensitive, unicode: unicode, @@ -57,14 +62,10 @@ class Parser { _matcherGroupRanges.add([ for (var i = 0; i < groupCount; i++) groupIndexStart + i, ]); - groupIndexStart += groupCount + 1; } - _pattern = { - for (var i = 0; i < matchers.length; i++) - '(?<${_matcherGroupNames[i]}>${matchers[i].pattern})', - }.join('|'); + _pattern = patterns.join('|'); } List parse(String text, {required bool onlyMatches}) { diff --git a/test/matchers/matcher_test.dart b/test/matchers/matcher_test.dart index 1dbe37b..19806ee 100644 --- a/test/matchers/matcher_test.dart +++ b/test/matchers/matcher_test.dart @@ -49,17 +49,34 @@ void main() { ); }); - test('Having matcher containing empty pattern throws AssertionError', () { - expect( - () => TextParser(matchers: const [EmailMatcher(), PatternMatcher('')]), - throwsA( - isA().having( - (e) => e.message, - 'message', - contains('must have a non-empty pattern'), - ), - ), + test('correctly parsed with matchers containing empty pattern', () async { + final parser = TextParser( + matchers: const [ + PatternMatcher('(bbb)'), + PatternMatcher(''), + PatternMatcher('(ddd)'), + ], ); + final elements = await parser.parse('aaabbbcccdddeee'); + + expect(elements, hasLength(5)); + expect(elements[0], const TextElement('aaa')); + expect(elements[0].matcherType, TextMatcher); + expect(elements[0].matcherIndex, null); + expect(elements[1].text, 'bbb'); + expect(elements[1].matcherType, PatternMatcher); + expect(elements[1].matcherIndex, 0); + expect(elements[1].groups, ['bbb']); + expect(elements[2].text, 'ccc'); + expect(elements[2].matcherType, TextMatcher); + expect(elements[2].matcherIndex, null); + expect(elements[3].text, 'ddd'); + expect(elements[3].matcherType, PatternMatcher); + expect(elements[3].matcherIndex, 2); + expect(elements[3].groups, ['ddd']); + expect(elements[4].text, 'eee'); + expect(elements[4].matcherType, TextMatcher); + expect(elements[4].matcherIndex, null); }); }); }