stsearch.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. // © 2016 and later: Unicode, Inc. and others.
  2. // License & terms of use: http://www.unicode.org/copyright.html
  3. /*
  4. **********************************************************************
  5. * Copyright (C) 2001-2014 IBM and others. All rights reserved.
  6. **********************************************************************
  7. * Date Name Description
  8. * 03/22/2000 helena Creation.
  9. **********************************************************************
  10. */
  11. #ifndef STSEARCH_H
  12. #define STSEARCH_H
  13. #include "unicode/utypes.h"
  14. #if U_SHOW_CPLUSPLUS_API
  15. /**
  16. * \file
  17. * \brief C++ API: Service for searching text based on RuleBasedCollator.
  18. */
  19. #if !UCONFIG_NO_COLLATION && !UCONFIG_NO_BREAK_ITERATION
  20. #include "unicode/tblcoll.h"
  21. #include "unicode/coleitr.h"
  22. #include "unicode/search.h"
  23. U_NAMESPACE_BEGIN
  24. /**
  25. *
  26. * <tt>StringSearch</tt> is a <tt>SearchIterator</tt> that provides
  27. * language-sensitive text searching based on the comparison rules defined
  28. * in a {@link RuleBasedCollator} object.
  29. * StringSearch ensures that language eccentricity can be
  30. * handled, e.g. for the German collator, characters &szlig; and SS will be matched
  31. * if case is chosen to be ignored.
  32. * See the <a href="https://htmlpreview.github.io/?https://github.com/unicode-org/icu-docs/blob/main/design/collation/ICU_collation_design.htm">
  33. * "ICU Collation Design Document"</a> for more information.
  34. * <p>
  35. * There are 2 match options for selection:<br>
  36. * Let S' be the sub-string of a text string S between the offsets start and
  37. * end [start, end].
  38. * <br>
  39. * A pattern string P matches a text string S at the offsets [start, end]
  40. * if
  41. * <pre>
  42. * option 1. Some canonical equivalent of P matches some canonical equivalent
  43. * of S'
  44. * option 2. P matches S' and if P starts or ends with a combining mark,
  45. * there exists no non-ignorable combining mark before or after S?
  46. * in S respectively.
  47. * </pre>
  48. * Option 2. will be the default.
  49. * <p>
  50. * This search has APIs similar to that of other text iteration mechanisms
  51. * such as the break iterators in <tt>BreakIterator</tt>. Using these
  52. * APIs, it is easy to scan through text looking for all occurrences of
  53. * a given pattern. This search iterator allows changing of direction by
  54. * calling a <tt>reset</tt> followed by a <tt>next</tt> or <tt>previous</tt>.
  55. * Though a direction change can occur without calling <tt>reset</tt> first,
  56. * this operation comes with some speed penalty.
  57. * Match results in the forward direction will match the result matches in
  58. * the backwards direction in the reverse order
  59. * <p>
  60. * <tt>SearchIterator</tt> provides APIs to specify the starting position
  61. * within the text string to be searched, e.g. <tt>setOffset</tt>,
  62. * <tt>preceding</tt> and <tt>following</tt>. Since the
  63. * starting position will be set as it is specified, please take note that
  64. * there are some danger points which the search may render incorrect
  65. * results:
  66. * <ul>
  67. * <li> The midst of a substring that requires normalization.
  68. * <li> If the following match is to be found, the position should not be the
  69. * second character which requires to be swapped with the preceding
  70. * character. Vice versa, if the preceding match is to be found,
  71. * position to search from should not be the first character which
  72. * requires to be swapped with the next character. E.g certain Thai and
  73. * Lao characters require swapping.
  74. * <li> If a following pattern match is to be found, any position within a
  75. * contracting sequence except the first will fail. Vice versa if a
  76. * preceding pattern match is to be found, a invalid starting point
  77. * would be any character within a contracting sequence except the last.
  78. * </ul>
  79. * <p>
  80. * A <tt>BreakIterator</tt> can be used if only matches at logical breaks are desired.
  81. * Using a <tt>BreakIterator</tt> will only give you results that exactly matches the
  82. * boundaries given by the breakiterator. For instance the pattern "e" will
  83. * not be found in the string "\u00e9" if a character break iterator is used.
  84. * <p>
  85. * Options are provided to handle overlapping matches.
  86. * E.g. In English, overlapping matches produces the result 0 and 2
  87. * for the pattern "abab" in the text "ababab", where else mutually
  88. * exclusive matches only produce the result of 0.
  89. * <p>
  90. * Though collator attributes will be taken into consideration while
  91. * performing matches, there are no APIs here for setting and getting the
  92. * attributes. These attributes can be set by getting the collator
  93. * from <tt>getCollator</tt> and using the APIs in <tt>coll.h</tt>.
  94. * Lastly to update <tt>StringSearch</tt> to the new collator attributes,
  95. * <tt>reset</tt> has to be called.
  96. * <p>
  97. * Restriction: <br>
  98. * Currently there are no composite characters that consists of a
  99. * character with combining class > 0 before a character with combining
  100. * class == 0. However, if such a character exists in the future,
  101. * <tt>StringSearch</tt> does not guarantee the results for option 1.
  102. * <p>
  103. * Consult the <tt>SearchIterator</tt> documentation for information on
  104. * and examples of how to use instances of this class to implement text
  105. * searching.
  106. * <pre><code>
  107. * UnicodeString target("The quick brown fox jumps over the lazy dog.");
  108. * UnicodeString pattern("fox");
  109. *
  110. * UErrorCode error = U_ZERO_ERROR;
  111. * StringSearch iter(pattern, target, Locale::getUS(), nullptr, status);
  112. * for (int pos = iter.first(error);
  113. * pos != USEARCH_DONE;
  114. * pos = iter.next(error))
  115. * {
  116. * printf("Found match at %d pos, length is %d\n", pos, iter.getMatchedLength());
  117. * }
  118. * </code></pre>
  119. * <p>
  120. * Note, <tt>StringSearch</tt> is not to be subclassed.
  121. * </p>
  122. * @see SearchIterator
  123. * @see RuleBasedCollator
  124. * @since ICU 2.0
  125. */
  126. class U_I18N_API StringSearch final : public SearchIterator
  127. {
  128. public:
  129. // public constructors and destructors --------------------------------
  130. /**
  131. * Creating a <tt>StringSearch</tt> instance using the argument locale
  132. * language rule set. A collator will be created in the process, which
  133. * will be owned by this instance and will be deleted during
  134. * destruction
  135. * @param pattern The text for which this object will search.
  136. * @param text The text in which to search for the pattern.
  137. * @param locale A locale which defines the language-sensitive
  138. * comparison rules used to determine whether text in the
  139. * pattern and target matches.
  140. * @param breakiter A <tt>BreakIterator</tt> object used to constrain
  141. * the matches that are found. Matches whose start and end
  142. * indices in the target text are not boundaries as
  143. * determined by the <tt>BreakIterator</tt> are
  144. * ignored. If this behavior is not desired,
  145. * <tt>nullptr</tt> can be passed in instead.
  146. * @param status for errors if any. If pattern or text is nullptr, or if
  147. * either the length of pattern or text is 0 then an
  148. * U_ILLEGAL_ARGUMENT_ERROR is returned.
  149. * @stable ICU 2.0
  150. */
  151. StringSearch(const UnicodeString &pattern, const UnicodeString &text,
  152. const Locale &locale,
  153. BreakIterator *breakiter,
  154. UErrorCode &status);
  155. /**
  156. * Creating a <tt>StringSearch</tt> instance using the argument collator
  157. * language rule set. Note, user retains the ownership of this collator,
  158. * it does not get destroyed during this instance's destruction.
  159. * @param pattern The text for which this object will search.
  160. * @param text The text in which to search for the pattern.
  161. * @param coll A <tt>RuleBasedCollator</tt> object which defines
  162. * the language-sensitive comparison rules used to
  163. * determine whether text in the pattern and target
  164. * matches. User is responsible for the clearing of this
  165. * object.
  166. * @param breakiter A <tt>BreakIterator</tt> object used to constrain
  167. * the matches that are found. Matches whose start and end
  168. * indices in the target text are not boundaries as
  169. * determined by the <tt>BreakIterator</tt> are
  170. * ignored. If this behavior is not desired,
  171. * <tt>nullptr</tt> can be passed in instead.
  172. * @param status for errors if any. If either the length of pattern or
  173. * text is 0 then an U_ILLEGAL_ARGUMENT_ERROR is returned.
  174. * @stable ICU 2.0
  175. */
  176. StringSearch(const UnicodeString &pattern,
  177. const UnicodeString &text,
  178. RuleBasedCollator *coll,
  179. BreakIterator *breakiter,
  180. UErrorCode &status);
  181. /**
  182. * Creating a <tt>StringSearch</tt> instance using the argument locale
  183. * language rule set. A collator will be created in the process, which
  184. * will be owned by this instance and will be deleted during
  185. * destruction
  186. * <p>
  187. * Note: No parsing of the text within the <tt>CharacterIterator</tt>
  188. * will be done during searching for this version. The block of text
  189. * in <tt>CharacterIterator</tt> will be used as it is.
  190. * @param pattern The text for which this object will search.
  191. * @param text The text iterator in which to search for the pattern.
  192. * @param locale A locale which defines the language-sensitive
  193. * comparison rules used to determine whether text in the
  194. * pattern and target matches. User is responsible for
  195. * the clearing of this object.
  196. * @param breakiter A <tt>BreakIterator</tt> object used to constrain
  197. * the matches that are found. Matches whose start and end
  198. * indices in the target text are not boundaries as
  199. * determined by the <tt>BreakIterator</tt> are
  200. * ignored. If this behavior is not desired,
  201. * <tt>nullptr</tt> can be passed in instead.
  202. * @param status for errors if any. If either the length of pattern or
  203. * text is 0 then an U_ILLEGAL_ARGUMENT_ERROR is returned.
  204. * @stable ICU 2.0
  205. */
  206. StringSearch(const UnicodeString &pattern, CharacterIterator &text,
  207. const Locale &locale,
  208. BreakIterator *breakiter,
  209. UErrorCode &status);
  210. /**
  211. * Creating a <tt>StringSearch</tt> instance using the argument collator
  212. * language rule set. Note, user retains the ownership of this collator,
  213. * it does not get destroyed during this instance's destruction.
  214. * <p>
  215. * Note: No parsing of the text within the <tt>CharacterIterator</tt>
  216. * will be done during searching for this version. The block of text
  217. * in <tt>CharacterIterator</tt> will be used as it is.
  218. * @param pattern The text for which this object will search.
  219. * @param text The text in which to search for the pattern.
  220. * @param coll A <tt>RuleBasedCollator</tt> object which defines
  221. * the language-sensitive comparison rules used to
  222. * determine whether text in the pattern and target
  223. * matches. User is responsible for the clearing of this
  224. * object.
  225. * @param breakiter A <tt>BreakIterator</tt> object used to constrain
  226. * the matches that are found. Matches whose start and end
  227. * indices in the target text are not boundaries as
  228. * determined by the <tt>BreakIterator</tt> are
  229. * ignored. If this behavior is not desired,
  230. * <tt>nullptr</tt> can be passed in instead.
  231. * @param status for errors if any. If either the length of pattern or
  232. * text is 0 then an U_ILLEGAL_ARGUMENT_ERROR is returned.
  233. * @stable ICU 2.0
  234. */
  235. StringSearch(const UnicodeString &pattern, CharacterIterator &text,
  236. RuleBasedCollator *coll,
  237. BreakIterator *breakiter,
  238. UErrorCode &status);
  239. /**
  240. * Copy constructor that creates a StringSearch instance with the same
  241. * behavior, and iterating over the same text.
  242. * @param that StringSearch instance to be copied.
  243. * @stable ICU 2.0
  244. */
  245. StringSearch(const StringSearch &that);
  246. /**
  247. * Destructor. Cleans up the search iterator data struct.
  248. * If a collator is created in the constructor, it will be destroyed here.
  249. * @stable ICU 2.0
  250. */
  251. virtual ~StringSearch();
  252. /**
  253. * Clone this object.
  254. * Clones can be used concurrently in multiple threads.
  255. * If an error occurs, then nullptr is returned.
  256. * The caller must delete the clone.
  257. *
  258. * @return a clone of this object
  259. *
  260. * @see getDynamicClassID
  261. * @stable ICU 2.8
  262. */
  263. StringSearch *clone() const;
  264. // operator overloading ---------------------------------------------
  265. /**
  266. * Assignment operator. Sets this iterator to have the same behavior,
  267. * and iterate over the same text, as the one passed in.
  268. * @param that instance to be copied.
  269. * @stable ICU 2.0
  270. */
  271. StringSearch & operator=(const StringSearch &that);
  272. /**
  273. * Equality operator.
  274. * @param that instance to be compared.
  275. * @return true if both instances have the same attributes,
  276. * breakiterators, collators and iterate over the same text
  277. * while looking for the same pattern.
  278. * @stable ICU 2.0
  279. */
  280. virtual bool operator==(const SearchIterator &that) const override;
  281. // public get and set methods ----------------------------------------
  282. /**
  283. * Sets the index to point to the given position, and clears any state
  284. * that's affected.
  285. * <p>
  286. * This method takes the argument index and sets the position in the text
  287. * string accordingly without checking if the index is pointing to a
  288. * valid starting point to begin searching.
  289. * @param position within the text to be set. If position is less
  290. * than or greater than the text range for searching,
  291. * an U_INDEX_OUTOFBOUNDS_ERROR will be returned
  292. * @param status for errors if it occurs
  293. * @stable ICU 2.0
  294. */
  295. virtual void setOffset(int32_t position, UErrorCode &status) override;
  296. /**
  297. * Return the current index in the text being searched.
  298. * If the iteration has gone past the end of the text
  299. * (or past the beginning for a backwards search), USEARCH_DONE
  300. * is returned.
  301. * @return current index in the text being searched.
  302. * @stable ICU 2.0
  303. */
  304. virtual int32_t getOffset() const override;
  305. /**
  306. * Set the target text to be searched.
  307. * Text iteration will hence begin at the start of the text string.
  308. * This method is
  309. * useful if you want to re-use an iterator to search for the same
  310. * pattern within a different body of text.
  311. * @param text text string to be searched
  312. * @param status for errors if any. If the text length is 0 then an
  313. * U_ILLEGAL_ARGUMENT_ERROR is returned.
  314. * @stable ICU 2.0
  315. */
  316. virtual void setText(const UnicodeString &text, UErrorCode &status) override;
  317. /**
  318. * Set the target text to be searched.
  319. * Text iteration will hence begin at the start of the text string.
  320. * This method is
  321. * useful if you want to re-use an iterator to search for the same
  322. * pattern within a different body of text.
  323. * Note: No parsing of the text within the <tt>CharacterIterator</tt>
  324. * will be done during searching for this version. The block of text
  325. * in <tt>CharacterIterator</tt> will be used as it is.
  326. * @param text text string to be searched
  327. * @param status for errors if any. If the text length is 0 then an
  328. * U_ILLEGAL_ARGUMENT_ERROR is returned.
  329. * @stable ICU 2.0
  330. */
  331. virtual void setText(CharacterIterator &text, UErrorCode &status) override;
  332. /**
  333. * Gets the collator used for the language rules.
  334. * <p>
  335. * Caller may modify but <b>must not</b> delete the <tt>RuleBasedCollator</tt>!
  336. * Modifications to this collator will affect the original collator passed in to
  337. * the <tt>StringSearch></tt> constructor or to setCollator, if any.
  338. * @return collator used for string search
  339. * @stable ICU 2.0
  340. */
  341. RuleBasedCollator * getCollator() const;
  342. /**
  343. * Sets the collator used for the language rules. User retains the
  344. * ownership of this collator, thus the responsibility of deletion lies
  345. * with the user. The iterator's position will not be changed by this method.
  346. * @param coll collator
  347. * @param status for errors if any
  348. * @stable ICU 2.0
  349. */
  350. void setCollator(RuleBasedCollator *coll, UErrorCode &status);
  351. /**
  352. * Sets the pattern used for matching.
  353. * The iterator's position will not be changed by this method.
  354. * @param pattern search pattern to be found
  355. * @param status for errors if any. If the pattern length is 0 then an
  356. * U_ILLEGAL_ARGUMENT_ERROR is returned.
  357. * @stable ICU 2.0
  358. */
  359. void setPattern(const UnicodeString &pattern, UErrorCode &status);
  360. /**
  361. * Gets the search pattern.
  362. * @return pattern used for matching
  363. * @stable ICU 2.0
  364. */
  365. const UnicodeString & getPattern() const;
  366. // public methods ----------------------------------------------------
  367. /**
  368. * Reset the iteration.
  369. * Search will begin at the start of the text string if a forward
  370. * iteration is initiated before a backwards iteration. Otherwise if
  371. * a backwards iteration is initiated before a forwards iteration, the
  372. * search will begin at the end of the text string.
  373. * @stable ICU 2.0
  374. */
  375. virtual void reset() override;
  376. /**
  377. * Returns a copy of StringSearch with the same behavior, and
  378. * iterating over the same text, as this one. Note that all data will be
  379. * replicated, except for the user-specified collator and the
  380. * breakiterator.
  381. * @return cloned object
  382. * @stable ICU 2.0
  383. */
  384. virtual StringSearch * safeClone() const override;
  385. /**
  386. * ICU "poor man's RTTI", returns a UClassID for the actual class.
  387. *
  388. * @stable ICU 2.2
  389. */
  390. virtual UClassID getDynamicClassID() const override;
  391. /**
  392. * ICU "poor man's RTTI", returns a UClassID for this class.
  393. *
  394. * @stable ICU 2.2
  395. */
  396. static UClassID U_EXPORT2 getStaticClassID();
  397. protected:
  398. // protected method -------------------------------------------------
  399. /**
  400. * Search forward for matching text, starting at a given location.
  401. * Clients should not call this method directly; instead they should
  402. * call {@link SearchIterator#next }.
  403. * <p>
  404. * If a match is found, this method returns the index at which the match
  405. * starts and calls {@link SearchIterator#setMatchLength } with the number
  406. * of characters in the target text that make up the match. If no match
  407. * is found, the method returns <tt>USEARCH_DONE</tt>.
  408. * <p>
  409. * The <tt>StringSearch</tt> is adjusted so that its current index
  410. * (as returned by {@link #getOffset }) is the match position if one was
  411. * found.
  412. * If a match is not found, <tt>USEARCH_DONE</tt> will be returned and
  413. * the <tt>StringSearch</tt> will be adjusted to the index USEARCH_DONE.
  414. * @param position The index in the target text at which the search
  415. * starts
  416. * @param status for errors if any occurs
  417. * @return The index at which the matched text in the target starts, or
  418. * USEARCH_DONE if no match was found.
  419. * @stable ICU 2.0
  420. */
  421. virtual int32_t handleNext(int32_t position, UErrorCode &status) override;
  422. /**
  423. * Search backward for matching text, starting at a given location.
  424. * Clients should not call this method directly; instead they should call
  425. * <tt>SearchIterator.previous()</tt>, which this method overrides.
  426. * <p>
  427. * If a match is found, this method returns the index at which the match
  428. * starts and calls {@link SearchIterator#setMatchLength } with the number
  429. * of characters in the target text that make up the match. If no match
  430. * is found, the method returns <tt>USEARCH_DONE</tt>.
  431. * <p>
  432. * The <tt>StringSearch</tt> is adjusted so that its current index
  433. * (as returned by {@link #getOffset }) is the match position if one was
  434. * found.
  435. * If a match is not found, <tt>USEARCH_DONE</tt> will be returned and
  436. * the <tt>StringSearch</tt> will be adjusted to the index USEARCH_DONE.
  437. * @param position The index in the target text at which the search
  438. * starts.
  439. * @param status for errors if any occurs
  440. * @return The index at which the matched text in the target starts, or
  441. * USEARCH_DONE if no match was found.
  442. * @stable ICU 2.0
  443. */
  444. virtual int32_t handlePrev(int32_t position, UErrorCode &status) override;
  445. private :
  446. StringSearch() = delete; // default constructor not implemented
  447. // private data members ----------------------------------------------
  448. /**
  449. * Pattern text
  450. * @stable ICU 2.0
  451. */
  452. UnicodeString m_pattern_;
  453. /**
  454. * String search struct data
  455. * @stable ICU 2.0
  456. */
  457. UStringSearch *m_strsrch_;
  458. };
  459. U_NAMESPACE_END
  460. #endif /* #if !UCONFIG_NO_COLLATION */
  461. #endif /* U_SHOW_CPLUSPLUS_API */
  462. #endif