1 /* 2 ******************************************************************************* 3 * Copyright (C) 1996-2015, International Business Machines Corporation and * 4 * others. All Rights Reserved. * 5 ******************************************************************************* 6 */ 7 8 package com.ibm.icu.text; 9 10 import java.text.CharacterIterator; 11 12 /** 13 * <tt>SearchIterator</tt> is an abstract base class that provides 14 * methods to search for a pattern within a text string. Instances of 15 * <tt>SearchIterator</tt> maintain a current position and scan over the 16 * target text, returning the indices the pattern is matched and the length 17 * of each match. 18 * <p> 19 * <tt>SearchIterator</tt> defines a protocol for text searching. 20 * Subclasses provide concrete implementations of various search algorithms. 21 * For example, <tt>StringSearch</tt> implements language-sensitive pattern 22 * matching based on the comparison rules defined in a 23 * <tt>RuleBasedCollator</tt> object. 24 * <p> 25 * Other options for searching include using a BreakIterator to restrict 26 * the points at which matches are detected. 27 * <p> 28 * <tt>SearchIterator</tt> provides an API that is similar to that of 29 * other text iteration classes such as <tt>BreakIterator</tt>. Using 30 * this class, it is easy to scan through text looking for all occurrences of 31 * a given pattern. The following example uses a <tt>StringSearch</tt> 32 * object to find all instances of "fox" in the target string. Any other 33 * subclass of <tt>SearchIterator</tt> can be used in an identical 34 * manner. 35 * <pre><code> 36 * String target = "The quick brown fox jumped over the lazy fox"; 37 * String pattern = "fox"; 38 * SearchIterator iter = new StringSearch(pattern, target); 39 * for (int pos = iter.first(); pos != SearchIterator.DONE; 40 * pos = iter.next()) { 41 * System.out.println("Found match at " + pos + 42 * ", length is " + iter.getMatchLength()); 43 * } 44 * </code></pre> 45 * 46 * @author Laura Werner, synwee 47 * @stable ICU 2.0 48 * @see BreakIterator 49 * @see RuleBasedCollator 50 */ 51 public abstract class SearchIterator 52 { 53 /** 54 * The BreakIterator to define the boundaries of a logical match. 55 * This value can be a null. 56 * See class documentation for more information. 57 * @see #setBreakIterator(BreakIterator) 58 * @see #getBreakIterator 59 * @see BreakIterator 60 * @stable ICU 2.0 61 */ 62 protected BreakIterator breakIterator; 63 64 /** 65 * Target text for searching. 66 * @see #setTarget(CharacterIterator) 67 * @see #getTarget 68 * @stable ICU 2.0 69 */ 70 protected CharacterIterator targetText; 71 /** 72 * Length of the most current match in target text. 73 * Value 0 is the default value. 74 * @see #setMatchLength 75 * @see #getMatchLength 76 * @stable ICU 2.0 77 */ 78 protected int matchLength; 79 80 /** 81 * Java port of ICU4C struct USearch (usrchimp.h) 82 * 83 * Note: 84 * 85 * ICU4J already exposed some protected members such as 86 * targetText, breakIterator and matchedLength as a part of stable 87 * APIs. In ICU4C, they are exposed through USearch struct, 88 * although USearch struct itself is internal API. 89 * 90 * This class was created for making ICU4J code parallel to 91 * ICU4C implementation. ICU4J implementation access member 92 * fields like C struct (e.g. search_.isOverlap_) mostly, except 93 * fields already exposed as protected member (e.g. search_.text()). 94 * 95 */ 96 final class Search { 97 text()98 CharacterIterator text() { 99 return SearchIterator.this.targetText; 100 } 101 setTarget(CharacterIterator text)102 void setTarget(CharacterIterator text) { 103 SearchIterator.this.targetText = text; 104 } 105 106 /** Flag to indicate if overlapping search is to be done. 107 E.g. looking for "aa" in "aaa" will yield matches at offset 0 and 1. */ 108 boolean isOverlap_; 109 110 boolean isCanonicalMatch_; 111 112 ElementComparisonType elementComparisonType_; 113 114 BreakIterator internalBreakIter_; 115 breakIter()116 BreakIterator breakIter() { 117 return SearchIterator.this.breakIterator; 118 } 119 setBreakIter(BreakIterator breakIter)120 void setBreakIter(BreakIterator breakIter) { 121 SearchIterator.this.breakIterator = breakIter; 122 } 123 124 int matchedIndex_; 125 matchedLength()126 int matchedLength() { 127 return SearchIterator.this.matchLength; 128 } 129 setMatchedLength(int matchedLength)130 void setMatchedLength(int matchedLength) { 131 SearchIterator.this.matchLength = matchedLength; 132 } 133 134 /** Flag indicates if we are doing a forwards search */ 135 boolean isForwardSearching_; 136 137 /** Flag indicates if we are at the start of a string search. 138 This indicates that we are in forward search and at the start of m_text. */ 139 boolean reset_; 140 141 // Convenient methods for accessing begin/end index of the 142 // target text. These are ICU4J only and are not data fields. beginIndex()143 int beginIndex() { 144 if (targetText == null) { 145 return 0; 146 } 147 return targetText.getBeginIndex(); 148 } 149 endIndex()150 int endIndex() { 151 if (targetText == null) { 152 return 0; 153 } 154 return targetText.getEndIndex(); 155 } 156 } 157 158 Search search_ = new Search(); 159 160 // public data members ------------------------------------------------- 161 162 /** 163 * DONE is returned by previous() and next() after all valid matches have 164 * been returned, and by first() and last() if there are no matches at all. 165 * @see #previous 166 * @see #next 167 * @stable ICU 2.0 168 */ 169 public static final int DONE = -1; 170 171 // public methods ----------------------------------------------------- 172 173 // public setters ----------------------------------------------------- 174 175 /** 176 * <p> 177 * Sets the position in the target text at which the next search will start. 178 * This method clears any previous match. 179 * </p> 180 * @param position position from which to start the next search 181 * @exception IndexOutOfBoundsException thrown if argument position is out 182 * of the target text range. 183 * @see #getIndex 184 * @stable ICU 2.8 185 */ setIndex(int position)186 public void setIndex(int position) { 187 if (position < search_.beginIndex() 188 || position > search_.endIndex()) { 189 throw new IndexOutOfBoundsException( 190 "setIndex(int) expected position to be between " + 191 search_.beginIndex() + " and " + search_.endIndex()); 192 } 193 search_.reset_ = false; 194 search_.setMatchedLength(0); 195 search_.matchedIndex_ = DONE; 196 } 197 198 /** 199 * Determines whether overlapping matches are returned. See the class 200 * documentation for more information about overlapping matches. 201 * <p> 202 * The default setting of this property is false 203 * 204 * @param allowOverlap flag indicator if overlapping matches are allowed 205 * @see #isOverlapping 206 * @stable ICU 2.8 207 */ setOverlapping(boolean allowOverlap)208 public void setOverlapping(boolean allowOverlap) { 209 search_.isOverlap_ = allowOverlap; 210 } 211 212 /** 213 * Set the BreakIterator that will be used to restrict the points 214 * at which matches are detected. 215 * 216 * @param breakiter A BreakIterator that will be used to restrict the 217 * points at which matches are detected. If a match is 218 * found, but the match's start or end index is not a 219 * boundary as determined by the {@link BreakIterator}, 220 * the match will be rejected and another will be searched 221 * for. If this parameter is <tt>null</tt>, no break 222 * detection is attempted. 223 * @see BreakIterator 224 * @stable ICU 2.0 225 */ setBreakIterator(BreakIterator breakiter)226 public void setBreakIterator(BreakIterator breakiter) { 227 search_.setBreakIter(breakiter); 228 if (search_.breakIter() != null) { 229 // Create a clone of CharacterItearator, so it won't 230 // affect the position currently held by search_.text() 231 if (search_.text() != null) { 232 search_.breakIter().setText((CharacterIterator)search_.text().clone()); 233 } 234 } 235 } 236 237 /** 238 * Set the target text to be searched. Text iteration will then begin at 239 * the start of the text string. This method is useful if you want to 240 * reuse an iterator to search within a different body of text. 241 * 242 * @param text new text iterator to look for match, 243 * @exception IllegalArgumentException thrown when text is null or has 244 * 0 length 245 * @see #getTarget 246 * @stable ICU 2.4 247 */ setTarget(CharacterIterator text)248 public void setTarget(CharacterIterator text) 249 { 250 if (text == null || text.getEndIndex() == text.getIndex()) { 251 throw new IllegalArgumentException("Illegal null or empty text"); 252 } 253 254 text.setIndex(text.getBeginIndex()); 255 search_.setTarget(text); 256 search_.matchedIndex_ = DONE; 257 search_.setMatchedLength(0); 258 search_.reset_ = true; 259 search_.isForwardSearching_ = true; 260 if (search_.breakIter() != null) { 261 // Create a clone of CharacterItearator, so it won't 262 // affect the position currently held by search_.text() 263 search_.breakIter().setText((CharacterIterator)text.clone()); 264 } 265 if (search_.internalBreakIter_ != null) { 266 search_.internalBreakIter_.setText((CharacterIterator)text.clone()); 267 } 268 } 269 270 //TODO: We may add APIs below to match ICU4C APIs 271 // setCanonicalMatch 272 273 // public getters ---------------------------------------------------- 274 275 /** 276 * Returns the index to the match in the text string that was searched. 277 * This call returns a valid result only after a successful call to 278 * {@link #first}, {@link #next}, {@link #previous}, or {@link #last}. 279 * Just after construction, or after a searching method returns 280 * {@link #DONE}, this method will return {@link #DONE}. 281 * <p> 282 * Use {@link #getMatchLength} to get the matched string length. 283 * 284 * @return index of a substring within the text string that is being 285 * searched. 286 * @see #first 287 * @see #next 288 * @see #previous 289 * @see #last 290 * @stable ICU 2.0 291 */ getMatchStart()292 public int getMatchStart() { 293 return search_.matchedIndex_; 294 } 295 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), {@link #DONE} 300 * is returned. 301 * 302 * @return current index in the text being searched. 303 * @stable ICU 2.8 304 */ getIndex()305 public abstract int getIndex(); 306 307 /** 308 * Returns the length of text in the string which matches the search 309 * pattern. This call returns a valid result only after a successful call 310 * to {@link #first}, {@link #next}, {@link #previous}, or {@link #last}. 311 * Just after construction, or after a searching method returns 312 * {@link #DONE}, this method will return 0. 313 * 314 * @return The length of the match in the target text, or 0 if there 315 * is no match currently. 316 * @see #first 317 * @see #next 318 * @see #previous 319 * @see #last 320 * @stable ICU 2.0 321 */ getMatchLength()322 public int getMatchLength() { 323 return search_.matchedLength(); 324 } 325 326 /** 327 * Returns the BreakIterator that is used to restrict the indexes at which 328 * matches are detected. This will be the same object that was passed to 329 * the constructor or to {@link #setBreakIterator}. 330 * If the {@link BreakIterator} has not been set, <tt>null</tt> will be returned. 331 * See {@link #setBreakIterator} for more information. 332 * 333 * @return the BreakIterator set to restrict logic matches 334 * @see #setBreakIterator 335 * @see BreakIterator 336 * @stable ICU 2.0 337 */ getBreakIterator()338 public BreakIterator getBreakIterator() { 339 return search_.breakIter(); 340 } 341 342 /** 343 * Return the string text to be searched. 344 * @return text string to be searched. 345 * @stable ICU 2.0 346 */ getTarget()347 public CharacterIterator getTarget() { 348 return search_.text(); 349 } 350 351 /** 352 * Returns the text that was matched by the most recent call to 353 * {@link #first}, {@link #next}, {@link #previous}, or {@link #last}. 354 * If the iterator is not pointing at a valid match (e.g. just after 355 * construction or after {@link #DONE} has been returned, 356 * returns an empty string. 357 * 358 * @return the substring in the target test of the most recent match, 359 * or null if there is no match currently. 360 * @see #first 361 * @see #next 362 * @see #previous 363 * @see #last 364 * @stable ICU 2.0 365 */ getMatchedText()366 public String getMatchedText() { 367 if (search_.matchedLength() > 0) { 368 int limit = search_.matchedIndex_ + search_.matchedLength(); 369 StringBuilder result = new StringBuilder(search_.matchedLength()); 370 CharacterIterator it = search_.text(); 371 it.setIndex(search_.matchedIndex_); 372 while (it.getIndex() < limit) { 373 result.append(it.current()); 374 it.next(); 375 } 376 it.setIndex(search_.matchedIndex_); 377 return result.toString(); 378 } 379 return null; 380 } 381 382 // miscellaneous public methods ----------------------------------------- 383 384 /** 385 * Returns the index of the next point at which the text matches the 386 * search pattern, starting from the current position 387 * The iterator is adjusted so that its current index (as returned by 388 * {@link #getIndex}) is the match position if one was found. 389 * If a match is not found, {@link #DONE} will be returned and 390 * the iterator will be adjusted to a position after the end of the text 391 * string. 392 * 393 * @return The index of the next match after the current position, 394 * or {@link #DONE} if there are no more matches. 395 * @see #getIndex 396 * @stable ICU 2.0 397 */ next()398 public int next() { 399 int index = getIndex(); // offset = getOffset() in ICU4C 400 int matchindex = search_.matchedIndex_; 401 int matchlength = search_.matchedLength(); 402 search_.reset_ = false; 403 if (search_.isForwardSearching_) { 404 int endIdx = search_.endIndex(); 405 if (index == endIdx || matchindex == endIdx || 406 (matchindex != DONE && 407 matchindex + matchlength >= endIdx)) { 408 setMatchNotFound(); 409 return DONE; 410 } 411 } else { 412 // switching direction. 413 // if matchedIndex == DONE, it means that either a 414 // setIndex (setOffset in C) has been called or that previous ran off the text 415 // string. the iterator would have been set to offset 0 if a 416 // match is not found. 417 search_.isForwardSearching_ = true; 418 if (search_.matchedIndex_ != DONE) { 419 // there's no need to set the collation element iterator 420 // the next call to next will set the offset. 421 return matchindex; 422 } 423 } 424 425 if (matchlength > 0) { 426 // if matchlength is 0 we are at the start of the iteration 427 if (search_.isOverlap_) { 428 index++; 429 } else { 430 index += matchlength; 431 } 432 } 433 434 return handleNext(index); 435 } 436 437 /** 438 * Returns the index of the previous point at which the string text 439 * matches the search pattern, starting at the current position. 440 * The iterator is adjusted so that its current index (as returned by 441 * {@link #getIndex}) is the match position if one was found. 442 * If a match is not found, {@link #DONE} will be returned and 443 * the iterator will be adjusted to the index {@link #DONE}. 444 * 445 * @return The index of the previous match before the current position, 446 * or {@link #DONE} if there are no more matches. 447 * @see #getIndex 448 * @stable ICU 2.0 449 */ previous()450 public int previous() { 451 int index; // offset in ICU4C 452 if (search_.reset_) { 453 index = search_.endIndex(); // m_search_->textLength in ICU4C 454 search_.isForwardSearching_ = false; 455 search_.reset_ = false; 456 setIndex(index); 457 } else { 458 index = getIndex(); 459 } 460 461 int matchindex = search_.matchedIndex_; 462 if (search_.isForwardSearching_) { 463 // switching direction. 464 // if matchedIndex == DONE, it means that either a 465 // setIndex (setOffset in C) has been called or that next ran off the text 466 // string. the iterator would have been set to offset textLength if 467 // a match is not found. 468 search_.isForwardSearching_ = false; 469 if (matchindex != DONE) { 470 return matchindex; 471 } 472 } else { 473 int startIdx = search_.beginIndex(); 474 if (index == startIdx || matchindex == startIdx) { 475 // not enough characters to match 476 setMatchNotFound(); 477 return DONE; 478 } 479 } 480 481 if (matchindex != DONE) { 482 if (search_.isOverlap_) { 483 matchindex += search_.matchedLength() - 2; 484 } 485 486 return handlePrevious(matchindex); 487 } 488 489 return handlePrevious(index); 490 } 491 492 /** 493 * Return true if the overlapping property has been set. 494 * See {@link #setOverlapping(boolean)} for more information. 495 * 496 * @see #setOverlapping 497 * @return true if the overlapping property has been set, false otherwise 498 * @stable ICU 2.8 499 */ isOverlapping()500 public boolean isOverlapping() { 501 return search_.isOverlap_; 502 } 503 504 //TODO: We may add APIs below to match ICU4C APIs 505 // isCanonicalMatch 506 507 /** 508 * Resets the iteration. 509 * Search will begin at the start of the text string if a forward 510 * iteration is initiated before a backwards iteration. Otherwise if a 511 * backwards iteration is initiated before a forwards iteration, the 512 * search will begin at the end of the text string. 513 * 514 * @stable ICU 2.0 515 */ reset()516 public void reset() { 517 setMatchNotFound(); 518 setIndex(search_.beginIndex()); 519 search_.isOverlap_ = false; 520 search_.isCanonicalMatch_ = false; 521 search_.elementComparisonType_ = ElementComparisonType.STANDARD_ELEMENT_COMPARISON; 522 search_.isForwardSearching_ = true; 523 search_.reset_ = true; 524 } 525 526 /** 527 * Returns the first index at which the string text matches the search 528 * pattern. The iterator is adjusted so that its current index (as 529 * returned by {@link #getIndex()}) is the match position if one 530 * 531 * was found. 532 * If a match is not found, {@link #DONE} will be returned and 533 * the iterator will be adjusted to the index {@link #DONE}. 534 * @return The character index of the first match, or 535 * {@link #DONE} if there are no matches. 536 * 537 * @see #getIndex 538 * @stable ICU 2.0 539 */ first()540 public final int first() { 541 int startIdx = search_.beginIndex(); 542 setIndex(startIdx); 543 return handleNext(startIdx); 544 } 545 546 /** 547 * Returns the first index equal or greater than <tt>position</tt> at which the 548 * string text matches the search pattern. The iterator is adjusted so 549 * that its current index (as returned by {@link #getIndex()}) is the 550 * match position if one was found. 551 * If a match is not found, {@link #DONE} will be returned and the 552 * iterator will be adjusted to the index {@link #DONE}. 553 * 554 * @param position where search if to start from. 555 * @return The character index of the first match following 556 * <tt>position</tt>, or {@link #DONE} if there are no matches. 557 * @throws IndexOutOfBoundsException If position is less than or greater 558 * than the text range for searching. 559 * @see #getIndex 560 * @stable ICU 2.0 561 */ following(int position)562 public final int following(int position) { 563 setIndex(position); 564 return handleNext(position); 565 } 566 567 /** 568 * Returns the last index in the target text at which it matches the 569 * search pattern. The iterator is adjusted so that its current index 570 * (as returned by {@link #getIndex}) is the match position if one was 571 * found. 572 * If a match is not found, {@link #DONE} will be returned and 573 * the iterator will be adjusted to the index {@link #DONE}. 574 * 575 * @return The index of the first match, or {@link #DONE} if 576 * there are no matches. 577 * @see #getIndex 578 * @stable ICU 2.0 579 */ last()580 public final int last() { 581 int endIdx = search_.endIndex(); 582 setIndex(endIdx); 583 return handlePrevious(endIdx); 584 } 585 586 /** 587 * Returns the first index less than <tt>position</tt> at which the string 588 * text matches the search pattern. The iterator is adjusted so that its 589 * current index (as returned by {@link #getIndex}) is the match 590 * position if one was found. If a match is not found, 591 * {@link #DONE} will be returned and the iterator will be 592 * adjusted to the index {@link #DONE} 593 * <p> 594 * When the overlapping option ({@link #isOverlapping}) is off, the last index of the 595 * result match is always less than <tt>position</tt>. 596 * When the overlapping option is on, the result match may span across 597 * <tt>position</tt>. 598 * 599 * @param position where search is to start from. 600 * @return The character index of the first match preceding 601 * <tt>position</tt>, or {@link #DONE} if there are 602 * no matches. 603 * @throws IndexOutOfBoundsException If position is less than or greater than 604 * the text range for searching 605 * @see #getIndex 606 * @stable ICU 2.0 607 */ preceding(int position)608 public final int preceding(int position) { 609 setIndex(position); 610 return handlePrevious(position); 611 } 612 613 // protected constructor ---------------------------------------------- 614 615 /** 616 * Protected constructor for use by subclasses. 617 * Initializes the iterator with the argument target text for searching 618 * and sets the BreakIterator. 619 * See class documentation for more details on the use of the target text 620 * and {@link BreakIterator}. 621 * 622 * @param target The target text to be searched. 623 * @param breaker A {@link BreakIterator} that is used to determine the 624 * boundaries of a logical match. This argument can be null. 625 * @exception IllegalArgumentException thrown when argument target is null, 626 * or of length 0 627 * @see BreakIterator 628 * @stable ICU 2.0 629 */ SearchIterator(CharacterIterator target, BreakIterator breaker)630 protected SearchIterator(CharacterIterator target, BreakIterator breaker) 631 { 632 if (target == null 633 || (target.getEndIndex() - target.getBeginIndex()) == 0) { 634 throw new IllegalArgumentException( 635 "Illegal argument target. " + 636 " Argument can not be null or of length 0"); 637 } 638 639 search_.setTarget(target); 640 search_.setBreakIter(breaker); 641 if (search_.breakIter() != null) { 642 search_.breakIter().setText((CharacterIterator)target.clone()); 643 } 644 search_.isOverlap_ = false; 645 search_.isCanonicalMatch_ = false; 646 search_.elementComparisonType_ = ElementComparisonType.STANDARD_ELEMENT_COMPARISON; 647 search_.isForwardSearching_ = true; 648 search_.reset_ = true; 649 search_.matchedIndex_ = DONE; 650 search_.setMatchedLength(0); 651 } 652 653 // protected methods -------------------------------------------------- 654 655 656 /** 657 * Sets the length of the most recent match in the target text. 658 * Subclasses' handleNext() and handlePrevious() methods should call this 659 * after they find a match in the target text. 660 * 661 * @param length new length to set 662 * @see #handleNext 663 * @see #handlePrevious 664 * @stable ICU 2.0 665 */ setMatchLength(int length)666 protected void setMatchLength(int length) 667 { 668 search_.setMatchedLength(length); 669 } 670 671 /** 672 * Abstract method which subclasses override to provide the mechanism 673 * for finding the next match in the target text. This allows different 674 * subclasses to provide different search algorithms. 675 * <p> 676 * If a match is found, the implementation should return the index at 677 * which the match starts and should call 678 * {@link #setMatchLength} with the number of characters 679 * in the target text that make up the match. If no match is found, the 680 * method should return {@link #DONE}. 681 * 682 * @param start The index in the target text at which the search 683 * should start. 684 * @return index at which the match starts, else if match is not found 685 * {@link #DONE} is returned 686 * @see #setMatchLength 687 * @stable ICU 2.0 688 */ handleNext(int start)689 protected abstract int handleNext(int start); 690 691 /** 692 * Abstract method which subclasses override to provide the mechanism for 693 * finding the previous match in the target text. This allows different 694 * subclasses to provide different search algorithms. 695 * <p> 696 * If a match is found, the implementation should return the index at 697 * which the match starts and should call 698 * {@link #setMatchLength} with the number of characters 699 * in the target text that make up the match. If no match is found, the 700 * method should return {@link #DONE}. 701 * 702 * @param startAt The index in the target text at which the search 703 * should start. 704 * @return index at which the match starts, else if match is not found 705 * {@link #DONE} is returned 706 * @see #setMatchLength 707 * @stable ICU 2.0 708 */ handlePrevious(int startAt)709 protected abstract int handlePrevious(int startAt); 710 711 /** 712 * @internal 713 * @deprecated This API is ICU internal only. 714 */ 715 @Deprecated 716 //TODO: This protected method is @stable 2.0 in ICU4C setMatchNotFound()717 protected void setMatchNotFound() { 718 search_.matchedIndex_ = DONE; 719 search_.setMatchedLength(0); 720 } 721 722 /** 723 * Option to control how collation elements are compared. 724 * The default value will be {@link #STANDARD_ELEMENT_COMPARISON}. 725 * <p> 726 * PATTERN_BASE_WEIGHT_IS_WILDCARD supports "asymmetric search" as described in 727 * <a href="http://www.unicode.org/reports/tr10/#Asymmetric_Search"> 728 * UTS #10 Unicode Collation Algorithm</a>, while ANY_BASE_WEIGHT_IS_WILDCARD 729 * supports a related option in which "unmarked" characters in either the 730 * pattern or the searched text are treated as wildcards that match marked or 731 * unmarked versions of the same character. 732 * 733 * @see #setElementComparisonType(ElementComparisonType) 734 * @see #getElementComparisonType() 735 * @stable ICU 53 736 */ 737 public enum ElementComparisonType { 738 /** 739 * Standard collation element comparison at the specified collator strength. 740 * 741 * @stable ICU 53 742 */ 743 STANDARD_ELEMENT_COMPARISON, 744 /** 745 * Collation element comparison is modified to effectively provide behavior 746 * between the specified strength and strength - 1. 747 * <p> 748 * Collation elements in the pattern that have the base weight for the specified 749 * strength are treated as "wildcards" that match an element with any other 750 * weight at that collation level in the searched text. For example, with a 751 * secondary-strength English collator, a plain 'e' in the pattern will match 752 * a plain e or an e with any diacritic in the searched text, but an e with 753 * diacritic in the pattern will only match an e with the same diacritic in 754 * the searched text. 755 * 756 * @stable ICU 53 757 */ 758 PATTERN_BASE_WEIGHT_IS_WILDCARD, 759 760 /** 761 * Collation element comparison is modified to effectively provide behavior 762 * between the specified strength and strength - 1. 763 * <p> 764 * Collation elements in either the pattern or the searched text that have the 765 * base weight for the specified strength are treated as "wildcards" that match 766 * an element with any other weight at that collation level. For example, with 767 * a secondary-strength English collator, a plain 'e' in the pattern will match 768 * a plain e or an e with any diacritic in the searched text, but an e with 769 * diacritic in the pattern will only match an e with the same diacritic or a 770 * plain e in the searched text. 771 * 772 * @stable ICU 53 773 */ 774 ANY_BASE_WEIGHT_IS_WILDCARD 775 } 776 777 /** 778 * Sets the collation element comparison type. 779 * <p> 780 * The default comparison type is {@link ElementComparisonType#STANDARD_ELEMENT_COMPARISON}. 781 * 782 * @see ElementComparisonType 783 * @see #getElementComparisonType() 784 * @stable ICU 53 785 */ setElementComparisonType(ElementComparisonType type)786 public void setElementComparisonType(ElementComparisonType type) { 787 search_.elementComparisonType_ = type; 788 } 789 790 /** 791 * Returns the collation element comparison type. 792 * 793 * @see ElementComparisonType 794 * @see #setElementComparisonType(ElementComparisonType) 795 * @stable ICU 53 796 */ getElementComparisonType()797 public ElementComparisonType getElementComparisonType() { 798 return search_.elementComparisonType_; 799 } 800 } 801