// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

part of dart.core;

/// A regular expression pattern.
///
/// Regular expressions are [Pattern]s, and can as such be used to match strings
/// or parts of strings.
///
/// Dart regular expressions have the same syntax and semantics as
/// JavaScript regular expressions. See
/// <https://ecma-international.org/ecma-262/9.0/#sec-regexp-regular-expression-objects>
/// for the specification of JavaScript regular expressions.
///
/// The [firstMatch] method is the main implementation method
/// that applies a regular expression to a string
/// and returns the first [RegExpMatch].
/// All other methods in [RegExp] can be build from that.
///
/// Use [allMatches] to look for all matches of a regular expression in
/// a string.
///
/// The following example finds all matches of a regular expression in
/// a string.
/// ```dart
/// RegExp exp = RegExp(r"(\w+)");
/// String str = "Parse my string";
/// Iterable<RegExpMatch> matches = exp.allMatches(str);
/// ```
///
/// Note the use of a _raw string_ (a string prefixed with `r`)
/// in the example above. Use a raw string to treat each character in a string
/// as a literal character.
abstract class RegExp implements Pattern {
  /// Constructs a regular expression.
  ///
  /// Throws a [FormatException] if [source] is not valid regular
  /// expression syntax.
  ///
  /// If `multiLine` is enabled, then `^` and `$` will match the beginning and
  /// end of a _line_, in addition to matching beginning and end of input,
  /// respectively.
  ///
  /// If `caseSensitive` is disabled, then case is ignored.
  ///
  /// If `unicode` is enabled, then the pattern is treated as a Unicode
  /// pattern as described by the ECMAScript standard.
  ///
  /// If `dotAll` is enabled, then the `.` pattern will match _all_ characters,
  /// including line terminators.
  ///
  /// Example:
  ///
  /// ```dart
  /// var wordPattern = RegExp(r"(\w+)");
  /// var bracketedNumberValue = RegExp("$key: \\[\\d+\\]");
  /// ```
  ///
  /// Notice the use of a _raw string_ in the first example, and a regular
  /// string in the second. Because of the many escapes, like `\d`, used in
  /// regular expressions, it is common to use a raw string here, unless string
  /// interpolation is required.
  external factory RegExp(String source,
      {bool multiLine = false,
      bool caseSensitive = true,
      @Since("2.4") bool unicode = false,
      @Since("2.4") bool dotAll = false});

  /// Creates regular expression syntax that matches [text].
  ///
  /// If [text] contains characters that are meaningful in regular expressions,
  /// the resulting regular expression will match those characters literally.
  /// If [text] contains no characters that have special meaning in a regular
  /// expression, it is returned unmodified.
  ///
  /// The characters that have special meaning in regular expressions are:
  /// `(`, `)`, `[`, `]`, `{`, `}`, `*`, `+`, `?`, `.`, `^`, `$`, `|` and `\`.
  ///
  /// This method is mainly used to create a pattern to be included in a
  /// larger regular expression. Since a [String] is itself a [Pattern]
  /// which matches itself, converting the string to a regular expression
  /// isn't needed in order to search for just that string.
  external static String escape(String text);

  /// Finds the first match of the regular expression in the string [input].
  ///
  /// Returns `null` if there is no match.
  RegExpMatch? firstMatch(String input);

  Iterable<RegExpMatch> allMatches(String input, [int start = 0]);

  /// Whether the regular expression has a match in the string [input].
  bool hasMatch(String input);

  /// The substring of the first match of this regular expression in [input].
  String? stringMatch(String input);

  /// The source regular expression string used to create this `RegExp`.
  String get pattern;

  /// Whether this regular expression matches multiple lines.
  ///
  /// If the regexp does match multiple lines, the "^" and "$" characters
  /// match the beginning and end of lines. If not, the characters match the
  /// beginning and end of the input.
  bool get isMultiLine;

  /// Whether this regular expression is case sensitive.
  ///
  /// If the regular expression is not case sensitive, it will match an input
  /// letter with a pattern letter even if the two letters are different case
  /// versions of the same letter.
  bool get isCaseSensitive;

  /// Whether this regular expression is in Unicode mode.
  ///
  /// In Unicode mode, UTF-16 surrogate pairs in the original string will be
  /// treated as a single code point and will not match separately. Otherwise,
  /// the target string will be treated purely as a sequence of individual code
  /// units and surrogates will not be treated specially.
  ///
  /// In Unicode mode, the syntax of the RegExp pattern is more restricted, but
  /// some pattern features, like Unicode property escapes, are only available in
  /// this mode.
  @Since("2.4")
  bool get isUnicode;

  /// Whether "." in this regular expression matches line terminators.
  ///
  /// When false, the "." character matches a single character, unless that
  /// character is a line terminator. When true, then the "." character will
  /// match any single character including line terminators.
  ///
  /// This feature is distinct from [isMultiLine], as they affect the behavior
  /// of different pattern characters, and so they can be used together or
  /// separately.
  @Since("2.4")
  bool get isDotAll;
}

/// A regular expression match.
///
/// Regular expression matches are [Match]es, but also include the ability
/// to retrieve the names for any named capture groups and to retrieve
/// matches for named capture groups by name instead of their index.
@Since("2.3")
abstract class RegExpMatch implements Match {
  /// The string matched by the group named [name].
  ///
  /// Returns the string matched by the capture group named [name], or
  /// `null` if no string was matched by that capture group as part of
  /// this match.
  ///
  /// The [name] must be the name of a named capture group in the regular
  /// expression creating this match (that is, the name must be in
  /// [groupNames]).
  String? namedGroup(String name);

  /// The names of the captured groups in the match.
  Iterable<String> get groupNames;
}
