// 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;

/**
 * [Match] contains methods to manipulate a regular expression match.
 *
 * Iterables of [Match] objects are returned from [RegExp] matching methods.
 *
 * The following example finds all matches of a [RegExp] in a [String]
 * and iterates through the returned iterable of [Match] objects.
 *
 *     RegExp exp = new RegExp(r"(\w+)");
 *     String str = "Parse my string";
 *     Iterable<Match> matches = exp.allMatches(str);
 *     for (Match m in matches) {
 *       String match = m.group(0);
 *       print(match);
 *     }
 *
 * The output of the example is:
 *
 *     Parse
 *     my
 *     string
 */
abstract class Match {
  /**
   * Returns the index in the string where the match starts.
   */
  int get start;

  /**
   * Returns the index in the string after the last character of the
   * match.
   */
  int get end;

  /**
   * Returns the string matched by the given [group]. If [group] is 0,
   * returns the match of the regular expression.
   */
  String group(int group);
  String operator [](int group);

  /**
   * Returns the strings matched by [groups]. The order in the
   * returned string follows the order in [groups].
   */
  List<String> groups(List<int> groups);

  /**
   * Returns the number of groups in the regular expression.
   */
  int get groupCount;

  /**
   * The string on which this matcher was computed.
   */
  String get str;

  /**
   * The pattern used to search in [str].
   */
  Pattern get pattern;
}


/**
 * A class for working with regular expressions.
 *
 * Dart regular expressions have the same syntax and semantics as
 * JavaScript regular expressions. See
 * <http://ecma-international.org/ecma-262/5.1/#sec-15.10>
 * for the specification of JavaScript regular expressions.
 *
 * [firstMatch] is the main implementation method that applies a regular
 * expression to a string and returns the first [Match]. All
 * other methods in [RegExp] can build on it.
 *
 * 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.
 *
 *     RegExp exp = new RegExp(r"(\w+)");
 *     String str = "Parse my string";
 *     Iterable<Match> matches = exp.allMatches(str);
 */
abstract class RegExp implements Pattern {
  /**
   * Constructs a regular expression. The default implementation of a
   * [RegExp] sets [multiLine] to false and [caseSensitive] to true.
   * Throws a [FormatException] if [pattern] is not a valid regular
   * exression pattern.
   */
  external factory RegExp(String pattern, {bool multiLine: false,
                                           bool caseSensitive: true});

  /**
   * Searches for the first match of the regular expression
   * in the string [str]. Returns `null` if there is no match.
   */
  Match firstMatch(String str);

  /**
   * Returns an iterable on the  matches of the regular
   * expression in [str].
   */
  Iterable<Match> allMatches(String str);

  /**
   * Returns whether the regular expression has a match in the string [str].
   */
  bool hasMatch(String str);

  /**
   * Searches for the first match of the regular expression
   * in the string [str] and returns the matched string.
   */
  String stringMatch(String str);

  /**
   * The pattern of this regular expression.
   */
  String get pattern;

  /**
   * Whether this regular expression matches multiple lines.
   */
  bool get isMultiLine;

  /**
   * Whether this regular expression is case insensitive.
   */
  bool get isCaseSensitive;
}
