16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 /**
27 * @test
28 * @summary tests RegExp framework
29 * @author Mike McCloskey
30 * @bug 4481568 4482696 4495089 4504687 4527731 4599621 4631553 4619345
31 * 4630911 4672616 4711773 4727935 4750573 4792284 4803197 4757029 4808962
32 * 4872664 4803179 4892980 4900747 4945394 4938995 4979006 4994840 4997476
33 * 5013885 5003322 4988891 5098443 5110268 6173522 4829857 5027748 6376940
34 * 6358731 6178785 6284152 6231989 6497148 6486934 6233084 6504326 6635133
35 * 6350801 6676425 6878475 6919132 6931676 6948903 6990617 7014645 7039066
36 * 7067045 7014640 7189363 8007395
37 */
38
39 import java.util.regex.*;
40 import java.util.Random;
41 import java.io.*;
42 import java.util.*;
43 import java.nio.CharBuffer;
44
45 /**
46 * This is a test class created to check the operation of
47 * the Pattern and Matcher classes.
48 */
49 public class RegExTest {
50
51 private static Random generator = new Random();
52 private static boolean failure = false;
53 private static int failCount = 0;
54 private static String firstFailure = null;
55
56 /**
3373 while ((index = line.indexOf("\\n")) != -1) {
3374 StringBuffer temp = new StringBuffer(line);
3375 temp.replace(index, index+2, "\n");
3376 line = temp.toString();
3377 }
3378 while ((index = line.indexOf("\\u")) != -1) {
3379 StringBuffer temp = new StringBuffer(line);
3380 String value = temp.substring(index+2, index+6);
3381 char aChar = (char)Integer.parseInt(value, 16);
3382 String unicodeChar = "" + aChar;
3383 temp.replace(index, index+6, unicodeChar);
3384 line = temp.toString();
3385 }
3386
3387 return line;
3388 }
3389
3390 private static void check(Pattern p, String s, String g, String expected) {
3391 Matcher m = p.matcher(s);
3392 m.find();
3393 if (!m.group(g).equals(expected))
3394 failCount++;
3395 }
3396
3397 private static void checkReplaceFirst(String p, String s, String r, String expected)
3398 {
3399 if (!expected.equals(Pattern.compile(p)
3400 .matcher(s)
3401 .replaceFirst(r)))
3402 failCount++;
3403 }
3404
3405 private static void checkReplaceAll(String p, String s, String r, String expected)
3406 {
3407 if (!expected.equals(Pattern.compile(p)
3408 .matcher(s)
3409 .replaceAll(r)))
3410 failCount++;
3411 }
3412
3413 private static void checkExpectedFail(String p) {
3414 try {
3415 Pattern.compile(p);
3416 } catch (PatternSyntaxException pse) {
3417 //pse.printStackTrace();
3418 return;
3419 }
3420 failCount++;
3421 }
3422
3423 private static void checkExpectedFail(Matcher m, String g) {
3424 m.find();
3425 try {
3426 m.group(g);
3427 } catch (IllegalArgumentException iae) {
3428 //iae.printStackTrace();
3429 return;
3430 } catch (NullPointerException npe) {
3431 return;
3432 }
3433 failCount++;
3434 }
3435
3436
3437 private static void namedGroupCaptureTest() throws Exception {
3438 check(Pattern.compile("x+(?<gname>y+)z+"),
3439 "xxxyyyzzz",
3440 "gname",
3441 "yyy");
3442
3443 check(Pattern.compile("x+(?<gname8>y+)z+"),
3444 "xxxyyyzzz",
3445 "gname8",
3446 "yyy");
3447
3448 //backref
3449 Pattern pattern = Pattern.compile("(a*)bc\\1");
3450 check(pattern, "zzzaabcazzz", true); // found "abca"
3451
3452 check(Pattern.compile("(?<gname>a*)bc\\k<gname>"),
3453 "zzzaabcaazzz", true);
3454
3455 check(Pattern.compile("(?<gname>abc)(def)\\k<gname>"),
3542 "${dog}",
3543 "zzzDogzzzDogAndCatzzz");
3544
3545
3546 checkReplaceAll("(?<dog>Dog)AndCat",
3547 "zzzDogAndCatzzzDogAndCatzzz",
3548 "${dog}",
3549 "zzzDogzzzDogzzz");
3550
3551 // backref in Matcher & String
3552 if (!"abcdefghij".replaceFirst("cd(?<gn>ef)gh", "${gn}").equals("abefij") ||
3553 !"abbbcbdbefgh".replaceAll("(?<gn>[a-e])b", "${gn}").equals("abcdefgh"))
3554 failCount++;
3555
3556 // negative
3557 checkExpectedFail("(?<groupnamehasnoascii.in>abc)(def)");
3558 checkExpectedFail("(?<groupnamehasnoascii_in>abc)(def)");
3559 checkExpectedFail("(?<6groupnamestartswithdigit>abc)(def)");
3560 checkExpectedFail("(?<gname>abc)(def)\\k<gnameX>");
3561 checkExpectedFail("(?<gname>abc)(?<gname>def)\\k<gnameX>");
3562 checkExpectedFail(Pattern.compile("(?<gname>abc)(def)").matcher("abcdef"),
3563 "gnameX");
3564 checkExpectedFail(Pattern.compile("(?<gname>abc)(def)").matcher("abcdef"),
3565 null);
3566 report("NamedGroupCapture");
3567 }
3568
3569 // This is for bug 6969132
3570 private static void nonBmpClassComplementTest() throws Exception {
3571 Pattern p = Pattern.compile("\\P{Lu}");
3572 Matcher m = p.matcher(new String(new int[] {0x1d400}, 0, 1));
3573 if (m.find() && m.start() == 1)
3574 failCount++;
3575
3576 // from a unicode category
3577 p = Pattern.compile("\\P{Lu}");
3578 m = p.matcher(new String(new int[] {0x1d400}, 0, 1));
3579 if (m.find())
3580 failCount++;
3581 if (!m.hitEnd())
3582 failCount++;
3583
3584 // block
3585 p = Pattern.compile("\\P{InMathematicalAlphanumericSymbols}");
3742 Matcher wordU = Pattern.compile("\\w", Pattern.UNICODE_CHARACTER_CLASS).matcher("");
3743 // embedded flag (?U)
3744 Matcher lowerEU = Pattern.compile("(?U)\\p{Lower}", Pattern.UNICODE_CHARACTER_CLASS).matcher("");
3745 Matcher graphEU = Pattern.compile("(?U)\\p{Graph}", Pattern.UNICODE_CHARACTER_CLASS).matcher("");
3746 Matcher wordEU = Pattern.compile("(?U)\\w", Pattern.UNICODE_CHARACTER_CLASS).matcher("");
3747
3748 Matcher bwb = Pattern.compile("\\b\\w\\b").matcher("");
3749 Matcher bwbU = Pattern.compile("\\b\\w++\\b", Pattern.UNICODE_CHARACTER_CLASS).matcher("");
3750 Matcher bwbEU = Pattern.compile("(?U)\\b\\w++\\b", Pattern.UNICODE_CHARACTER_CLASS).matcher("");
3751 // properties
3752 Matcher lowerP = Pattern.compile("\\p{IsLowerCase}").matcher("");
3753 Matcher upperP = Pattern.compile("\\p{IsUpperCase}").matcher("");
3754 Matcher titleP = Pattern.compile("\\p{IsTitleCase}").matcher("");
3755 Matcher letterP = Pattern.compile("\\p{IsLetter}").matcher("");
3756 Matcher alphaP = Pattern.compile("\\p{IsAlphabetic}").matcher("");
3757 Matcher ideogP = Pattern.compile("\\p{IsIdeographic}").matcher("");
3758 Matcher cntrlP = Pattern.compile("\\p{IsControl}").matcher("");
3759 Matcher spaceP = Pattern.compile("\\p{IsWhiteSpace}").matcher("");
3760 Matcher definedP = Pattern.compile("\\p{IsAssigned}").matcher("");
3761 Matcher nonCCPP = Pattern.compile("\\p{IsNoncharacterCodePoint}").matcher("");
3762
3763 // javaMethod
3764 Matcher lowerJ = Pattern.compile("\\p{javaLowerCase}").matcher("");
3765 Matcher upperJ = Pattern.compile("\\p{javaUpperCase}").matcher("");
3766 Matcher alphaJ = Pattern.compile("\\p{javaAlphabetic}").matcher("");
3767 Matcher ideogJ = Pattern.compile("\\p{javaIdeographic}").matcher("");
3768
3769 for (int cp = 1; cp < 0x30000; cp++) {
3770 String str = new String(Character.toChars(cp));
3771 int type = Character.getType(cp);
3772 if (// lower
3773 POSIX_ASCII.isLower(cp) != lower.reset(str).matches() ||
3774 Character.isLowerCase(cp) != lowerU.reset(str).matches() ||
3775 Character.isLowerCase(cp) != lowerP.reset(str).matches() ||
3776 Character.isLowerCase(cp) != lowerEU.reset(str).matches()||
3777 Character.isLowerCase(cp) != lowerJ.reset(str).matches()||
3778 // upper
3779 POSIX_ASCII.isUpper(cp) != upper.reset(str).matches() ||
3780 POSIX_Unicode.isUpper(cp) != upperU.reset(str).matches() ||
3781 Character.isUpperCase(cp) != upperP.reset(str).matches() ||
3812 // hexdigit
3813 POSIX_ASCII.isHexDigit(cp) != xdigit.reset(str).matches() ||
3814 POSIX_Unicode.isHexDigit(cp) != xdigitU.reset(str).matches() ||
3815 // space
3816 POSIX_ASCII.isSpace(cp) != space.reset(str).matches() ||
3817 POSIX_Unicode.isSpace(cp) != spaceU.reset(str).matches() ||
3818 POSIX_Unicode.isSpace(cp) != spaceP.reset(str).matches() ||
3819 // word
3820 POSIX_ASCII.isWord(cp) != word.reset(str).matches() ||
3821 POSIX_Unicode.isWord(cp) != wordU.reset(str).matches() ||
3822 POSIX_Unicode.isWord(cp) != wordEU.reset(str).matches()||
3823 // bwordb
3824 POSIX_ASCII.isWord(cp) != bwb.reset(str).matches() ||
3825 POSIX_Unicode.isWord(cp) != bwbU.reset(str).matches() ||
3826 // properties
3827 Character.isTitleCase(cp) != titleP.reset(str).matches() ||
3828 Character.isLetter(cp) != letterP.reset(str).matches()||
3829 Character.isIdeographic(cp) != ideogP.reset(str).matches() ||
3830 Character.isIdeographic(cp) != ideogJ.reset(str).matches() ||
3831 (Character.UNASSIGNED == type) == definedP.reset(str).matches() ||
3832 POSIX_Unicode.isNoncharacterCodePoint(cp) != nonCCPP.reset(str).matches())
3833 failCount++;
3834 }
3835
3836 // bounds/word align
3837 twoFindIndexes(" \u0180sherman\u0400 ", bound, 1, 10);
3838 if (!bwbU.reset("\u0180sherman\u0400").matches())
3839 failCount++;
3840 twoFindIndexes(" \u0180sh\u0345erman\u0400 ", bound, 1, 11);
3841 if (!bwbU.reset("\u0180sh\u0345erman\u0400").matches())
3842 failCount++;
3843 twoFindIndexes(" \u0724\u0739\u0724 ", bound, 1, 4);
3844 if (!bwbU.reset("\u0724\u0739\u0724").matches())
3845 failCount++;
3846 if (!bwbEU.reset("\u0724\u0739\u0724").matches())
3847 failCount++;
3848 report("unicodePredefinedClasses");
3849 }
3850
3851 private static void horizontalAndVerticalWSTest() throws Exception {
3852 String hws = new String (new char[] {
|
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 /**
27 * @test
28 * @summary tests RegExp framework
29 * @author Mike McCloskey
30 * @bug 4481568 4482696 4495089 4504687 4527731 4599621 4631553 4619345
31 * 4630911 4672616 4711773 4727935 4750573 4792284 4803197 4757029 4808962
32 * 4872664 4803179 4892980 4900747 4945394 4938995 4979006 4994840 4997476
33 * 5013885 5003322 4988891 5098443 5110268 6173522 4829857 5027748 6376940
34 * 6358731 6178785 6284152 6231989 6497148 6486934 6233084 6504326 6635133
35 * 6350801 6676425 6878475 6919132 6931676 6948903 6990617 7014645 7039066
36 * 7067045 7014640 7189363 8007395 8013252 8013254
37 */
38
39 import java.util.regex.*;
40 import java.util.Random;
41 import java.io.*;
42 import java.util.*;
43 import java.nio.CharBuffer;
44
45 /**
46 * This is a test class created to check the operation of
47 * the Pattern and Matcher classes.
48 */
49 public class RegExTest {
50
51 private static Random generator = new Random();
52 private static boolean failure = false;
53 private static int failCount = 0;
54 private static String firstFailure = null;
55
56 /**
3373 while ((index = line.indexOf("\\n")) != -1) {
3374 StringBuffer temp = new StringBuffer(line);
3375 temp.replace(index, index+2, "\n");
3376 line = temp.toString();
3377 }
3378 while ((index = line.indexOf("\\u")) != -1) {
3379 StringBuffer temp = new StringBuffer(line);
3380 String value = temp.substring(index+2, index+6);
3381 char aChar = (char)Integer.parseInt(value, 16);
3382 String unicodeChar = "" + aChar;
3383 temp.replace(index, index+6, unicodeChar);
3384 line = temp.toString();
3385 }
3386
3387 return line;
3388 }
3389
3390 private static void check(Pattern p, String s, String g, String expected) {
3391 Matcher m = p.matcher(s);
3392 m.find();
3393 if (!m.group(g).equals(expected) ||
3394 s.charAt(m.start(g)) != expected.charAt(0) ||
3395 s.charAt(m.end(g) - 1) != expected.charAt(expected.length() - 1))
3396 failCount++;
3397 }
3398
3399 private static void checkReplaceFirst(String p, String s, String r, String expected)
3400 {
3401 if (!expected.equals(Pattern.compile(p)
3402 .matcher(s)
3403 .replaceFirst(r)))
3404 failCount++;
3405 }
3406
3407 private static void checkReplaceAll(String p, String s, String r, String expected)
3408 {
3409 if (!expected.equals(Pattern.compile(p)
3410 .matcher(s)
3411 .replaceAll(r)))
3412 failCount++;
3413 }
3414
3415 private static void checkExpectedFail(String p) {
3416 try {
3417 Pattern.compile(p);
3418 } catch (PatternSyntaxException pse) {
3419 //pse.printStackTrace();
3420 return;
3421 }
3422 failCount++;
3423 }
3424
3425 private static void checkExpectedIAE(Matcher m, String g) {
3426 m.find();
3427 try {
3428 m.group(g);
3429 } catch (IllegalArgumentException x) {
3430 //iae.printStackTrace();
3431 try {
3432 m.start(g);
3433 } catch (IllegalArgumentException xx) {
3434 try {
3435 m.start(g);
3436 } catch (IllegalArgumentException xxx) {
3437 return;
3438 }
3439 }
3440 }
3441 failCount++;
3442 }
3443
3444 private static void checkExpectedNPE(Matcher m) {
3445 m.find();
3446 try {
3447 m.group(null);
3448 } catch (NullPointerException x) {
3449 try {
3450 m.start(null);
3451 } catch (NullPointerException xx) {
3452 try {
3453 m.end(null);
3454 } catch (NullPointerException xxx) {
3455 return;
3456 }
3457 }
3458 }
3459 failCount++;
3460 }
3461
3462 private static void namedGroupCaptureTest() throws Exception {
3463 check(Pattern.compile("x+(?<gname>y+)z+"),
3464 "xxxyyyzzz",
3465 "gname",
3466 "yyy");
3467
3468 check(Pattern.compile("x+(?<gname8>y+)z+"),
3469 "xxxyyyzzz",
3470 "gname8",
3471 "yyy");
3472
3473 //backref
3474 Pattern pattern = Pattern.compile("(a*)bc\\1");
3475 check(pattern, "zzzaabcazzz", true); // found "abca"
3476
3477 check(Pattern.compile("(?<gname>a*)bc\\k<gname>"),
3478 "zzzaabcaazzz", true);
3479
3480 check(Pattern.compile("(?<gname>abc)(def)\\k<gname>"),
3567 "${dog}",
3568 "zzzDogzzzDogAndCatzzz");
3569
3570
3571 checkReplaceAll("(?<dog>Dog)AndCat",
3572 "zzzDogAndCatzzzDogAndCatzzz",
3573 "${dog}",
3574 "zzzDogzzzDogzzz");
3575
3576 // backref in Matcher & String
3577 if (!"abcdefghij".replaceFirst("cd(?<gn>ef)gh", "${gn}").equals("abefij") ||
3578 !"abbbcbdbefgh".replaceAll("(?<gn>[a-e])b", "${gn}").equals("abcdefgh"))
3579 failCount++;
3580
3581 // negative
3582 checkExpectedFail("(?<groupnamehasnoascii.in>abc)(def)");
3583 checkExpectedFail("(?<groupnamehasnoascii_in>abc)(def)");
3584 checkExpectedFail("(?<6groupnamestartswithdigit>abc)(def)");
3585 checkExpectedFail("(?<gname>abc)(def)\\k<gnameX>");
3586 checkExpectedFail("(?<gname>abc)(?<gname>def)\\k<gnameX>");
3587 checkExpectedIAE(Pattern.compile("(?<gname>abc)(def)").matcher("abcdef"),
3588 "gnameX");
3589 checkExpectedNPE(Pattern.compile("(?<gname>abc)(def)").matcher("abcdef"));
3590 report("NamedGroupCapture");
3591 }
3592
3593 // This is for bug 6969132
3594 private static void nonBmpClassComplementTest() throws Exception {
3595 Pattern p = Pattern.compile("\\P{Lu}");
3596 Matcher m = p.matcher(new String(new int[] {0x1d400}, 0, 1));
3597 if (m.find() && m.start() == 1)
3598 failCount++;
3599
3600 // from a unicode category
3601 p = Pattern.compile("\\P{Lu}");
3602 m = p.matcher(new String(new int[] {0x1d400}, 0, 1));
3603 if (m.find())
3604 failCount++;
3605 if (!m.hitEnd())
3606 failCount++;
3607
3608 // block
3609 p = Pattern.compile("\\P{InMathematicalAlphanumericSymbols}");
3766 Matcher wordU = Pattern.compile("\\w", Pattern.UNICODE_CHARACTER_CLASS).matcher("");
3767 // embedded flag (?U)
3768 Matcher lowerEU = Pattern.compile("(?U)\\p{Lower}", Pattern.UNICODE_CHARACTER_CLASS).matcher("");
3769 Matcher graphEU = Pattern.compile("(?U)\\p{Graph}", Pattern.UNICODE_CHARACTER_CLASS).matcher("");
3770 Matcher wordEU = Pattern.compile("(?U)\\w", Pattern.UNICODE_CHARACTER_CLASS).matcher("");
3771
3772 Matcher bwb = Pattern.compile("\\b\\w\\b").matcher("");
3773 Matcher bwbU = Pattern.compile("\\b\\w++\\b", Pattern.UNICODE_CHARACTER_CLASS).matcher("");
3774 Matcher bwbEU = Pattern.compile("(?U)\\b\\w++\\b", Pattern.UNICODE_CHARACTER_CLASS).matcher("");
3775 // properties
3776 Matcher lowerP = Pattern.compile("\\p{IsLowerCase}").matcher("");
3777 Matcher upperP = Pattern.compile("\\p{IsUpperCase}").matcher("");
3778 Matcher titleP = Pattern.compile("\\p{IsTitleCase}").matcher("");
3779 Matcher letterP = Pattern.compile("\\p{IsLetter}").matcher("");
3780 Matcher alphaP = Pattern.compile("\\p{IsAlphabetic}").matcher("");
3781 Matcher ideogP = Pattern.compile("\\p{IsIdeographic}").matcher("");
3782 Matcher cntrlP = Pattern.compile("\\p{IsControl}").matcher("");
3783 Matcher spaceP = Pattern.compile("\\p{IsWhiteSpace}").matcher("");
3784 Matcher definedP = Pattern.compile("\\p{IsAssigned}").matcher("");
3785 Matcher nonCCPP = Pattern.compile("\\p{IsNoncharacterCodePoint}").matcher("");
3786 Matcher joinCrtl = Pattern.compile("\\p{IsJoinControl}").matcher("");
3787
3788 // javaMethod
3789 Matcher lowerJ = Pattern.compile("\\p{javaLowerCase}").matcher("");
3790 Matcher upperJ = Pattern.compile("\\p{javaUpperCase}").matcher("");
3791 Matcher alphaJ = Pattern.compile("\\p{javaAlphabetic}").matcher("");
3792 Matcher ideogJ = Pattern.compile("\\p{javaIdeographic}").matcher("");
3793
3794 for (int cp = 1; cp < 0x30000; cp++) {
3795 String str = new String(Character.toChars(cp));
3796 int type = Character.getType(cp);
3797 if (// lower
3798 POSIX_ASCII.isLower(cp) != lower.reset(str).matches() ||
3799 Character.isLowerCase(cp) != lowerU.reset(str).matches() ||
3800 Character.isLowerCase(cp) != lowerP.reset(str).matches() ||
3801 Character.isLowerCase(cp) != lowerEU.reset(str).matches()||
3802 Character.isLowerCase(cp) != lowerJ.reset(str).matches()||
3803 // upper
3804 POSIX_ASCII.isUpper(cp) != upper.reset(str).matches() ||
3805 POSIX_Unicode.isUpper(cp) != upperU.reset(str).matches() ||
3806 Character.isUpperCase(cp) != upperP.reset(str).matches() ||
3837 // hexdigit
3838 POSIX_ASCII.isHexDigit(cp) != xdigit.reset(str).matches() ||
3839 POSIX_Unicode.isHexDigit(cp) != xdigitU.reset(str).matches() ||
3840 // space
3841 POSIX_ASCII.isSpace(cp) != space.reset(str).matches() ||
3842 POSIX_Unicode.isSpace(cp) != spaceU.reset(str).matches() ||
3843 POSIX_Unicode.isSpace(cp) != spaceP.reset(str).matches() ||
3844 // word
3845 POSIX_ASCII.isWord(cp) != word.reset(str).matches() ||
3846 POSIX_Unicode.isWord(cp) != wordU.reset(str).matches() ||
3847 POSIX_Unicode.isWord(cp) != wordEU.reset(str).matches()||
3848 // bwordb
3849 POSIX_ASCII.isWord(cp) != bwb.reset(str).matches() ||
3850 POSIX_Unicode.isWord(cp) != bwbU.reset(str).matches() ||
3851 // properties
3852 Character.isTitleCase(cp) != titleP.reset(str).matches() ||
3853 Character.isLetter(cp) != letterP.reset(str).matches()||
3854 Character.isIdeographic(cp) != ideogP.reset(str).matches() ||
3855 Character.isIdeographic(cp) != ideogJ.reset(str).matches() ||
3856 (Character.UNASSIGNED == type) == definedP.reset(str).matches() ||
3857 POSIX_Unicode.isNoncharacterCodePoint(cp) != nonCCPP.reset(str).matches() ||
3858 POSIX_Unicode.isJoinControl(cp) != joinCrtl.reset(str).matches())
3859 failCount++;
3860 }
3861
3862 // bounds/word align
3863 twoFindIndexes(" \u0180sherman\u0400 ", bound, 1, 10);
3864 if (!bwbU.reset("\u0180sherman\u0400").matches())
3865 failCount++;
3866 twoFindIndexes(" \u0180sh\u0345erman\u0400 ", bound, 1, 11);
3867 if (!bwbU.reset("\u0180sh\u0345erman\u0400").matches())
3868 failCount++;
3869 twoFindIndexes(" \u0724\u0739\u0724 ", bound, 1, 4);
3870 if (!bwbU.reset("\u0724\u0739\u0724").matches())
3871 failCount++;
3872 if (!bwbEU.reset("\u0724\u0739\u0724").matches())
3873 failCount++;
3874 report("unicodePredefinedClasses");
3875 }
3876
3877 private static void horizontalAndVerticalWSTest() throws Exception {
3878 String hws = new String (new char[] {
|