| /* Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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. |
| */ |
| |
| package org.apache.harmony.regex.tests.java.util.regex; |
| |
| import dalvik.annotation.BrokenTest; |
| import dalvik.annotation.TestTargetClass; |
| import dalvik.annotation.TestTargets; |
| import dalvik.annotation.TestTargetNew; |
| import dalvik.annotation.TestLevel; |
| |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| import java.util.regex.PatternSyntaxException; |
| |
| import junit.framework.TestCase; |
| @TestTargetClass(Pattern.class) |
| /** |
| * Tests simple Pattern compilation and Matcher methods |
| * |
| */ |
| public class Pattern2Test extends TestCase { |
| |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies matches(String regex, CharSequence input) method.", |
| method = "matches", |
| args = {java.lang.String.class, java.lang.CharSequence.class} |
| ) |
| public void testSimpleMatch() throws PatternSyntaxException { |
| Pattern p = Pattern.compile("foo.*"); |
| |
| Matcher m1 = p.matcher("foo123"); |
| assertTrue(m1.matches()); |
| assertTrue(m1.find(0)); |
| assertTrue(m1.lookingAt()); |
| |
| Matcher m2 = p.matcher("fox"); |
| assertFalse(m2.matches()); |
| assertFalse(m2.find(0)); |
| assertFalse(m2.lookingAt()); |
| |
| assertTrue(Pattern.matches("foo.*", "foo123")); |
| assertFalse(Pattern.matches("foo.*", "fox")); |
| |
| assertFalse(Pattern.matches("bar", "foobar")); |
| |
| assertTrue(Pattern.matches("", "")); |
| } |
| @TestTargets({ |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies compile(String regex) method and matcher for created pattern.", |
| method = "compile", |
| args = {java.lang.String.class} |
| ), |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies compile(String regex) method and matcher for created pattern.", |
| method = "matcher", |
| args = {java.lang.CharSequence.class} |
| ) |
| }) |
| public void testCursors() { |
| Pattern p; |
| Matcher m; |
| |
| try { |
| p = Pattern.compile("foo"); |
| |
| m = p.matcher("foobar"); |
| assertTrue(m.find()); |
| assertEquals(0, m.start()); |
| assertEquals(3, m.end()); |
| assertFalse(m.find()); |
| |
| // Note: also testing reset here |
| m.reset(); |
| assertTrue(m.find()); |
| assertEquals(0, m.start()); |
| assertEquals(3, m.end()); |
| assertFalse(m.find()); |
| |
| m.reset("barfoobar"); |
| assertTrue(m.find()); |
| assertEquals(3, m.start()); |
| assertEquals(6, m.end()); |
| assertFalse(m.find()); |
| |
| m.reset("barfoo"); |
| assertTrue(m.find()); |
| assertEquals(3, m.start()); |
| assertEquals(6, m.end()); |
| assertFalse(m.find()); |
| |
| m.reset("foobarfoobarfoo"); |
| assertTrue(m.find()); |
| assertEquals(0, m.start()); |
| assertEquals(3, m.end()); |
| assertTrue(m.find()); |
| assertEquals(6, m.start()); |
| assertEquals(9, m.end()); |
| assertTrue(m.find()); |
| assertEquals(12, m.start()); |
| assertEquals(15, m.end()); |
| assertFalse(m.find()); |
| assertTrue(m.find(0)); |
| assertEquals(0, m.start()); |
| assertEquals(3, m.end()); |
| assertTrue(m.find(4)); |
| assertEquals(6, m.start()); |
| assertEquals(9, m.end()); |
| } catch (PatternSyntaxException e) { |
| System.out.println(e.getMessage()); |
| fail(); |
| } |
| } |
| @TestTargets({ |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies compile(String regex) method and matcher for created pattern.", |
| method = "compile", |
| args = {java.lang.String.class} |
| ), |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies compile(String regex) method and matcher for created pattern.", |
| method = "matcher", |
| args = {java.lang.CharSequence.class} |
| ) |
| }) |
| public void testGroups() throws PatternSyntaxException { |
| Pattern p; |
| Matcher m; |
| |
| p = Pattern.compile("(p[0-9]*)#?(q[0-9]*)"); |
| |
| m = p.matcher("p1#q3p2q42p5p71p63#q888"); |
| assertTrue(m.find()); |
| assertEquals(0, m.start()); |
| assertEquals(5, m.end()); |
| assertEquals(2, m.groupCount()); |
| assertEquals(0, m.start(0)); |
| assertEquals(5, m.end(0)); |
| assertEquals(0, m.start(1)); |
| assertEquals(2, m.end(1)); |
| assertEquals(3, m.start(2)); |
| assertEquals(5, m.end(2)); |
| assertEquals("p1#q3", m.group()); |
| assertEquals("p1#q3", m.group(0)); |
| assertEquals("p1", m.group(1)); |
| assertEquals("q3", m.group(2)); |
| |
| assertTrue(m.find()); |
| assertEquals(5, m.start()); |
| assertEquals(10, m.end()); |
| assertEquals(2, m.groupCount()); |
| assertEquals(10, m.end(0)); |
| assertEquals(5, m.start(1)); |
| assertEquals(7, m.end(1)); |
| assertEquals(7, m.start(2)); |
| assertEquals(10, m.end(2)); |
| assertEquals("p2q42", m.group()); |
| assertEquals("p2q42", m.group(0)); |
| assertEquals("p2", m.group(1)); |
| assertEquals("q42", m.group(2)); |
| |
| assertTrue(m.find()); |
| assertEquals(15, m.start()); |
| assertEquals(23, m.end()); |
| assertEquals(2, m.groupCount()); |
| assertEquals(15, m.start(0)); |
| assertEquals(23, m.end(0)); |
| assertEquals(15, m.start(1)); |
| assertEquals(18, m.end(1)); |
| assertEquals(19, m.start(2)); |
| assertEquals(23, m.end(2)); |
| assertEquals("p63#q888", m.group()); |
| assertEquals("p63#q888", m.group(0)); |
| assertEquals("p63", m.group(1)); |
| assertEquals("q888", m.group(2)); |
| assertFalse(m.find()); |
| } |
| |
| @TestTargets({ |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies compile(String regex) method and matcher for created pattern.", |
| method = "compile", |
| args = {java.lang.String.class} |
| ), |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies compile(String regex) method and matcher for created pattern.", |
| method = "matcher", |
| args = {java.lang.CharSequence.class} |
| ) |
| }) |
| public void testReplace() throws PatternSyntaxException { |
| Pattern p; |
| Matcher m; |
| |
| // Note: examples from book, |
| // Hitchens, Ron, 2002, "Java NIO", O'Reilly, page 171 |
| p = Pattern.compile("a*b"); |
| |
| m = p.matcher("aabfooaabfooabfoob"); |
| assertTrue(m.replaceAll("-").equals("-foo-foo-foo-")); |
| assertTrue(m.replaceFirst("-").equals("-fooaabfooabfoob")); |
| |
| /* |
| * p = Pattern.compile ("\\p{Blank}"); |
| * |
| * m = p.matcher ("fee fie foe fum"); assertTrue |
| * (m.replaceFirst("-").equals ("fee-fie foe fum")); assertTrue |
| * (m.replaceAll("-").equals ("fee-fie-foe-fum")); |
| */ |
| |
| p = Pattern.compile("([bB])yte"); |
| |
| m = p.matcher("Byte for byte"); |
| assertTrue(m.replaceFirst("$1ite").equals("Bite for byte")); |
| assertTrue(m.replaceAll("$1ite").equals("Bite for bite")); |
| |
| p = Pattern.compile("\\d\\d\\d\\d([- ])"); |
| |
| m = p.matcher("card #1234-5678-1234"); |
| assertTrue(m.replaceFirst("xxxx$1").equals("card #xxxx-5678-1234")); |
| assertTrue(m.replaceAll("xxxx$1").equals("card #xxxx-xxxx-1234")); |
| |
| p = Pattern.compile("(up|left)( *)(right|down)"); |
| |
| m = p.matcher("left right, up down"); |
| assertTrue(m.replaceFirst("$3$2$1").equals("right left, up down")); |
| assertTrue(m.replaceAll("$3$2$1").equals("right left, down up")); |
| |
| p = Pattern.compile("([CcPp][hl]e[ea]se)"); |
| |
| m = p.matcher("I want cheese. Please."); |
| assertTrue(m.replaceFirst("<b> $1 </b>").equals( |
| "I want <b> cheese </b>. Please.")); |
| assertTrue(m.replaceAll("<b> $1 </b>").equals( |
| "I want <b> cheese </b>. <b> Please </b>.")); |
| } |
| |
| @TestTargets({ |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies compile(String regex) method and matcher for created pattern.", |
| method = "compile", |
| args = {java.lang.String.class} |
| ), |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies compile(String regex) method and matcher for created pattern.", |
| method = "matcher", |
| args = {java.lang.CharSequence.class} |
| ) |
| }) |
| public void testEscapes() throws PatternSyntaxException { |
| Pattern p; |
| Matcher m; |
| |
| // Test \\ sequence |
| p = Pattern.compile("([a-z]+)\\\\([a-z]+);"); |
| m = p.matcher("fred\\ginger;abbott\\costello;jekell\\hyde;"); |
| assertTrue(m.find()); |
| assertEquals("fred", m.group(1)); |
| assertEquals("ginger", m.group(2)); |
| assertTrue(m.find()); |
| assertEquals("abbott", m.group(1)); |
| assertEquals("costello", m.group(2)); |
| assertTrue(m.find()); |
| assertEquals("jekell", m.group(1)); |
| assertEquals("hyde", m.group(2)); |
| assertFalse(m.find()); |
| |
| // Test \n, \t, \r, \f, \e, \a sequences |
| p = Pattern.compile("([a-z]+)[\\n\\t\\r\\f\\e\\a]+([a-z]+)"); |
| m = p.matcher("aa\nbb;cc\u0009\rdd;ee\u000C\u001Bff;gg\n\u0007hh"); |
| assertTrue(m.find()); |
| assertEquals("aa", m.group(1)); |
| assertEquals("bb", m.group(2)); |
| assertTrue(m.find()); |
| assertEquals("cc", m.group(1)); |
| assertEquals("dd", m.group(2)); |
| assertTrue(m.find()); |
| assertEquals("ee", m.group(1)); |
| assertEquals("ff", m.group(2)); |
| assertTrue(m.find()); |
| assertEquals("gg", m.group(1)); |
| assertEquals("hh", m.group(2)); |
| assertFalse(m.find()); |
| |
| // Test \\u and \\x sequences |
| /* p = Pattern.compile("([0-9]+)[\\u0020:\\x21];"); |
| m = p.matcher("11:;22 ;33-;44!;"); |
| assertTrue(m.find()); |
| assertEquals("11", m.group(1)); |
| assertTrue(m.find()); |
| assertEquals("22", m.group(1)); |
| assertTrue(m.find()); |
| assertEquals("44", m.group(1)); |
| assertFalse(m.find()); |
| */ |
| // Test invalid unicode sequences |
| /* try { |
| p = Pattern.compile("\\u"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| |
| try { |
| p = Pattern.compile("\\u;"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| |
| try { |
| p = Pattern.compile("\\u002"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| |
| try { |
| p = Pattern.compile("\\u002;"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| |
| // Test invalid hex sequences |
| try { |
| p = Pattern.compile("\\x"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| |
| try { |
| p = Pattern.compile("\\x;"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| |
| try { |
| p = Pattern.compile("\\xa"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| |
| try { |
| p = Pattern.compile("\\xa;"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| */ |
| // Test \0 (octal) sequences (1, 2 and 3 digit) |
| p = Pattern.compile("([0-9]+)[\\07\\040\\0160];"); |
| m = p.matcher("11\u0007;22:;33 ;44p;"); |
| assertTrue(m.find()); |
| assertEquals("11", m.group(1)); |
| assertTrue(m.find()); |
| assertEquals("33", m.group(1)); |
| assertTrue(m.find()); |
| assertEquals("44", m.group(1)); |
| assertFalse(m.find()); |
| |
| // Test invalid octal sequences |
| try { |
| p = Pattern.compile("\\08"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| |
| //originally contributed test did not check the result |
| //TODO: check what RI does here |
| // try { |
| // p = Pattern.compile("\\0477"); |
| // fail("PatternSyntaxException expected"); |
| // } catch (PatternSyntaxException e) { |
| // } |
| |
| try { |
| p = Pattern.compile("\\0"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| |
| try { |
| p = Pattern.compile("\\0;"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| |
| |
| // Test \c (control character) sequence |
| p = Pattern.compile("([0-9]+)[\\cA\\cB\\cC\\cD];"); |
| m = p.matcher("11\u0001;22:;33\u0002;44p;55\u0003;66\u0004;"); |
| assertTrue(m.find()); |
| assertEquals("11", m.group(1)); |
| assertTrue(m.find()); |
| assertEquals("33", m.group(1)); |
| assertTrue(m.find()); |
| assertEquals("55", m.group(1)); |
| assertTrue(m.find()); |
| assertEquals("66", m.group(1)); |
| assertFalse(m.find()); |
| |
| // More thorough control escape test |
| // Ensure that each escape matches exactly the corresponding |
| // character |
| // code and no others (well, from 0-255 at least) |
| int i, j; |
| for (i = 0; i < 26; i++) { |
| p = Pattern.compile("\\c" + Character.toString((char) ('A' + i))); |
| int match_char = -1; |
| for (j = 0; j < 255; j++) { |
| m = p.matcher(Character.toString((char) j)); |
| if (m.matches()) { |
| assertEquals(-1, match_char); |
| match_char = j; |
| } |
| } |
| assertTrue(match_char == i + 1); |
| } |
| |
| // Test invalid control escapes |
| // BEGIN android-removed |
| // ICU doesn't complain about illegal control sequences |
| // try { |
| // p = Pattern.compile("\\c"); |
| // fail("PatternSyntaxException expected"); |
| // } catch (PatternSyntaxException e) { |
| // } |
| // END android-removed |
| |
| //originally contributed test did not check the result |
| //TODO: check what RI does here |
| // try { |
| // p = Pattern.compile("\\c;"); |
| // fail("PatternSyntaxException expected"); |
| // } catch (PatternSyntaxException e) { |
| // } |
| // |
| // try { |
| // p = Pattern.compile("\\ca;"); |
| // fail("PatternSyntaxException expected"); |
| // } catch (PatternSyntaxException e) { |
| // } |
| // |
| // try { |
| // p = Pattern.compile("\\c4;"); |
| // fail("PatternSyntaxException expected"); |
| // } catch (PatternSyntaxException e) { |
| // } |
| } |
| @TestTargets({ |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies patterns with different ranges of characters.", |
| method = "compile", |
| args = {java.lang.String.class} |
| ), |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies patterns with different ranges of characters.", |
| method = "matcher", |
| args = {CharSequence.class} |
| ) |
| }) |
| public void testCharacterClasses() throws PatternSyntaxException { |
| Pattern p; |
| Matcher m; |
| |
| // Test one character range |
| p = Pattern.compile("[p].*[l]"); |
| m = p.matcher("paul"); |
| assertTrue(m.matches()); |
| m = p.matcher("pool"); |
| assertTrue(m.matches()); |
| m = p.matcher("pong"); |
| assertFalse(m.matches()); |
| m = p.matcher("pl"); |
| assertTrue(m.matches()); |
| |
| // Test two character range |
| p = Pattern.compile("[pm].*[lp]"); |
| m = p.matcher("prop"); |
| assertTrue(m.matches()); |
| m = p.matcher("mall"); |
| assertTrue(m.matches()); |
| m = p.matcher("pong"); |
| assertFalse(m.matches()); |
| m = p.matcher("pill"); |
| assertTrue(m.matches()); |
| |
| // Test range including [ and ] |
| p = Pattern.compile("[<\\[].*[\\]>]"); |
| m = p.matcher("<foo>"); |
| assertTrue(m.matches()); |
| m = p.matcher("[bar]"); |
| assertTrue(m.matches()); |
| m = p.matcher("{foobar]"); |
| assertFalse(m.matches()); |
| m = p.matcher("<pill]"); |
| assertTrue(m.matches()); |
| |
| // Test range using ^ |
| p = Pattern.compile("[^bc][a-z]+[tr]"); |
| m = p.matcher("pat"); |
| assertTrue(m.matches()); |
| m = p.matcher("liar"); |
| assertTrue(m.matches()); |
| m = p.matcher("car"); |
| assertFalse(m.matches()); |
| m = p.matcher("gnat"); |
| assertTrue(m.matches()); |
| |
| // Test character range using - |
| p = Pattern.compile("[a-z]_+[a-zA-Z]-+[0-9p-z]"); |
| m = p.matcher("d__F-8"); |
| assertTrue(m.matches()); |
| m = p.matcher("c_a-q"); |
| assertTrue(m.matches()); |
| m = p.matcher("a__R-a"); |
| assertFalse(m.matches()); |
| m = p.matcher("r_____d-----5"); |
| assertTrue(m.matches()); |
| |
| // Test range using unicode characters and unicode and hex escapes |
| p = Pattern.compile("[\\u1234-\\u2345]_+[a-z]-+[\u0001-\\x11]"); |
| m = p.matcher("\u2000_q-\u0007"); |
| assertTrue(m.matches()); |
| m = p.matcher("\u1234_z-\u0001"); |
| assertTrue(m.matches()); |
| m = p.matcher("r_p-q"); |
| assertFalse(m.matches()); |
| m = p.matcher("\u2345_____d-----\n"); |
| assertTrue(m.matches()); |
| |
| // BEGIN android-removed |
| // The "---" collides with ICU's "--" operator and is likely to be a user error |
| // anyway, so we simply comment this one out. |
| // // Test ranges including the "-" character |
| // p = Pattern.compile("[\\*-/]_+[---]!+[--AP]"); |
| // m = p.matcher("-_-!!A"); |
| // assertTrue(m.matches()); |
| // m = p.matcher("\u002b_-!!!-"); |
| // assertTrue(m.matches()); |
| // m = p.matcher("!_-!@"); |
| // assertFalse(m.matches()); |
| // m = p.matcher(",______-!!!!!!!P"); |
| // assertTrue(m.matches()); |
| // END android-removed |
| |
| // Test nested ranges |
| p = Pattern.compile("[pm[t]][a-z]+[[r]lp]"); |
| m = p.matcher("prop"); |
| assertTrue(m.matches()); |
| m = p.matcher("tsar"); |
| assertTrue(m.matches()); |
| m = p.matcher("pong"); |
| assertFalse(m.matches()); |
| m = p.matcher("moor"); |
| assertTrue(m.matches()); |
| |
| // Test character class intersection with && |
| // TODO: figure out what x&&y or any class with a null intersection |
| // set (like [[a-c]&&[d-f]]) might mean. It doesn't mean "match |
| // nothing" and doesn't mean "match anything" so I'm stumped. |
| p = Pattern.compile("[[a-p]&&[g-z]]+-+[[a-z]&&q]-+[x&&[a-z]]-+"); |
| m = p.matcher("h--q--x--"); |
| assertTrue(m.matches()); |
| m = p.matcher("hog--q-x-"); |
| assertTrue(m.matches()); |
| m = p.matcher("ape--q-x-"); |
| assertFalse(m.matches()); |
| m = p.matcher("mop--q-x----"); |
| assertTrue(m.matches()); |
| |
| // Test error cases with && |
| // BEGIN android-removed |
| // This is more of a bug, and ICU doesn't have this behavior. |
| // p = Pattern.compile("[&&[xyz]]"); |
| // m = p.matcher("&"); |
| // // System.out.println(m.matches()); |
| // m = p.matcher("x"); |
| // // System.out.println(m.matches()); |
| // m = p.matcher("y"); |
| // // System.out.println(m.matches()); |
| // END android-removed |
| p = Pattern.compile("[[xyz]&[axy]]"); |
| m = p.matcher("x"); |
| // System.out.println(m.matches()); |
| m = p.matcher("z"); |
| // System.out.println(m.matches()); |
| m = p.matcher("&"); |
| // System.out.println(m.matches()); |
| p = Pattern.compile("[abc[123]&&[345]def]"); |
| m = p.matcher("a"); |
| // System.out.println(m.matches()); |
| |
| // BEGIN android-removed |
| // This is more of a bug, and ICU doesn't have this behavior. |
| // p = Pattern.compile("[[xyz]&&]"); |
| // END android-removed |
| p = Pattern.compile("[[abc]&]"); |
| |
| try { |
| p = Pattern.compile("[[abc]&&"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| |
| p = Pattern.compile("[[abc]\\&&[xyz]]"); |
| |
| p = Pattern.compile("[[abc]&\\&[xyz]]"); |
| |
| // Test 3-way intersection |
| p = Pattern.compile("[[a-p]&&[g-z]&&[d-k]]"); |
| m = p.matcher("g"); |
| assertTrue(m.matches()); |
| m = p.matcher("m"); |
| assertFalse(m.matches()); |
| |
| // Test nested intersection |
| p = Pattern.compile("[[[a-p]&&[g-z]]&&[d-k]]"); |
| m = p.matcher("g"); |
| assertTrue(m.matches()); |
| m = p.matcher("m"); |
| assertFalse(m.matches()); |
| |
| // Test character class subtraction with && and ^ |
| p = Pattern.compile("[[a-z]&&[^aeiou]][aeiou][[^xyz]&&[a-z]]"); |
| m = p.matcher("pop"); |
| assertTrue(m.matches()); |
| m = p.matcher("tag"); |
| assertTrue(m.matches()); |
| m = p.matcher("eat"); |
| assertFalse(m.matches()); |
| m = p.matcher("tax"); |
| assertFalse(m.matches()); |
| m = p.matcher("zip"); |
| assertTrue(m.matches()); |
| |
| // Test . (DOT), with and without DOTALL |
| // Note: DOT not allowed in character classes |
| p = Pattern.compile(".+/x.z"); |
| m = p.matcher("!$/xyz"); |
| assertTrue(m.matches()); |
| m = p.matcher("%\n\r/x\nz"); |
| assertFalse(m.matches()); |
| p = Pattern.compile(".+/x.z", Pattern.DOTALL); |
| m = p.matcher("%\n\r/x\nz"); |
| assertTrue(m.matches()); |
| |
| // Test \d (digit) |
| p = Pattern.compile("\\d+[a-z][\\dx]"); |
| m = p.matcher("42a6"); |
| assertTrue(m.matches()); |
| m = p.matcher("21zx"); |
| assertTrue(m.matches()); |
| m = p.matcher("ab6"); |
| assertFalse(m.matches()); |
| m = p.matcher("56912f9"); |
| assertTrue(m.matches()); |
| |
| // Test \D (not a digit) |
| p = Pattern.compile("\\D+[a-z]-[\\D3]"); |
| m = p.matcher("za-p"); |
| assertTrue(m.matches()); |
| m = p.matcher("%!e-3"); |
| assertTrue(m.matches()); |
| m = p.matcher("9a-x"); |
| assertFalse(m.matches()); |
| m = p.matcher("\u1234pp\ny-3"); |
| assertTrue(m.matches()); |
| |
| // Test \s (whitespace) |
| p = Pattern.compile("<[a-zA-Z]+\\s+[0-9]+[\\sx][^\\s]>"); |
| m = p.matcher("<cat \t1\fx>"); |
| assertTrue(m.matches()); |
| m = p.matcher("<cat \t1\f >"); |
| assertFalse(m.matches()); |
| m = p |
| .matcher("xyz <foo\n\r22 5> <pp \t\n\f\r \u000b41x\u1234><pp \nx7\rc> zzz"); |
| assertTrue(m.find()); |
| assertTrue(m.find()); |
| assertFalse(m.find()); |
| |
| // Test \S (not whitespace) |
| p = Pattern.compile("<[a-z] \\S[0-9][\\S\n]+[^\\S]221>"); |
| m = p.matcher("<f $0**\n** 221>"); |
| assertTrue(m.matches()); |
| m = p.matcher("<x 441\t221>"); |
| assertTrue(m.matches()); |
| m = p.matcher("<z \t9\ng 221>"); |
| assertFalse(m.matches()); |
| m = p.matcher("<z 60\ngg\u1234\f221>"); |
| assertTrue(m.matches()); |
| p = Pattern.compile("<[a-z] \\S[0-9][\\S\n]+[^\\S]221[\\S&&[^abc]]>"); |
| m = p.matcher("<f $0**\n** 221x>"); |
| assertTrue(m.matches()); |
| m = p.matcher("<x 441\t221z>"); |
| assertTrue(m.matches()); |
| m = p.matcher("<x 441\t221 >"); |
| assertFalse(m.matches()); |
| m = p.matcher("<x 441\t221c>"); |
| assertFalse(m.matches()); |
| m = p.matcher("<z \t9\ng 221x>"); |
| assertFalse(m.matches()); |
| m = p.matcher("<z 60\ngg\u1234\f221\u0001>"); |
| assertTrue(m.matches()); |
| |
| // Test \w (ascii word) |
| p = Pattern.compile("<\\w+\\s[0-9]+;[^\\w]\\w+/[\\w$]+;"); |
| m = p.matcher("<f1 99;!foo5/a$7;"); |
| assertTrue(m.matches()); |
| m = p.matcher("<f$ 99;!foo5/a$7;"); |
| assertFalse(m.matches()); |
| m = p |
| .matcher("<abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789 99;!foo5/a$7;"); |
| assertTrue(m.matches()); |
| |
| // Test \W (not an ascii word) |
| p = Pattern.compile("<\\W\\w+\\s[0-9]+;[\\W_][^\\W]+\\s[0-9]+;"); |
| m = p.matcher("<$foo3\n99;_bar\t0;"); |
| assertTrue(m.matches()); |
| m = p.matcher("<hh 99;_g 0;"); |
| assertFalse(m.matches()); |
| m = p.matcher("<*xx\t00;^zz\f11;"); |
| assertTrue(m.matches()); |
| |
| // Test x|y pattern |
| // TODO |
| } |
| @TestTargets({ |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies compile(String regex) method and matcher for patterns with POSIX characters.", |
| method = "compile", |
| args = {java.lang.String.class} |
| ), |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies compile(String regex) method and matcher for patterns with POSIX characters.", |
| method = "matcher", |
| args = {java.lang.CharSequence.class} |
| ) |
| }) |
| public void testPOSIXGroups() throws PatternSyntaxException { |
| Pattern p; |
| Matcher m; |
| |
| // Test POSIX groups using \p and \P (in the group and not in the group) |
| // Groups are Lower, Upper, ASCII, Alpha, Digit, XDigit, Alnum, Punct, |
| // Graph, Print, Blank, Space, Cntrl |
| // Test \p{Lower} |
| /* |
| * FIXME: Requires complex range processing |
| * p = Pattern.compile("<\\p{Lower}\\d\\P{Lower}:[\\p{Lower}Z]\\s[^\\P{Lower}]>"); |
| * m = p.matcher("<a4P:g x>"); assertTrue(m.matches()); m = |
| * p.matcher("<p4%:Z\tq>"); assertTrue(m.matches()); m = |
| * p.matcher("<A6#:e e>"); assertFalse(m.matches()); |
| */ |
| p = Pattern.compile("\\p{Lower}+"); |
| m = p.matcher("abcdefghijklmnopqrstuvwxyz"); |
| assertTrue(m.matches()); |
| |
| // Invalid uses of \p{Lower} |
| try { |
| p = Pattern.compile("\\p"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| |
| try { |
| p = Pattern.compile("\\p;"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| |
| try { |
| p = Pattern.compile("\\p{"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| |
| try { |
| p = Pattern.compile("\\p{;"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| |
| try { |
| p = Pattern.compile("\\p{Lower"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| |
| try { |
| p = Pattern.compile("\\p{Lower;"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| |
| // Test \p{Upper} |
| /* |
| * FIXME: Requires complex range processing |
| * p = Pattern.compile("<\\p{Upper}\\d\\P{Upper}:[\\p{Upper}z]\\s[^\\P{Upper}]>"); |
| * m = p.matcher("<A4p:G X>"); assertTrue(m.matches()); m = |
| * p.matcher("<P4%:z\tQ>"); assertTrue(m.matches()); m = |
| * p.matcher("<a6#:E E>"); assertFalse(m.matches()); |
| */ |
| p = Pattern.compile("\\p{Upper}+"); |
| m = p.matcher("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); |
| assertTrue(m.matches()); |
| |
| // Invalid uses of \p{Upper} |
| try { |
| p = Pattern.compile("\\p{Upper"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| |
| try { |
| p = Pattern.compile("\\p{Upper;"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| |
| // Test \p{ASCII} |
| /* |
| * FIXME: Requires complex range processing p = Pattern.compile("<\\p{ASCII}\\d\\P{ASCII}:[\\p{ASCII}\u1234]\\s[^\\P{ASCII}]>"); |
| * m = p.matcher("<A4\u0080:G X>"); assertTrue(m.matches()); m = |
| * p.matcher("<P4\u00ff:\u1234\t\n>"); assertTrue(m.matches()); m = |
| * p.matcher("<\u00846#:E E>"); assertFalse(m.matches()) |
| */ |
| int i; |
| p = Pattern.compile("\\p{ASCII}"); |
| for (i = 0; i < 0x80; i++) { |
| m = p.matcher(Character.toString((char) i)); |
| assertTrue(m.matches()); |
| } |
| for (; i < 0xff; i++) { |
| m = p.matcher(Character.toString((char) i)); |
| assertFalse(m.matches()); |
| } |
| |
| // Invalid uses of \p{ASCII} |
| try { |
| p = Pattern.compile("\\p{ASCII"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| |
| try { |
| p = Pattern.compile("\\p{ASCII;"); |
| fail("PatternSyntaxException expected"); |
| } catch (PatternSyntaxException e) { |
| } |
| |
| // Test \p{Alpha} |
| // TODO |
| |
| // Test \p{Digit} |
| // TODO |
| |
| // Test \p{XDigit} |
| // TODO |
| |
| // Test \p{Alnum} |
| // TODO |
| |
| // Test \p{Punct} |
| // TODO |
| |
| // Test \p{Graph} |
| // TODO |
| |
| // Test \p{Print} |
| // TODO |
| |
| // Test \p{Blank} |
| // TODO |
| |
| // Test \p{Space} |
| // TODO |
| |
| // Test \p{Cntrl} |
| // TODO |
| } |
| @TestTargetNew( |
| level = TestLevel.ADDITIONAL, |
| notes = "", |
| method = "!", |
| args = {} |
| ) |
| public void testUnicodeCategories() throws PatternSyntaxException { |
| // Test Unicode categories using \p and \P |
| // One letter codes: L, M, N, P, S, Z, C |
| // Two letter codes: Lu, Nd, Sc, Sm, ... |
| // See java.lang.Character and Unicode standard for complete list |
| // TODO |
| // Test \p{L} |
| // TODO |
| |
| // Test \p{N} |
| // TODO |
| |
| // Test two letter codes: |
| // From unicode.org: |
| // Lu |
| // Ll |
| // Lt |
| // Lm |
| // Lo |
| // Mn |
| // Mc |
| // Me |
| // Nd |
| // Nl |
| // No |
| // Pc |
| // Pd |
| // Ps |
| // Pe |
| // Pi |
| // Pf |
| // Po |
| // Sm |
| // Sc |
| // Sk |
| // So |
| // Zs |
| // Zl |
| // Zp |
| // Cc |
| // Cf |
| // Cs |
| // Co |
| // Cn |
| |
| // TODO add more tests per category |
| //{"Cc", "\u0000", "-\u0041"}, |
| testCategory("Cf", "\u202B"); |
| testCategory("Co", "\uE000"); |
| testCategory("Cs", "\uD800"); |
| testCategory("Ll", "a", "b", "x", "y", "z", "-A", "-Z"); |
| testCategory("Lm", "\u02B9"); |
| testCategory("Lu", "B", "C", "-c"); |
| testCategory("Lo", "\u05E2"); |
| testCategory("Lt", "\u01C5"); |
| testCategory("Mc", "\u0903"); |
| testCategory("Me", "\u06DE"); |
| testCategory("Mn", "\u0300"); |
| testCategory("Nd", "\u0030"); |
| testCategory("Nl", "\u2164"); |
| testCategory("No", "\u0BF0"); |
| // testCategory("Pc", "\u30FB"); |
| testCategory("Pd", "\u2015"); |
| testCategory("Pe", "\u207E"); |
| testCategory("Po", "\u00B7"); |
| testCategory("Ps", "\u0F3C"); |
| testCategory("Sc", "\u20A0"); |
| testCategory("Sk", "\u00B8"); |
| testCategory("Sm", "\u002B"); |
| testCategory("So", "\u0B70"); |
| testCategory("Zl", "\u2028"); |
| // testCategory("Pi", "\u200C"); |
| testCategory("Zp", "\u2029"); |
| } |
| |
| private void testCategory(String cat, String... matches) { |
| String pa = "{"+cat+"}"; |
| String pat = "\\p"+pa; |
| String npat = "\\P"+pa; |
| Pattern p = Pattern.compile(pat); |
| Pattern pn = Pattern.compile(npat); |
| for (int j = 0; j < matches.length; j++) { |
| String t = matches[j]; |
| boolean invert = t.startsWith("-"); |
| if (invert) { |
| // test negative case, expected to fail |
| t = t.substring(1); |
| assertFalse("expected '"+t+"' to not be matched " + |
| "by pattern '"+pat, p.matcher(t).matches()); |
| assertTrue("expected '"+t+"' to " + |
| "be matched by pattern '"+npat, pn.matcher(t).matches()); |
| } else { |
| assertTrue("expected '"+t+"' to be matched " + |
| "by pattern '"+pat, p.matcher(t).matches()); |
| assertFalse("expected '"+t+"' to " + |
| "not be matched by pattern '"+npat, pn.matcher(t).matches()); |
| } |
| } |
| } |
| |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies matcher(CharSequence input) method for input specified by Unicode blocks.", |
| method = "matcher", |
| args = {java.lang.CharSequence.class} |
| ) |
| public void testUnicodeBlocks() throws PatternSyntaxException { |
| Pattern p; |
| Matcher m; |
| int i, j; |
| |
| // Test Unicode blocks using \p and \P |
| // FIXME: |
| // Note that LatinExtended-B and ArabicPresentations-B are unrecognized |
| // by the reference JDK. |
| for (i = 0; i < UBlocks.length; i++) { |
| /* |
| * p = Pattern.compile("\\p{"+UBlocks[i].name+"}"); |
| * |
| * if (UBlocks[i].low > 0) { m = |
| * p.matcher(Character.toString((char)(UBlocks[i].low-1))); |
| * assertFalse(m.matches()); } for (j=UBlocks[i].low; j <= |
| * UBlocks[i].high; j++) { m = |
| * p.matcher(Character.toString((char)j)); |
| * assertTrue(m.matches()); } if (UBlocks[i].high < 0xFFFF) { m = |
| * p.matcher(Character.toString((char)(UBlocks[i].high+1))); |
| * assertFalse(m.matches()); } |
| * |
| * p = Pattern.compile("\\P{"+UBlocks[i].name+"}"); |
| * |
| * if (UBlocks[i].low > 0) { m = |
| * p.matcher(Character.toString((char)(UBlocks[i].low-1))); |
| * assertTrue(m.matches()); } for (j=UBlocks[i].low; j < |
| * UBlocks[i].high; j++) { m = |
| * p.matcher(Character.toString((char)j)); |
| * assertFalse(m.matches()); } if (UBlocks[i].high < 0xFFFF) { m = |
| * p.matcher(Character.toString((char)(UBlocks[i].high+1))); |
| * assertTrue(m.matches()); } |
| */ |
| |
| p = Pattern.compile("\\p{In" + UBlocks[i].name + "}"); |
| // BEGIN android-changed |
| // Added the name of the block under test to the assertion to get more output. |
| |
| if (UBlocks[i].low > 0) { |
| m = p.matcher(Character.toString((char) (UBlocks[i].low - 1))); |
| assertFalse(UBlocks[i].name, m.matches()); |
| } |
| for (j = UBlocks[i].low; j <= UBlocks[i].high; j++) { |
| m = p.matcher(Character.toString((char) j)); |
| assertTrue(UBlocks[i].name, m.matches()); |
| } |
| if (UBlocks[i].high < 0xFFFF) { |
| m = p.matcher(Character.toString((char) (UBlocks[i].high + 1))); |
| assertFalse(UBlocks[i].name, m.matches()); |
| } |
| |
| p = Pattern.compile("\\P{In" + UBlocks[i].name + "}"); |
| |
| if (UBlocks[i].low > 0) { |
| m = p.matcher(Character.toString((char) (UBlocks[i].low - 1))); |
| assertTrue(UBlocks[i].name, m.matches()); |
| } |
| for (j = UBlocks[i].low; j < UBlocks[i].high; j++) { |
| m = p.matcher(Character.toString((char) j)); |
| assertFalse(UBlocks[i].name, m.matches()); |
| } |
| if (UBlocks[i].high < 0xFFFF) { |
| m = p.matcher(Character.toString((char) (UBlocks[i].high + 1))); |
| assertTrue(UBlocks[i].name, m.matches()); |
| } |
| |
| // END android-changed |
| } |
| } |
| @TestTargetNew( |
| level = TestLevel.ADDITIONAL, |
| notes = "these tests are still partial, see TODO in the code", |
| method = "!", |
| args = {} |
| ) |
| public void testCapturingGroups() throws PatternSyntaxException { |
| Pattern p; |
| Matcher m; |
| |
| // Test simple capturing groups |
| p = Pattern.compile("(a+)b"); |
| m = p.matcher("aaaaaaaab"); |
| assertTrue(m.matches()); |
| assertEquals(1, m.groupCount()); |
| assertEquals("aaaaaaaa", m.group(1)); |
| |
| p = Pattern.compile("((an)+)((as)+)"); |
| m = p.matcher("ananas"); |
| assertTrue(m.matches()); |
| assertEquals(4, m.groupCount()); |
| assertEquals("ananas", m.group(0)); |
| assertEquals("anan", m.group(1)); |
| assertEquals("an", m.group(2)); |
| assertEquals("as", m.group(3)); |
| assertEquals("as", m.group(4)); |
| |
| // Test grouping without capture (?:...) |
| p = Pattern.compile("(?:(?:an)+)(as)"); |
| m = p.matcher("ananas"); |
| assertTrue(m.matches()); |
| assertEquals(1, m.groupCount()); |
| assertEquals("as", m.group(1)); |
| try { |
| m.group(2); |
| fail("expected IndexOutOfBoundsException"); |
| } catch (IndexOutOfBoundsException ioobe) { |
| // expected |
| } |
| |
| // Test combination of grouping and capture |
| // TODO |
| |
| // Test \<num> sequence with capturing and non-capturing groups |
| // TODO |
| |
| // Test \<num> with <num> out of range |
| p = Pattern.compile("((an)+)as\\1"); |
| m = p.matcher("ananasanan"); |
| assertTrue(m.matches()); |
| |
| try { |
| p = Pattern.compile("((an)+)as\\4"); |
| fail("expected PatternSyntaxException"); |
| } catch (PatternSyntaxException pse) { |
| // expected |
| } |
| |
| } |
| @TestTargetNew( |
| level = TestLevel.ADDITIONAL, |
| notes = "", |
| method = "!", |
| args = {} |
| ) |
| public void testRepeats() { |
| Pattern p; |
| Matcher m; |
| |
| // Test ? |
| p = Pattern.compile("(abc)?c"); |
| m = p.matcher("abcc"); |
| assertTrue(m.matches()); |
| m = p.matcher("c"); |
| assertTrue(m.matches()); |
| m = p.matcher("cc"); |
| assertFalse(m.matches()); |
| m = p.matcher("abcabcc"); |
| assertFalse(m.matches()); |
| |
| // Test * |
| p = Pattern.compile("(abc)*c"); |
| m = p.matcher("abcc"); |
| assertTrue(m.matches()); |
| m = p.matcher("c"); |
| assertTrue(m.matches()); |
| m = p.matcher("cc"); |
| assertFalse(m.matches()); |
| m = p.matcher("abcabcc"); |
| assertTrue(m.matches()); |
| |
| // Test + |
| p = Pattern.compile("(abc)+c"); |
| m = p.matcher("abcc"); |
| assertTrue(m.matches()); |
| m = p.matcher("c"); |
| assertFalse(m.matches()); |
| m = p.matcher("cc"); |
| assertFalse(m.matches()); |
| m = p.matcher("abcabcc"); |
| assertTrue(m.matches()); |
| |
| // Test {<num>}, including 0, 1 and more |
| p = Pattern.compile("(abc){0}c"); |
| m = p.matcher("abcc"); |
| assertFalse(m.matches()); |
| m = p.matcher("c"); |
| assertTrue(m.matches()); |
| |
| p = Pattern.compile("(abc){1}c"); |
| m = p.matcher("abcc"); |
| assertTrue(m.matches()); |
| m = p.matcher("c"); |
| assertFalse(m.matches()); |
| m = p.matcher("abcabcc"); |
| assertFalse(m.matches()); |
| |
| p = Pattern.compile("(abc){2}c"); |
| m = p.matcher("abcc"); |
| assertFalse(m.matches()); |
| m = p.matcher("c"); |
| assertFalse(m.matches()); |
| m = p.matcher("cc"); |
| assertFalse(m.matches()); |
| m = p.matcher("abcabcc"); |
| assertTrue(m.matches()); |
| |
| // Test {<num>,}, including 0, 1 and more |
| // TODO |
| |
| // Test {<n1>,<n2>}, with n1 < n2, n1 = n2 and n1 > n2 (illegal?) |
| // TODO |
| } |
| @TestTargetNew( |
| level = TestLevel.ADDITIONAL, |
| notes = "", |
| method = "!", |
| args = {} |
| ) |
| public void testAnchors() throws PatternSyntaxException { |
| Pattern p; |
| Matcher m; |
| |
| // Test ^, default and MULTILINE |
| p = Pattern.compile("^abc\\n^abc", Pattern.MULTILINE); |
| m = p.matcher("abc\nabc"); |
| assertTrue(m.matches()); |
| |
| p = Pattern.compile("^abc\\n^abc"); |
| m = p.matcher("abc\nabc"); |
| assertFalse(m.matches()); |
| |
| // Test $, default and MULTILINE |
| // TODO |
| |
| // Test \b (word boundary) |
| // TODO |
| |
| // Test \B (not a word boundary) |
| // TODO |
| |
| // Test \A (beginning of string) |
| // TODO |
| |
| // Test \Z (end of string) |
| // TODO |
| |
| // Test \z (end of string) |
| // TODO |
| |
| // Test \G |
| // TODO |
| |
| // Test positive lookahead using (?=...) |
| // TODO |
| |
| // Test negative lookahead using (?!...) |
| // TODO |
| |
| // Test positive lookbehind using (?<=...) |
| // TODO |
| |
| // Test negative lookbehind using (?<!...) |
| // TODO |
| } |
| @TestTargets({ |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies compile(String regex) method and matcher for created pattern.", |
| method = "compile", |
| args = {java.lang.String.class} |
| ), |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies compile(String regex) method and matcher for created pattern.", |
| method = "matcher", |
| args = {java.lang.CharSequence.class} |
| ) |
| }) |
| public void testMisc() throws PatternSyntaxException { |
| Pattern p; |
| Matcher m; |
| |
| // Test (?>...) |
| // TODO |
| |
| // Test (?onflags-offflags) |
| // Valid flags are i,m,d,s,u,x |
| // TODO |
| |
| // Test (?onflags-offflags:...) |
| // TODO |
| |
| // Test \Q, \E |
| p = Pattern.compile("[a-z]+;\\Q[a-z]+;\\Q(foo.*);\\E[0-9]+"); |
| m = p.matcher("abc;[a-z]+;\\Q(foo.*);411"); |
| assertTrue(m.matches()); |
| m = p.matcher("abc;def;foo42;555"); |
| assertFalse(m.matches()); |
| m = p.matcher("abc;\\Qdef;\\Qfoo99;\\E123"); |
| assertFalse(m.matches()); |
| |
| p = Pattern.compile("[a-z]+;(foo[0-9]-\\Q(...)\\E);[0-9]+"); |
| m = p.matcher("abc;foo5-(...);123"); |
| assertTrue(m.matches()); |
| assertEquals("foo5-(...)", m.group(1)); |
| m = p.matcher("abc;foo9-(xxx);789"); |
| assertFalse(m.matches()); |
| |
| p = Pattern.compile("[a-z]+;(bar[0-9]-[a-z\\Q$-\\E]+);[0-9]+"); |
| m = p.matcher("abc;bar0-def$-;123"); |
| assertTrue(m.matches()); |
| |
| // FIXME: |
| // This should work the same as the pattern above but fails with the |
| // the reference JDK |
| p = Pattern.compile("[a-z]+;(bar[0-9]-[a-z\\Q-$\\E]+);[0-9]+"); |
| m = p.matcher("abc;bar0-def$-;123"); |
| // assertTrue(m.matches()); |
| |
| // FIXME: |
| // This should work too .. it looks as if just about anything that |
| // has more |
| // than one character between \Q and \E is broken in the the reference JDK |
| p = Pattern.compile("[a-z]+;(bar[0-9]-[a-z\\Q[0-9]\\E]+);[0-9]+"); |
| m = p.matcher("abc;bar0-def[99]-]0x[;123"); |
| // assertTrue(m.matches()); |
| |
| // This is the same as above but with explicit escapes .. and this |
| // does work |
| // on the the reference JDK |
| p = Pattern.compile("[a-z]+;(bar[0-9]-[a-z\\[0\\-9\\]]+);[0-9]+"); |
| m = p.matcher("abc;bar0-def[99]-]0x[;123"); |
| assertTrue(m.matches()); |
| |
| // Test #<comment text> |
| // TODO |
| } |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies compile(String regex) method.", |
| method = "compile", |
| args = {java.lang.String.class} |
| ) |
| public void testCompile1() throws PatternSyntaxException { |
| Pattern pattern = Pattern |
| .compile("[0-9A-Za-z][0-9A-Za-z\\x2e\\x3a\\x2d\\x5f]*"); |
| String name = "iso-8859-1"; |
| assertTrue(pattern.matcher(name).matches()); |
| } |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies compile(String regex, int flag) method.", |
| method = "compile", |
| args = {java.lang.String.class, int.class} |
| ) |
| public void testCompile2() throws PatternSyntaxException { |
| String findString = "\\Qimport\\E"; |
| |
| Pattern pattern = Pattern.compile(findString, 0); |
| Matcher matcher = pattern.matcher(new String( |
| "import a.A;\n\n import b.B;\nclass C {}")); |
| |
| assertTrue(matcher.find(0)); |
| } |
| @TestTargets({ |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies compile(String regex) and compile(String regex, int flag) method for specific patterns.", |
| method = "compile", |
| args = {java.lang.String.class} |
| ), |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies compile(String regex) and compile(String regex, int flag) method for specific patterns.", |
| method = "compile", |
| args = {java.lang.String.class, int.class} |
| ) |
| }) |
| public void testCompile3() throws PatternSyntaxException { |
| Pattern p; |
| Matcher m; |
| p = Pattern.compile("a$"); |
| m = p.matcher("a\n"); |
| assertTrue(m.find()); |
| assertEquals("a", m.group()); |
| assertFalse(m.find()); |
| |
| p = Pattern.compile("(a$)"); |
| m = p.matcher("a\n"); |
| assertTrue(m.find()); |
| assertEquals("a", m.group()); |
| assertEquals("a", m.group(1)); |
| assertFalse(m.find()); |
| |
| p = Pattern.compile("^.*$", Pattern.MULTILINE); |
| |
| m = p.matcher("a\n"); |
| assertTrue(m.find()); |
| // System.out.println("["+m.group()+"]"); |
| assertEquals("a", m.group()); |
| assertFalse(m.find()); |
| |
| m = p.matcher("a\nb\n"); |
| assertTrue(m.find()); |
| // System.out.println("["+m.group()+"]"); |
| assertEquals("a", m.group()); |
| assertTrue(m.find()); |
| // System.out.println("["+m.group()+"]"); |
| assertEquals("b", m.group()); |
| assertFalse(m.find()); |
| |
| m = p.matcher("a\nb"); |
| assertTrue(m.find()); |
| // System.out.println("["+m.group()+"]"); |
| assertEquals("a", m.group()); |
| assertTrue(m.find()); |
| assertEquals("b", m.group()); |
| assertFalse(m.find()); |
| |
| m = p.matcher("\naa\r\nbb\rcc\n\n"); |
| assertTrue(m.find()); |
| // System.out.println("["+m.group()+"]"); |
| assertTrue(m.group().equals("")); |
| assertTrue(m.find()); |
| // System.out.println("["+m.group()+"]"); |
| assertEquals("aa", m.group()); |
| assertTrue(m.find()); |
| // System.out.println("["+m.group()+"]"); |
| assertEquals("bb", m.group()); |
| assertTrue(m.find()); |
| // System.out.println("["+m.group()+"]"); |
| assertEquals("cc", m.group()); |
| assertTrue(m.find()); |
| // System.out.println("["+m.group()+"]"); |
| assertTrue(m.group().equals("")); |
| assertFalse(m.find()); |
| |
| m = p.matcher("a"); |
| assertTrue(m.find()); |
| assertEquals("a", m.group()); |
| assertFalse(m.find()); |
| |
| // BEGIN android-removed |
| // Makes no sense to duplicate this weird behavior |
| // m = p.matcher(""); |
| // // FIXME: This matches the reference behaviour but is |
| // // inconsistent with matching "a" - ie. the end of the |
| // // target string should match against $ always but this |
| // // appears to work with the null string only when not in |
| // // multiline mode (see below) |
| // assertFalse(m.find()); |
| // END android-removed |
| |
| p = Pattern.compile("^.*$"); |
| m = p.matcher(""); |
| assertTrue(m.find()); |
| assertTrue(m.group().equals("")); |
| assertFalse(m.find()); |
| } |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies compile(String regex, int flag) method for specific string.", |
| method = "compile", |
| args = {java.lang.String.class, int.class} |
| ) |
| public void testCompile4() throws PatternSyntaxException { |
| String findString = "\\Qpublic\\E"; |
| StringBuffer text = new StringBuffer(" public class Class {\n" |
| + " public class Class {"); |
| |
| Pattern pattern = Pattern.compile(findString, 0); |
| Matcher matcher = pattern.matcher(text); |
| |
| boolean found = matcher.find(); |
| assertTrue(found); |
| assertEquals(4, matcher.start()); |
| if (found) { |
| // modify text |
| text.delete(0, text.length()); |
| text.append("Text have been changed."); |
| matcher.reset(text); |
| } |
| |
| found = matcher.find(); |
| assertFalse(found); |
| } |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "Verifies compile(String regex) methodfor specific string.", |
| method = "compile", |
| args = {java.lang.String.class} |
| ) |
| public void testCompile5() throws PatternSyntaxException { |
| Pattern p = Pattern.compile("^[0-9]"); |
| String s[] = p.split("12", -1); |
| assertEquals("", s[0]); |
| assertEquals("2", s[1]); |
| assertEquals(2, s.length); |
| } |
| |
| // public void testCompile6() { |
| // String regex = "[\\p{L}[\\p{Mn}[\\p{Pc}[\\p{Nd}[\\p{Nl}[\\p{Sc}]]]]]]+"; |
| // String regex = "[\\p{L}\\p{Mn}\\p{Pc}\\p{Nd}\\p{Nl}\\p{Sc}]+"; |
| // try { |
| // Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE); |
| // assertTrue(true); |
| // } catch (PatternSyntaxException e) { |
| // System.out.println(e.getMessage()); |
| // assertTrue(false); |
| // } |
| // } |
| |
| private static class UBInfo { |
| public UBInfo(int low, int high, String name) { |
| this.name = name; |
| this.low = low; |
| this.high = high; |
| } |
| |
| public String name; |
| |
| public int low, high; |
| } |
| |
| // A table representing the unicode categories |
| //private static UBInfo[] UCategories = { |
| // Lu |
| // Ll |
| // Lt |
| // Lm |
| // Lo |
| // Mn |
| // Mc |
| // Me |
| // Nd |
| // Nl |
| // No |
| // Pc |
| // Pd |
| // Ps |
| // Pe |
| // Pi |
| // Pf |
| // Po |
| // Sm |
| // Sc |
| // Sk |
| // So |
| // Zs |
| // Zl |
| // Zp |
| // Cc |
| // Cf |
| // Cs |
| // Co |
| // Cn |
| //}; |
| |
| // A table representing the unicode character blocks |
| private static UBInfo[] UBlocks = { |
| /* 0000; 007F; Basic Latin */ |
| new UBInfo(0x0000, 0x007F, "BasicLatin"), // Character.UnicodeBlock.BASIC_LATIN |
| /* 0080; 00FF; Latin-1 Supplement */ |
| new UBInfo(0x0080, 0x00FF, "Latin-1Supplement"), // Character.UnicodeBlock.LATIN_1_SUPPLEMENT |
| /* 0100; 017F; Latin Extended-A */ |
| new UBInfo(0x0100, 0x017F, "LatinExtended-A"), // Character.UnicodeBlock.LATIN_EXTENDED_A |
| /* 0180; 024F; Latin Extended-B */ |
| // new UBInfo (0x0180,0x024F,"InLatinExtended-B"), // |
| // Character.UnicodeBlock.LATIN_EXTENDED_B |
| /* 0250; 02AF; IPA Extensions */ |
| new UBInfo(0x0250, 0x02AF, "IPAExtensions"), // Character.UnicodeBlock.IPA_EXTENSIONS |
| /* 02B0; 02FF; Spacing Modifier Letters */ |
| new UBInfo(0x02B0, 0x02FF, "SpacingModifierLetters"), // Character.UnicodeBlock.SPACING_MODIFIER_LETTERS |
| /* 0300; 036F; Combining Diacritical Marks */ |
| new UBInfo(0x0300, 0x036F, "CombiningDiacriticalMarks"), // Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS |
| /* 0370; 03FF; Greek */ |
| new UBInfo(0x0370, 0x03FF, "Greek"), // Character.UnicodeBlock.GREEK |
| /* 0400; 04FF; Cyrillic */ |
| new UBInfo(0x0400, 0x04FF, "Cyrillic"), // Character.UnicodeBlock.CYRILLIC |
| /* 0530; 058F; Armenian */ |
| new UBInfo(0x0530, 0x058F, "Armenian"), // Character.UnicodeBlock.ARMENIAN |
| /* 0590; 05FF; Hebrew */ |
| new UBInfo(0x0590, 0x05FF, "Hebrew"), // Character.UnicodeBlock.HEBREW |
| /* 0600; 06FF; Arabic */ |
| new UBInfo(0x0600, 0x06FF, "Arabic"), // Character.UnicodeBlock.ARABIC |
| /* 0700; 074F; Syriac */ |
| new UBInfo(0x0700, 0x074F, "Syriac"), // Character.UnicodeBlock.SYRIAC |
| /* 0780; 07BF; Thaana */ |
| new UBInfo(0x0780, 0x07BF, "Thaana"), // Character.UnicodeBlock.THAANA |
| /* 0900; 097F; Devanagari */ |
| new UBInfo(0x0900, 0x097F, "Devanagari"), // Character.UnicodeBlock.DEVANAGARI |
| /* 0980; 09FF; Bengali */ |
| new UBInfo(0x0980, 0x09FF, "Bengali"), // Character.UnicodeBlock.BENGALI |
| /* 0A00; 0A7F; Gurmukhi */ |
| new UBInfo(0x0A00, 0x0A7F, "Gurmukhi"), // Character.UnicodeBlock.GURMUKHI |
| /* 0A80; 0AFF; Gujarati */ |
| new UBInfo(0x0A80, 0x0AFF, "Gujarati"), // Character.UnicodeBlock.GUJARATI |
| /* 0B00; 0B7F; Oriya */ |
| new UBInfo(0x0B00, 0x0B7F, "Oriya"), // Character.UnicodeBlock.ORIYA |
| /* 0B80; 0BFF; Tamil */ |
| new UBInfo(0x0B80, 0x0BFF, "Tamil"), // Character.UnicodeBlock.TAMIL |
| /* 0C00; 0C7F; Telugu */ |
| new UBInfo(0x0C00, 0x0C7F, "Telugu"), // Character.UnicodeBlock.TELUGU |
| /* 0C80; 0CFF; Kannada */ |
| new UBInfo(0x0C80, 0x0CFF, "Kannada"), // Character.UnicodeBlock.KANNADA |
| /* 0D00; 0D7F; Malayalam */ |
| new UBInfo(0x0D00, 0x0D7F, "Malayalam"), // Character.UnicodeBlock.MALAYALAM |
| /* 0D80; 0DFF; Sinhala */ |
| new UBInfo(0x0D80, 0x0DFF, "Sinhala"), // Character.UnicodeBlock.SINHALA |
| /* 0E00; 0E7F; Thai */ |
| new UBInfo(0x0E00, 0x0E7F, "Thai"), // Character.UnicodeBlock.THAI |
| /* 0E80; 0EFF; Lao */ |
| new UBInfo(0x0E80, 0x0EFF, "Lao"), // Character.UnicodeBlock.LAO |
| /* 0F00; 0FFF; Tibetan */ |
| new UBInfo(0x0F00, 0x0FFF, "Tibetan"), // Character.UnicodeBlock.TIBETAN |
| /* 1000; 109F; Myanmar */ |
| new UBInfo(0x1000, 0x109F, "Myanmar"), // Character.UnicodeBlock.MYANMAR |
| /* 10A0; 10FF; Georgian */ |
| new UBInfo(0x10A0, 0x10FF, "Georgian"), // Character.UnicodeBlock.GEORGIAN |
| /* 1100; 11FF; Hangul Jamo */ |
| new UBInfo(0x1100, 0x11FF, "HangulJamo"), // Character.UnicodeBlock.HANGUL_JAMO |
| /* 1200; 137F; Ethiopic */ |
| new UBInfo(0x1200, 0x137F, "Ethiopic"), // Character.UnicodeBlock.ETHIOPIC |
| /* 13A0; 13FF; Cherokee */ |
| new UBInfo(0x13A0, 0x13FF, "Cherokee"), // Character.UnicodeBlock.CHEROKEE |
| /* 1400; 167F; Unified Canadian Aboriginal Syllabics */ |
| new UBInfo(0x1400, 0x167F, "UnifiedCanadianAboriginalSyllabics"), // Character.UnicodeBlock.UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS |
| /* 1680; 169F; Ogham */ |
| new UBInfo(0x1680, 0x169F, "Ogham"), // Character.UnicodeBlock.OGHAM |
| /* 16A0; 16FF; Runic */ |
| new UBInfo(0x16A0, 0x16FF, "Runic"), // Character.UnicodeBlock.RUNIC |
| /* 1780; 17FF; Khmer */ |
| new UBInfo(0x1780, 0x17FF, "Khmer"), // Character.UnicodeBlock.KHMER |
| /* 1800; 18AF; Mongolian */ |
| new UBInfo(0x1800, 0x18AF, "Mongolian"), // Character.UnicodeBlock.MONGOLIAN |
| /* 1E00; 1EFF; Latin Extended Additional */ |
| new UBInfo(0x1E00, 0x1EFF, "LatinExtendedAdditional"), // Character.UnicodeBlock.LATIN_EXTENDED_ADDITIONAL |
| /* 1F00; 1FFF; Greek Extended */ |
| new UBInfo(0x1F00, 0x1FFF, "GreekExtended"), // Character.UnicodeBlock.GREEK_EXTENDED |
| /* 2000; 206F; General Punctuation */ |
| new UBInfo(0x2000, 0x206F, "GeneralPunctuation"), // Character.UnicodeBlock.GENERAL_PUNCTUATION |
| /* 2070; 209F; Superscripts and Subscripts */ |
| new UBInfo(0x2070, 0x209F, "SuperscriptsandSubscripts"), // Character.UnicodeBlock.SUPERSCRIPTS_AND_SUBSCRIPTS |
| /* 20A0; 20CF; Currency Symbols */ |
| new UBInfo(0x20A0, 0x20CF, "CurrencySymbols"), // Character.UnicodeBlock.CURRENCY_SYMBOLS |
| /* 20D0; 20FF; Combining Marks for Symbols */ |
| new UBInfo(0x20D0, 0x20FF, "CombiningMarksforSymbols"), // Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS |
| /* 2100; 214F; Letterlike Symbols */ |
| new UBInfo(0x2100, 0x214F, "LetterlikeSymbols"), // Character.UnicodeBlock.LETTERLIKE_SYMBOLS |
| /* 2150; 218F; Number Forms */ |
| new UBInfo(0x2150, 0x218F, "NumberForms"), // Character.UnicodeBlock.NUMBER_FORMS |
| /* 2190; 21FF; Arrows */ |
| new UBInfo(0x2190, 0x21FF, "Arrows"), // Character.UnicodeBlock.ARROWS |
| /* 2200; 22FF; Mathematical Operators */ |
| new UBInfo(0x2200, 0x22FF, "MathematicalOperators"), // Character.UnicodeBlock.MATHEMATICAL_OPERATORS |
| /* 2300; 23FF; Miscellaneous Technical */ |
| new UBInfo(0x2300, 0x23FF, "MiscellaneousTechnical"), // Character.UnicodeBlock.MISCELLANEOUS_TECHNICAL |
| /* 2400; 243F; Control Pictures */ |
| new UBInfo(0x2400, 0x243F, "ControlPictures"), // Character.UnicodeBlock.CONTROL_PICTURES |
| /* 2440; 245F; Optical Character Recognition */ |
| new UBInfo(0x2440, 0x245F, "OpticalCharacterRecognition"), // Character.UnicodeBlock.OPTICAL_CHARACTER_RECOGNITION |
| /* 2460; 24FF; Enclosed Alphanumerics */ |
| new UBInfo(0x2460, 0x24FF, "EnclosedAlphanumerics"), // Character.UnicodeBlock.ENCLOSED_ALPHANUMERICS |
| /* 2500; 257F; Box Drawing */ |
| new UBInfo(0x2500, 0x257F, "BoxDrawing"), // Character.UnicodeBlock.BOX_DRAWING |
| /* 2580; 259F; Block Elements */ |
| new UBInfo(0x2580, 0x259F, "BlockElements"), // Character.UnicodeBlock.BLOCK_ELEMENTS |
| /* 25A0; 25FF; Geometric Shapes */ |
| new UBInfo(0x25A0, 0x25FF, "GeometricShapes"), // Character.UnicodeBlock.GEOMETRIC_SHAPES |
| /* 2600; 26FF; Miscellaneous Symbols */ |
| new UBInfo(0x2600, 0x26FF, "MiscellaneousSymbols"), // Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS |
| /* 2700; 27BF; Dingbats */ |
| new UBInfo(0x2700, 0x27BF, "Dingbats"), // Character.UnicodeBlock.DINGBATS |
| /* 2800; 28FF; Braille Patterns */ |
| new UBInfo(0x2800, 0x28FF, "BraillePatterns"), // Character.UnicodeBlock.BRAILLE_PATTERNS |
| /* 2E80; 2EFF; CJK Radicals Supplement */ |
| new UBInfo(0x2E80, 0x2EFF, "CJKRadicalsSupplement"), // Character.UnicodeBlock.CJK_RADICALS_SUPPLEMENT |
| /* 2F00; 2FDF; Kangxi Radicals */ |
| new UBInfo(0x2F00, 0x2FDF, "KangxiRadicals"), // Character.UnicodeBlock.KANGXI_RADICALS |
| /* 2FF0; 2FFF; Ideographic Description Characters */ |
| new UBInfo(0x2FF0, 0x2FFF, "IdeographicDescriptionCharacters"), // Character.UnicodeBlock.IDEOGRAPHIC_DESCRIPTION_CHARACTERS |
| /* 3000; 303F; CJK Symbols and Punctuation */ |
| new UBInfo(0x3000, 0x303F, "CJKSymbolsandPunctuation"), // Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION |
| /* 3040; 309F; Hiragana */ |
| new UBInfo(0x3040, 0x309F, "Hiragana"), // Character.UnicodeBlock.HIRAGANA |
| /* 30A0; 30FF; Katakana */ |
| new UBInfo(0x30A0, 0x30FF, "Katakana"), // Character.UnicodeBlock.KATAKANA |
| /* 3100; 312F; Bopomofo */ |
| new UBInfo(0x3100, 0x312F, "Bopomofo"), // Character.UnicodeBlock.BOPOMOFO |
| /* 3130; 318F; Hangul Compatibility Jamo */ |
| new UBInfo(0x3130, 0x318F, "HangulCompatibilityJamo"), // Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO |
| /* 3190; 319F; Kanbun */ |
| new UBInfo(0x3190, 0x319F, "Kanbun"), // Character.UnicodeBlock.KANBUN |
| /* 31A0; 31BF; Bopomofo Extended */ |
| new UBInfo(0x31A0, 0x31BF, "BopomofoExtended"), // Character.UnicodeBlock.BOPOMOFO_EXTENDED |
| /* 3200; 32FF; Enclosed CJK Letters and Months */ |
| new UBInfo(0x3200, 0x32FF, "EnclosedCJKLettersandMonths"), // Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS |
| /* 3300; 33FF; CJK Compatibility */ |
| new UBInfo(0x3300, 0x33FF, "CJKCompatibility"), // Character.UnicodeBlock.CJK_COMPATIBILITY |
| /* 3400; 4DB5; CJK Unified Ideographs Extension A */ |
| // BEGIN android-changed |
| // Modified this to reflect current Unicode tables (or maybe it was a typo) |
| new UBInfo(0x3400, 0x4DBF, "CJKUnifiedIdeographsExtensionA"), // Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A |
| // END android-changed |
| /* 4E00; 9FFF; CJK Unified Ideographs */ |
| new UBInfo(0x4E00, 0x9FFF, "CJKUnifiedIdeographs"), // Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS |
| /* A000; A48F; Yi Syllables */ |
| new UBInfo(0xA000, 0xA48F, "YiSyllables"), // Character.UnicodeBlock.YI_SYLLABLES |
| /* A490; A4CF; Yi Radicals */ |
| new UBInfo(0xA490, 0xA4CF, "YiRadicals"), // Character.UnicodeBlock.YI_RADICALS |
| /* AC00; D7A3; Hangul Syllables */ |
| // BEGIN android-changed |
| // Modified this to reflect current Unicode tables (or maybe it was a typo) |
| new UBInfo(0xAC00, 0xD7AF, "HangulSyllables"), // Character.UnicodeBlock.HANGUL_SYLLABLES |
| // END android-changed |
| /* D800; DB7F; High Surrogates */ |
| /* DB80; DBFF; High Private Use Surrogates */ |
| /* DC00; DFFF; Low Surrogates */ |
| /* E000; F8FF; Private Use */ |
| /* F900; FAFF; CJK Compatibility Ideographs */ |
| new UBInfo(0xF900, 0xFAFF, "CJKCompatibilityIdeographs"), // Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS |
| /* FB00; FB4F; Alphabetic Presentation Forms */ |
| new UBInfo(0xFB00, 0xFB4F, "AlphabeticPresentationForms"), // Character.UnicodeBlock.ALPHABETIC_PRESENTATION_FORMS |
| /* FB50; FDFF; Arabic Presentation Forms-A */ |
| new UBInfo(0xFB50, 0xFDFF, "ArabicPresentationForms-A"), // Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_A |
| /* FE20; FE2F; Combining Half Marks */ |
| new UBInfo(0xFE20, 0xFE2F, "CombiningHalfMarks"), // Character.UnicodeBlock.COMBINING_HALF_MARKS |
| /* FE30; FE4F; CJK Compatibility Forms */ |
| new UBInfo(0xFE30, 0xFE4F, "CJKCompatibilityForms"), // Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS |
| /* FE50; FE6F; Small Form Variants */ |
| new UBInfo(0xFE50, 0xFE6F, "SmallFormVariants"), // Character.UnicodeBlock.SMALL_FORM_VARIANTS |
| /* FE70; FEFE; Arabic Presentation Forms-B */ |
| // new UBInfo (0xFE70,0xFEFE,"InArabicPresentationForms-B"), // |
| // Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_B |
| /* FEFF; FEFF; Specials */ |
| // BEGIN android-changed |
| // Modified this to reflect current Unicode tables (or maybe it was a typo) |
| // FEFF is actually still Arabic Presentation Forms B |
| // new UBInfo(0xFEFF, 0xFEFF, "Specials"), // Character.UnicodeBlock.SPECIALS |
| // END android-changed |
| /* FF00; FFEF; Halfwidth and Fullwidth Forms */ |
| new UBInfo(0xFF00, 0xFFEF, "HalfwidthandFullwidthForms"), // Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS |
| /* FFF0; FFFD; Specials */ |
| // BEGIN android-changed |
| // Modified this to reflect current Unicode tables (or maybe it was a typo) |
| new UBInfo(0xFFF0, 0xFFFF, "Specials") // Character.UnicodeBlock.SPECIALS |
| // END android-changed |
| }; |
| } |