// Copyright (C) 2011 The Libphonenumber Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Author: George Yakovlev // Philippe Liard // // RegExp adapter to allow a pluggable regexp engine. It has been introduced // during the integration of the open-source version of this library into // Chromium to be able to use the ICU Regex engine instead of RE2, which is not // officially supported on Windows. // Since RE2 was initially used in this library, the interface of this adapter // is very close to the subset of the RE2 API used in phonenumberutil.cc. #ifndef I18N_PHONENUMBERS_REGEXP_ADAPTER_H_ #define I18N_PHONENUMBERS_REGEXP_ADAPTER_H_ #include #include namespace i18n { namespace phonenumbers { using std::string; // RegExpInput is the interface that abstracts the input that feeds the // Consume() method of RegExp which may differ depending on its various // implementations (StringPiece for RE2, UnicodeString for ICU Regex). class RegExpInput { public: virtual ~RegExpInput() {} // Converts to a C++ string. virtual string ToString() const = 0; }; // The regular expression abstract class. It supports only functions used in // phonenumberutil.cc. Consume(), Match() and Replace() methods must be // implemented. class RegExp { public: virtual ~RegExp() {} // Matches string to regular expression, returns true if expression was // matched, false otherwise, advances position in the match. // input_string - string to be searched. // anchor_at_start - if true, match would be successful only if it appears at // the beginning of the tested region of the string. // matched_string1 - the first string extracted from the match. Can be NULL. // matched_string2 - the second string extracted from the match. Can be NULL. // matched_string3 - the third string extracted from the match. Can be NULL. virtual bool Consume(RegExpInput* input_string, bool anchor_at_start, string* matched_string1, string* matched_string2, string* matched_string3) const = 0; // Helper methods calling the Consume method that assume the match must start // at the beginning. inline bool Consume(RegExpInput* input_string, string* matched_string1, string* matched_string2, string* matched_string3) const { return Consume(input_string, true, matched_string1, matched_string2, matched_string3); } inline bool Consume(RegExpInput* input_string, string* matched_string1, string* matched_string2) const { return Consume(input_string, true, matched_string1, matched_string2, NULL); } inline bool Consume(RegExpInput* input_string, string* matched_string) const { return Consume(input_string, true, matched_string, NULL, NULL); } inline bool Consume(RegExpInput* input_string) const { return Consume(input_string, true, NULL, NULL, NULL); } // Helper method calling the Consume method that assumes the match can start // at any place in the string. inline bool FindAndConsume(RegExpInput* input_string, string* matched_string) const { return Consume(input_string, false, matched_string, NULL, NULL); } // Matches string to regular expression, returns true if the expression was // matched, false otherwise. // input_string - string to be searched. // full_match - if true, match would be successful only if it matches the // complete string. // matched_string - the string extracted from the match. Can be NULL. virtual bool Match(const string& input_string, bool full_match, string* matched_string) const = 0; // Helper methods calling the Match method with the right arguments. inline bool PartialMatch(const string& input_string, string* matched_string) const { return Match(input_string, false, matched_string); } inline bool PartialMatch(const string& input_string) const { return Match(input_string, false, NULL); } inline bool FullMatch(const string& input_string, string* matched_string) const { return Match(input_string, true, matched_string); } inline bool FullMatch(const string& input_string) const { return Match(input_string, true, NULL); } // Replaces match(es) in 'string_to_process'. If 'global' is true, // replaces all the matches, otherwise only the first match. // replacement_string - text the matches are replaced with. The groups in the // replacement string are referenced with the $[0-9] notation. // Returns true if the pattern matches and a replacement occurs, false // otherwise. virtual bool Replace(string* string_to_process, bool global, const string& replacement_string) const = 0; // Helper methods calling the Replace method with the right arguments. inline bool Replace(string* string_to_process, const string& replacement_string) const { return Replace(string_to_process, false, replacement_string); } inline bool GlobalReplace(string* string_to_process, const string& replacement_string) const { return Replace(string_to_process, true, replacement_string); } }; // Abstract factory class that lets its subclasses instantiate the classes // implementing RegExp and RegExpInput. class AbstractRegExpFactory { public: virtual ~AbstractRegExpFactory() {} // Creates a new instance of RegExpInput. The deletion of the returned // instance is under the responsibility of the caller. virtual RegExpInput* CreateInput(const string& utf8_input) const = 0; // Creates a new instance of RegExp. The deletion of the returned instance is // under the responsibility of the caller. virtual RegExp* CreateRegExp(const string& utf8_regexp) const = 0; }; } // namespace phonenumbers } // namespace i18n #endif // I18N_PHONENUMBERS_REGEXP_ADAPTER_H_