2 // BackReferenceConstruct.jvm.cs
5 // Arina Itkes <arinai@mainsoft.com>
7 // Copyright (C) 2007 Mainsoft, Inc.
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.Collections.Generic;
35 using java.util.regex;
38 namespace System.Text.RegularExpressions
40 sealed class BackReferenceConstruct : IConstructType
42 private const string NUMBER_BACK_REFERENCE_PATTERN = @"(?<=(?:[^\\]|\A)(?:[\\]{2}){0,1073741823})\\(\d+)";
43 private const string NAME_1_BACK_REFERENCE_PATTERN = @"(?<=(?:[^\\]|\A)(?:[\\]{2}){0,1073741823})\\k<(\w+)>";
44 private const string NAME_2_BACK_REFERENCE_PATTERN = @"(?<=(?:[^\\]|\A)(?:[\\]{2}){0,1073741823})\\k'(\w+)'";
45 private const string NUMBER = @"\d+";
48 public bool HasConstruct (string pattern, RegexOptions options) {
49 if (JavaUtils.IsMatch (pattern, NUMBER_BACK_REFERENCE_PATTERN)) {
53 if (JavaUtils.IsMatch (pattern, NAME_1_BACK_REFERENCE_PATTERN)) {
57 return JavaUtils.IsMatch (pattern, NAME_2_BACK_REFERENCE_PATTERN);
60 public string Reformat (RegexOptions options,
61 string reformattedPattern,
62 PatternGrouping patternGrouping) {
63 if (!HasConstruct (reformattedPattern, options)) {
64 return reformattedPattern;
67 if (patternGrouping.GroupCount >= 0 && patternGrouping.SameGroupsFlag) {
71 Matcher m = JavaUtils.Matcher (reformattedPattern, NUMBER_BACK_REFERENCE_PATTERN);
73 reformattedPattern = ReplaceGroupNumber (m, reformattedPattern, patternGrouping, options);
74 if (reformattedPattern == null)
78 m = JavaUtils.Matcher(reformattedPattern, NAME_1_BACK_REFERENCE_PATTERN);
80 reformattedPattern = ReplaceGroupName (m, reformattedPattern, patternGrouping, options);
81 if (reformattedPattern == null)
85 m = JavaUtils.Matcher(reformattedPattern, NAME_2_BACK_REFERENCE_PATTERN);
87 reformattedPattern = ReplaceGroupName (m, reformattedPattern, patternGrouping, options);
88 if (reformattedPattern == null)
92 return reformattedPattern;
95 private string ReplaceGroupNumber (Matcher match,
96 string reformattedPattern,
97 PatternGrouping patternGrouping,
98 RegexOptions options) {
99 int groupNumber = int.Parse (match.group (1));
100 int javaGroupNumber = groupNumber;
101 int groupCount = patternGrouping.GroupCount;
103 if (groupCount == -1) {
104 if ((options & RegexOptions.ExplicitCapture) == RegexOptions.ExplicitCapture) {
108 groupCount = JavaUtils.GroupCount (reformattedPattern);
112 javaGroupNumber = patternGrouping.NetToJavaNumbersMap [groupNumber];
115 if (groupNumber > groupCount) {
119 return match.replaceFirst (@"\\" + javaGroupNumber);
122 private string ReplaceGroupName (Matcher match,
123 string reformattedPattern,
124 PatternGrouping patternGrouping,
125 RegexOptions options) {
127 if (patternGrouping.GroupCount == -1){
131 string groupName = match.group (1);
132 Pattern p = Pattern.compile (NUMBER);
133 Matcher m = p.matcher ((CharSequence) (object) groupName);
135 return ReplaceGroupNumber (match, reformattedPattern, patternGrouping, options);
138 if (!patternGrouping.GroupNameToNumberMap.Contains (groupName)) {
142 int javaGroupNumber = patternGrouping.NetToJavaNumbersMap [(int) patternGrouping.GroupNameToNumberMap [groupName]];
143 return match.replaceFirst (@"\\" + javaGroupNumber);