src/java.base/share/classes/java/util/regex/Pattern.java
changeset 48853 84b4ffbba8b0
parent 48491 7f11a1699ef6
child 49554 f088ec60bed5
equal deleted inserted replaced
48852:478e198da84b 48853:84b4ffbba8b0
   780     /**
   780     /**
   781      * Regular expression modifier values.  Instead of being passed as
   781      * Regular expression modifier values.  Instead of being passed as
   782      * arguments, they can also be passed as inline modifiers.
   782      * arguments, they can also be passed as inline modifiers.
   783      * For example, the following statements have the same effect.
   783      * For example, the following statements have the same effect.
   784      * <pre>
   784      * <pre>
   785      * RegExp r1 = RegExp.compile("abc", Pattern.I|Pattern.M);
   785      * Pattern p1 = Pattern.compile("abc", Pattern.CASE_INSENSITIVE|Pattern.MULTILINE);
   786      * RegExp r2 = RegExp.compile("(?im)abc", 0);
   786      * Pattern p2 = Pattern.compile("(?im)abc", 0);
   787      * </pre>
   787      * </pre>
   788      *
       
   789      * The flags are duplicated so that the familiar Perl match flag
       
   790      * names are available.
       
   791      */
   788      */
   792 
   789 
   793     /**
   790     /**
   794      * Enables Unix lines mode.
   791      * Enables Unix lines mode.
   795      *
   792      *
  2525                 break;
  2522                 break;
  2526             if (read() != '<')
  2523             if (read() != '<')
  2527                 throw error("\\k is not followed by '<' for named capturing group");
  2524                 throw error("\\k is not followed by '<' for named capturing group");
  2528             String name = groupname(read());
  2525             String name = groupname(read());
  2529             if (!namedGroups().containsKey(name))
  2526             if (!namedGroups().containsKey(name))
  2530                 throw error("(named capturing group <"+ name+"> does not exit");
  2527                 throw error("named capturing group <" + name + "> does not exist");
  2531             if (create) {
  2528             if (create) {
  2532                 hasGroupRef = true;
  2529                 hasGroupRef = true;
  2533                 if (has(CASE_INSENSITIVE))
  2530                 if (has(CASE_INSENSITIVE))
  2534                     root = new CIBackRef(namedGroups().get(name), has(UNICODE_CASE));
  2531                     root = new CIBackRef(namedGroups().get(name), has(UNICODE_CASE));
  2535                 else
  2532                 else
  2920      * Parses and returns the name of a "named capturing group", the trailing
  2917      * Parses and returns the name of a "named capturing group", the trailing
  2921      * ">" is consumed after parsing.
  2918      * ">" is consumed after parsing.
  2922      */
  2919      */
  2923     private String groupname(int ch) {
  2920     private String groupname(int ch) {
  2924         StringBuilder sb = new StringBuilder();
  2921         StringBuilder sb = new StringBuilder();
  2925         sb.append(Character.toChars(ch));
  2922         if (!ASCII.isAlpha(ch))
  2926         while (ASCII.isLower(ch=read()) || ASCII.isUpper(ch) ||
  2923             throw error("capturing group name does not start with a Latin letter");
  2927                ASCII.isDigit(ch)) {
  2924         do {
  2928             sb.append(Character.toChars(ch));
  2925             sb.append((char) ch);
  2929         }
  2926         } while (ASCII.isAlnum(ch=read()));
  2930         if (sb.length() == 0)
       
  2931             throw error("named capturing group has 0 length name");
       
  2932         if (ch != '>')
  2927         if (ch != '>')
  2933             throw error("named capturing group is missing trailing '>'");
  2928             throw error("named capturing group is missing trailing '>'");
  2934         return sb.toString();
  2929         return sb.toString();
  2935     }
  2930     }
  2936 
  2931 
  2972                 head.next = expr(tail);
  2967                 head.next = expr(tail);
  2973                 head = tail = new Ques(head, Qtype.INDEPENDENT);
  2968                 head = tail = new Ques(head, Qtype.INDEPENDENT);
  2974                 break;
  2969                 break;
  2975             case '<':   // (?<xxx)  look behind
  2970             case '<':   // (?<xxx)  look behind
  2976                 ch = read();
  2971                 ch = read();
  2977                 if (ASCII.isLower(ch) || ASCII.isUpper(ch)) {
  2972                 if (ch != '=' && ch != '!') {
  2978                     // named captured group
  2973                     // named captured group
  2979                     String name = groupname(ch);
  2974                     String name = groupname(ch);
  2980                     if (namedGroups().containsKey(name))
  2975                     if (namedGroups().containsKey(name))
  2981                         throw error("Named capturing group <" + name
  2976                         throw error("Named capturing group <" + name
  2982                                     + "> is already defined");
  2977                                     + "> is already defined");
  3003                     head = tail = (hasSupplementary ?
  2998                     head = tail = (hasSupplementary ?
  3004                                    new BehindS(head, info.maxLength,
  2999                                    new BehindS(head, info.maxLength,
  3005                                                info.minLength) :
  3000                                                info.minLength) :
  3006                                    new Behind(head, info.maxLength,
  3001                                    new Behind(head, info.maxLength,
  3007                                               info.minLength));
  3002                                               info.minLength));
  3008                 } else if (ch == '!') {
  3003                 } else { // if (ch == '!')
  3009                     head = tail = (hasSupplementary ?
  3004                     head = tail = (hasSupplementary ?
  3010                                    new NotBehindS(head, info.maxLength,
  3005                                    new NotBehindS(head, info.maxLength,
  3011                                                   info.minLength) :
  3006                                                   info.minLength) :
  3012                                    new NotBehind(head, info.maxLength,
  3007                                    new NotBehind(head, info.maxLength,
  3013                                                  info.minLength));
  3008                                                  info.minLength));
  3014                 } else {
       
  3015                     throw error("Unknown look-behind group");
       
  3016                 }
  3009                 }
  3017                 // clear all top-closure-nodes inside lookbehind
  3010                 // clear all top-closure-nodes inside lookbehind
  3018                 if (saveTCNCount < topClosureNodes.size())
  3011                 if (saveTCNCount < topClosureNodes.size())
  3019                     topClosureNodes.subList(saveTCNCount, topClosureNodes.size()).clear();
  3012                     topClosureNodes.subList(saveTCNCount, topClosureNodes.size()).clear();
  3020                 break;
  3013                 break;