cmRegularExpression.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. /*=========================================================================
  2. Program: Insight Segmentation & Registration Toolkit
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2001 Insight Consortium
  8. All rights reserved.
  9. Redistribution and use in source and binary forms, with or without
  10. modification, are permitted provided that the following conditions are met:
  11. * Redistributions of source code must retain the above copyright notice,
  12. this list of conditions and the following disclaimer.
  13. * Redistributions in binary form must reproduce the above copyright notice,
  14. this list of conditions and the following disclaimer in the documentation
  15. and/or other materials provided with the distribution.
  16. * The name of the Insight Consortium, nor the names of any consortium members,
  17. nor of any contributors, may be used to endorse or promote products derived
  18. from this software without specific prior written permission.
  19. * Modified source versions must be plainly marked as such, and must not be
  20. misrepresented as being the original software.
  21. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
  22. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
  25. ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  27. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  28. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  29. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. =========================================================================*/
  32. // Original Copyright notice:
  33. // Copyright (C) 1991 Texas Instruments Incorporated.
  34. //
  35. // Permission is granted to any individual or institution to use, copy, modify,
  36. // and distribute this software, provided that this complete copyright and
  37. // permission notice is maintained, intact, in all copies and supporting
  38. // documentation.
  39. //
  40. // Texas Instruments Incorporated provides this software "as is" without
  41. // express or implied warranty.
  42. //
  43. // Created: MNF 06/13/89 Initial Design and Implementation
  44. // Updated: LGO 08/09/89 Inherit from Generic
  45. // Updated: MBN 09/07/89 Added conditional exception handling
  46. // Updated: MBN 12/15/89 Sprinkled "const" qualifiers all over the place!
  47. // Updated: DLS 03/22/91 New lite version
  48. //
  49. #ifndef cmRegularExpression_h
  50. #define cmRegularExpression_h
  51. #include "cmStandardIncludes.h"
  52. const int NSUBEXP = 10;
  53. /** \class cmRegularExpression
  54. * \brief Implements pattern matching with regular expressions.
  55. *
  56. * This is the header file for the regular expression class. An object of
  57. * this class contains a regular expression, in a special "compiled" format.
  58. * This compiled format consists of several slots all kept as the objects
  59. * private data. The cmRegularExpression class provides a convenient way to
  60. * represent regular expressions. It makes it easy to search for the same
  61. * regular expression in many different strings without having to compile a
  62. * string to regular expression format more than necessary.
  63. *
  64. * This class implements pattern matching via regular expressions.
  65. * A regular expression allows a programmer to specify complex
  66. * patterns that can be searched for and matched against the
  67. * character string of a string object. In its simplest form, a
  68. * regular expression is a sequence of characters used to
  69. * search for exact character matches. However, many times the
  70. * exact sequence to be found is not known, or only a match at
  71. * the beginning or end of a string is desired. The cmRegularExpression regu-
  72. * lar expression class implements regular expression pattern
  73. * matching as is found and implemented in many UNIX commands
  74. * and utilities.
  75. *
  76. * Example: The perl code
  77. *
  78. * $filename =~ m"([a-z]+)\.cc";
  79. * print $1;
  80. *
  81. * Is written as follows in C++
  82. *
  83. * cmRegularExpression re("([a-z]+)\\.cc");
  84. * re.find(filename);
  85. * cerr << re.match(1);
  86. *
  87. *
  88. * The regular expression class provides a convenient mechanism
  89. * for specifying and manipulating regular expressions. The
  90. * regular expression object allows specification of such pat-
  91. * terns by using the following regular expression metacharac-
  92. * ters:
  93. *
  94. * ^ Matches at beginning of a line
  95. *
  96. * $ Matches at end of a line
  97. *
  98. * . Matches any single character
  99. *
  100. * [ ] Matches any character(s) inside the brackets
  101. *
  102. * [^ ] Matches any character(s) not inside the brackets
  103. *
  104. * - Matches any character in range on either side of a dash
  105. *
  106. * * Matches preceding pattern zero or more times
  107. *
  108. * + Matches preceding pattern one or more times
  109. *
  110. * ? Matches preceding pattern zero or once only
  111. *
  112. * () Saves a matched expression and uses it in a later match
  113. *
  114. * Note that more than one of these metacharacters can be used
  115. * in a single regular expression in order to create complex
  116. * search patterns. For example, the pattern [^ab1-9] says to
  117. * match any character sequence that does not begin with the
  118. * characters "ab" followed by numbers in the series one
  119. * through nine.
  120. *
  121. * There are three constructors for cmRegularExpression. One just creates an
  122. * empty cmRegularExpression object. Another creates a cmRegularExpression
  123. * object and initializes it with a regular expression that is given in the
  124. * form of a char*. The third takes a reference to a cmRegularExpression
  125. * object as an argument and creates an object initialized with the
  126. * information from the given cmRegularExpression object.
  127. *
  128. * The find member function finds the first occurence of the regualr
  129. * expression of that object in the string given to find as an argument. Find
  130. * returns a boolean, and if true, mutates the private data appropriately.
  131. * Find sets pointers to the beginning and end of the thing last found, they
  132. * are pointers into the actual string that was searched. The start and end
  133. * member functions return indicies into the searched string that correspond
  134. * to the beginning and end pointers respectively. The compile member
  135. * function takes a char* and puts the compiled version of the char* argument
  136. * into the object's private data fields. The == and != operators only check
  137. * the to see if the compiled regular expression is the same, and the
  138. * deep_equal functions also checks to see if the start and end pointers are
  139. * the same. The is_valid function returns false if program is set to NULL,
  140. * (i.e. there is no valid compiled exression). The set_invalid function sets
  141. * the program to NULL (Warning: this deletes the compiled expression). The
  142. * following examples may help clarify regular expression usage:
  143. *
  144. * * The regular expression "^hello" matches a "hello" only at the
  145. * beginning of a line. It would match "hello there" but not "hi,
  146. * hello there".
  147. *
  148. * * The regular expression "long$" matches a "long" only at the end
  149. * of a line. It would match "so long\0", but not "long ago".
  150. *
  151. * * The regular expression "t..t..g" will match anything that has a
  152. * "t" then any two characters, another "t", any two characters and
  153. * then a "g". It will match "testing", or "test again" but would
  154. * not match "toasting"
  155. *
  156. * * The regular expression "[1-9ab]" matches any number one through
  157. * nine, and the characters "a" and "b". It would match "hello 1"
  158. * or "begin", but would not match "no-match".
  159. *
  160. * * The regular expression "[^1-9ab]" matches any character that is
  161. * not a number one through nine, or an "a" or "b". It would NOT
  162. * match "hello 1" or "begin", but would match "no-match".
  163. *
  164. * * The regular expression "br* " matches something that begins with
  165. * a "b", is followed by zero or more "r"s, and ends in a space. It
  166. * would match "brrrrr ", and "b ", but would not match "brrh ".
  167. *
  168. * * The regular expression "br+ " matches something that begins with
  169. * a "b", is followed by one or more "r"s, and ends in a space. It
  170. * would match "brrrrr ", and "br ", but would not match "b " or
  171. * "brrh ".
  172. *
  173. * * The regular expression "br? " matches something that begins with
  174. * a "b", is followed by zero or one "r"s, and ends in a space. It
  175. * would match "br ", and "b ", but would not match "brrrr " or
  176. * "brrh ".
  177. *
  178. * * The regular expression "(..p)b" matches something ending with pb
  179. * and beginning with whatever the two characters before the first p
  180. * encounterd in the line were. It would find "repb" in "rep drepa
  181. * qrepb". The regular expression "(..p)a" would find "repa qrepb"
  182. * in "rep drepa qrepb"
  183. *
  184. * * The regular expression "d(..p)" matches something ending with p,
  185. * beginning with d, and having two characters in between that are
  186. * the same as the two characters before the first p encounterd in
  187. * the line. It would match "drepa qrepb" in "rep drepa qrepb".
  188. *
  189. */
  190. class cmRegularExpression
  191. {
  192. public:
  193. /**
  194. * Instantiate cmRegularExpression with program=NULL.
  195. */
  196. inline cmRegularExpression ();
  197. /**
  198. * Instantiate cmRegularExpression with compiled char*.
  199. */
  200. inline cmRegularExpression (char const*);
  201. /**
  202. * Instantiate cmRegularExpression as a copy of another regular expression.
  203. */
  204. cmRegularExpression (cmRegularExpression const&);
  205. /**
  206. * Destructor.
  207. */
  208. inline ~cmRegularExpression();
  209. /**
  210. * Compile a regular expression into internal code
  211. * for later pattern matching.
  212. */
  213. void compile (char const*);
  214. /**
  215. * Matches the regular expression to the given string.
  216. * Returns true if found, and sets start and end indexes accordingly.
  217. */
  218. bool find (char const*);
  219. /**
  220. * Matches the regular expression to the given std string.
  221. * Returns true if found, and sets start and end indexes accordingly.
  222. */
  223. bool find (std::string const&);
  224. /**
  225. * Index to start of first find.
  226. */
  227. inline long start() const;
  228. /**
  229. * Index to end of first find.
  230. */
  231. inline long end() const;
  232. /**
  233. * Returns true if two regular expressions have the same
  234. * compiled program for pattern matching.
  235. */
  236. bool operator== (cmRegularExpression const&) const;
  237. /**
  238. * Returns true if two regular expressions have different
  239. * compiled program for pattern matching.
  240. */
  241. inline bool operator!= (cmRegularExpression const&) const;
  242. /**
  243. * Returns true if have the same compiled regular expressions
  244. * and the same start and end pointers.
  245. */
  246. bool deep_equal (cmRegularExpression const&) const;
  247. /**
  248. * True if the compiled regexp is valid.
  249. */
  250. inline bool is_valid() const;
  251. /**
  252. * Marks the regular expression as invalid.
  253. */
  254. inline void set_invalid();
  255. /**
  256. * Destructor.
  257. */
  258. // awf added
  259. int start(int n) const;
  260. int end(int n) const;
  261. std::string match(int n) const;
  262. private:
  263. const char* startp[NSUBEXP];
  264. const char* endp[NSUBEXP];
  265. char regstart; // Internal use only
  266. char reganch; // Internal use only
  267. const char* regmust; // Internal use only
  268. int regmlen; // Internal use only
  269. char* program;
  270. int progsize;
  271. const char* searchstring;
  272. };
  273. /**
  274. * Create an empty regular expression.
  275. */
  276. inline cmRegularExpression::cmRegularExpression ()
  277. {
  278. this->program = NULL;
  279. }
  280. /**
  281. * Creates a regular expression from string s, and
  282. * compiles s.
  283. */
  284. inline cmRegularExpression::cmRegularExpression (const char* s)
  285. {
  286. this->program = NULL;
  287. compile(s);
  288. }
  289. /**
  290. * Destroys and frees space allocated for the regular expression.
  291. */
  292. inline cmRegularExpression::~cmRegularExpression ()
  293. {
  294. //#ifndef WIN32
  295. delete [] this->program;
  296. //#endif
  297. }
  298. /**
  299. * Set the start position for the regular expression.
  300. */
  301. inline long cmRegularExpression::start () const
  302. {
  303. return(this->startp[0] - searchstring);
  304. }
  305. /**
  306. * Returns the start/end index of the last item found.
  307. */
  308. inline long cmRegularExpression::end () const
  309. {
  310. return(this->endp[0] - searchstring);
  311. }
  312. /**
  313. * Returns true if two regular expressions have different
  314. * compiled program for pattern matching.
  315. */
  316. inline bool cmRegularExpression::operator!= (const cmRegularExpression& r) const
  317. {
  318. return(!(*this == r));
  319. }
  320. /**
  321. * Returns true if a valid regular expression is compiled
  322. * and ready for pattern matching.
  323. */
  324. inline bool cmRegularExpression::is_valid () const
  325. {
  326. return (this->program != NULL);
  327. }
  328. inline void cmRegularExpression::set_invalid ()
  329. {
  330. //#ifndef WIN32
  331. delete [] this->program;
  332. //#endif
  333. this->program = NULL;
  334. }
  335. /**
  336. * Return start index of nth submatch. start(0) is the start of the full match.
  337. */
  338. inline int cmRegularExpression::start(int n) const
  339. {
  340. return this->startp[n] - searchstring;
  341. }
  342. /**
  343. * Return end index of nth submatch. end(0) is the end of the full match.
  344. */
  345. inline int cmRegularExpression::end(int n) const
  346. {
  347. return this->endp[n] - searchstring;
  348. }
  349. /**
  350. * Return nth submatch as a string.
  351. */
  352. inline std::string cmRegularExpression::match(int n) const
  353. {
  354. return std::string(this->startp[n], this->endp[n] - this->startp[n]);
  355. }
  356. #endif // cmRegularExpressionh