recursive_regex 0.1.0+1 recursive_regex: ^0.1.0+1 copied to clipboard
An implementation of RegExp that isolates delimited blocks of text and applies the pattern to each block separately.
recursive_regex #
An implementation of Dart's RegExp class that isolates delimited blocks of text and applies the delimited pattern to each block separately.
The [RecursiveRegex] class implements Dart's [RegExp] class. As such, it has all of the same methods as [RegExp] and can be used interchangeably with [RegExp]s.
Usage #
import 'package:recursive_regex/recursive_regex.dart';
[RecursiveRegex] has 2 required parameters, [startDelimiter] and
[endDelimiter]. Both accept a [RegExp], must not be null
, and
must not have identical patterns.
RegExp regex = RecursiveRegex(
startDelimiter: RegExp(r'<'),
endDelimiter: RegExp(r'>'),
);
This [RecursiveRegex], if applied to a string, would capture every block
of text delimited by the <
and >
characters.
String input = '<a<b<c><d>>>';
regex.allMatches(input); // ['<a<b<c><d>>>']
By default, only top-level blocks of delimited text are matched. To match
every block of delimited text, nested or not, global
can be flagged true
.
String input = '<a<b<c><d>>>';
RegExp regex = RecursiveRegex(
startDelimiter: RegExp(r'<'),
endDelimiter: RegExp(r'>'),
global: true,
);
regex.allMatches(input); //['<c>', '<d>', '<b<c><d>>', '<a<b<c><d>>>']
Delimited blocks of text are matched in the order that they're closed.
Note: [RecursiveRegex] is not optimized for parsing strings that do not contain nested blocks of delimited text, [RegExp] would be more efficient if you know the string doesn't contain any nested delimiters.
Methods #
[RecursiveRegex] has the same methods as [RegExp] (@override
methods),
plus a few more.
/// Returns the first match found in [input].
@override
RegExpMatch firstMatch(String input);
/// Searches [input] for the match found at [index].
RegExpMatch nthMatch(int index, String input, {bool reverse = false});
/// Returns the last match found in [input].
RegExpMatch lastMatch(String input);
/// Returns a list of every match found in [input] after [start].
@override
List<RegExpMatch> allMatches(String input, [int start = 0]);
/// Returns a list of the matches found in [input].
List<RegExpMatch> getMatches(String input, {
int start = 0, int stop, bool reverse = false,
});
/// Returns `true` if [input] contains a match, otherwise returns `false`.
@override
bool hasMatch(String input);
/// Returns the first substring match found in [input].
@override
String stringMatch(String input);
/// Returns the list of substring matches found in [input].
List<String> stringMatches(String input, {
int start = 0, int stop, bool reverse = false,
});
/// Match the delimited pattern against the start of [string].
@override
Match matchAsPrefix(String string, [int start = 0]);
Behind the scenes, firstMatch()
, nthMatch()
, lastMatch()
, and
allMatches()
return results from getMatches()
.
getMatches()
, will identify every block of delimited text, and will apply
the delimited pattern to each block seperately. The pattern will only be
applied to the blocks being returned, all others will be ignored.
If getMatches()
[reverse] parameter is true, blocks of delimited text will
be identified in [input] from the bottom-up, as such, calling lastMatch()
is significantly more efficient than calling allMatches().last
.
getMatches()
[start] and [stop] parameters set the range of matches that should be returned. Matches with indexes that occur before [start] and after
[stop] will be ignored. nthMatches(3, input)
would call
getMatches(input, start: 3, stop: 3)
.
Capture Groups #
The block of text captured between the delimiters can be captured in a named group by providing [RecursiveRegex] with a [captureGroupName].
String input = '<!ELEMENT [ some markup ]>';
RegExp regex = RecursiveRegex(
startDelimiter: RegExp(r'<!(?<type>\w*)\s*\['),
endDelimiter: RegExp(r']>'),
captureGroupName: 'value',
);
print(regex.firstMatch(input).namedGroup('value')); // ' some markup '
// Groups named within the delimiters can also be called.
print(regex.firstMatch(input).namedGroup('type')); // 'ELEMENT'