Java Code Examples for java.util.regex.MatchResult#groupCount()

The following examples show how to use java.util.regex.MatchResult#groupCount() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: BatchRequestParser.java    From cloud-odata-java with Apache License 2.0 6 votes vote down vote up
private String getBoundary(final String contentType) throws BatchException {
  Scanner contentTypeScanner = new Scanner(contentType).useDelimiter(";\\s?");
  if (contentTypeScanner.hasNext(REG_EX_CONTENT_TYPE)) {
    contentTypeScanner.next(REG_EX_CONTENT_TYPE);
  } else {
    contentTypeScanner.close();
    throw new BatchException(BatchException.INVALID_CONTENT_TYPE.addContent(HttpContentType.MULTIPART_MIXED));
  }
  if (contentTypeScanner.hasNext(REG_EX_BOUNDARY_PARAMETER)) {
    contentTypeScanner.next(REG_EX_BOUNDARY_PARAMETER);
    MatchResult result = contentTypeScanner.match();
    contentTypeScanner.close();
    if (result.groupCount() == 1 && result.group(1).trim().matches(REG_EX_BOUNDARY)) {
      return trimQuota(result.group(1).trim());
    } else {
      throw new BatchException(BatchException.INVALID_BOUNDARY);
    }
  } else {
    contentTypeScanner.close();
    throw new BatchException(BatchException.MISSING_PARAMETER_IN_CONTENT_TYPE);
  }
}
 
Example 2
Source File: BatchResponseParser.java    From cloud-odata-java with Apache License 2.0 6 votes vote down vote up
private Map<String, String> parseMimeHeaders(final Scanner scanner) throws BatchException {
  Map<String, String> headers = new HashMap<String, String>();
  while (scanner.hasNext() && !(scanner.hasNext(REG_EX_BLANK_LINE))) {
    if (scanner.hasNext(REG_EX_HEADER)) {
      scanner.next(REG_EX_HEADER);
      currentLineNumber++;
      MatchResult result = scanner.match();
      if (result.groupCount() == 2) {
        String headerName = result.group(1).trim().toLowerCase(Locale.ENGLISH);
        String headerValue = result.group(2).trim();
        headers.put(headerName, headerValue);
      }
    } else {
      throw new BatchException(BatchException.INVALID_HEADER.addContent(scanner.next()));
    }
  }
  return headers;
}
 
Example 3
Source File: DownloadFileInfo.java    From springreplugin with Apache License 2.0 6 votes vote down vote up
/**
 * 根据文件名得到插件名
 *
 * @param fullname
 * @param type
 * @return
 */
public static final String parseName(String fullname, int type) {
    Matcher m = null;
    if (type == INCREMENT_PLUGIN) {
        m = INCREMENT_REGEX.matcher(fullname);
    } else if (type == SINGLE_PLUGIN) {
        m = INCREMENT_SINGLE_REGEX.matcher(fullname);
    } else if (type == MULTI_PLUGIN) {
        m = MULTI_REGEX.matcher(fullname);
    } else {
        m = NORMAL_REGEX.matcher(fullname);
    }
    if (m == null || !m.matches()) {
        return null;
    }
    MatchResult r = m.toMatchResult();
    if (r == null || r.groupCount() != 1) {
        return null;
    }
    return r.group(1);
}
 
Example 4
Source File: BatchResponseParser.java    From cloud-odata-java with Apache License 2.0 6 votes vote down vote up
private Map<String, String> parseResponseHeaders(final Scanner scanner) throws BatchException {
  Map<String, String> headers = new HashMap<String, String>();
  while (scanner.hasNext() && !scanner.hasNext(REG_EX_BLANK_LINE)) {
    if (scanner.hasNext(REG_EX_HEADER)) {
      scanner.next(REG_EX_HEADER);
      currentLineNumber++;
      MatchResult result = scanner.match();
      if (result.groupCount() == 2) {
        String headerName = result.group(1).trim();
        String headerValue = result.group(2).trim();
        if (BatchHelper.HTTP_CONTENT_ID.equalsIgnoreCase(headerName)) {
          if (currentContentId == null) {
            currentContentId = headerValue;
          }
        } else {
          headers.put(headerName, headerValue);
        }
      }
    } else {
      currentLineNumber++;
      throw new BatchException(BatchException.INVALID_HEADER.addContent(scanner.next()).addContent(currentLineNumber));
    }
  }
  return headers;
}
 
Example 5
Source File: FindAddress.java    From android_9.0.0_r45 with Apache License 2.0 5 votes vote down vote up
/**
 * Test whether zipCode matches the U.S. zip code format (ddddd or
 * ddddd-dddd) and is within the expected range, given that
 * stateMatch is a match of sStateRe.
 *
 * @return true if zipCode is a valid zip code, is legal for the
 * matched state, and is followed by a word delimiter or the end
 * of the string.
 */
private static boolean isValidZipCode(String zipCode, MatchResult stateMatch) {
    if (stateMatch == null) return false;
    // Work out the index of the state, based on which group matched.
    int stateIndex = stateMatch.groupCount();
    while (stateIndex > 0) {
        if (stateMatch.group(stateIndex--) != null) break;
    }
    return sZipCodeRe.matcher(zipCode).matches()
            && sStateZipCodeRanges[stateIndex].matches(zipCode);
}
 
Example 6
Source File: SystemUtils.java    From 30-android-libraries-in-30-days with Apache License 2.0 5 votes vote down vote up
/**
 * @return in kiloBytes.
 * @throws SystemUtilsException
 */
public static int getMemoryTotal() throws SystemUtilsException {
	final MatchResult matchResult = SystemUtils.matchSystemFile("/proc/meminfo", SystemUtils.MEMTOTAL_PATTERN, 1000);

	try {
		if(matchResult.groupCount() > 0) {
			return Integer.parseInt(matchResult.group(1));
		} else {
			throw new SystemUtilsException();
		}
	} catch (final NumberFormatException e) {
		throw new SystemUtilsException(e);
	}
}
 
Example 7
Source File: BatchResponseParser.java    From cloud-odata-java with Apache License 2.0 5 votes vote down vote up
private BatchSingleResponseImpl parseResponse(final Scanner scanner, final boolean isChangeSet) throws BatchException {
  BatchSingleResponseImpl response = new BatchSingleResponseImpl();
  if (scanner.hasNext(REG_EX_STATUS_LINE)) {
    scanner.next(REG_EX_STATUS_LINE);
    currentLineNumber++;
    final String statusCode;
    final String statusInfo;
    MatchResult result = scanner.match();
    if (result.groupCount() == 2) {
      statusCode = result.group(1);
      statusInfo = result.group(2);
    } else {
      currentLineNumber++;
      throw new BatchException(BatchException.INVALID_STATUS_LINE.addContent(scanner.next()).addContent(currentLineNumber));
    }

    Map<String, String> headers = parseResponseHeaders(scanner);
    parseNewLine(scanner);
    String contentLengthHeader = getHeaderValue(headers, HttpHeaders.CONTENT_LENGTH);
    String body = (contentLengthHeader != null) ? parseBody(scanner, Integer.parseInt(contentLengthHeader)) : parseBody(scanner);
    response.setStatusCode(statusCode);
    response.setStatusInfo(statusInfo);
    response.setHeaders(headers);
    response.setContentId(currentContentId);
    response.setBody(body);
  } else {
    currentLineNumber++;
    throw new BatchException(BatchException.INVALID_STATUS_LINE.addContent(scanner.next()).addContent(currentLineNumber));
  }
  return response;
}
 
Example 8
Source File: BatchRequestParser.java    From cloud-odata-java with Apache License 2.0 5 votes vote down vote up
private Map<String, String> parseQueryParameters(final String uri) throws BatchException {
  Scanner uriScanner = new Scanner(uri).useDelimiter("\n");
  Map<String, String> queryParametersMap = new HashMap<String, String>();
  Pattern regex = Pattern.compile("(?:" + baseUri + "/)?" + "[^?]+" + "\\?(.*)");
  if (uriScanner.hasNext(regex)) {
    uriScanner.next(regex);
    MatchResult uriResult = uriScanner.match();
    if (uriResult.groupCount() == 1) {
      String queryParams = uriResult.group(1);
      Scanner queryParamsScanner = new Scanner(queryParams).useDelimiter("&");
      while (queryParamsScanner.hasNext(REG_EX_QUERY_PARAMETER)) {
        queryParamsScanner.next(REG_EX_QUERY_PARAMETER);
        MatchResult result = queryParamsScanner.match();
        if (result.groupCount() == 2) {
          String systemQueryOption = result.group(1);
          String value = result.group(2);
          queryParametersMap.put(systemQueryOption, Decoder.decode(value));
        } else {
          queryParamsScanner.close();
          throw new BatchException(BatchException.INVALID_QUERY_PARAMETER);
        }
      }
      queryParamsScanner.close();

    } else {
      uriScanner.close();
      throw new BatchException(BatchException.INVALID_URI.addContent(currentLineNumber));
    }
  }
  uriScanner.close();
  return queryParametersMap;
}
 
Example 9
Source File: SystemUtils.java    From tilt-game-android with MIT License 5 votes vote down vote up
/**
 * @return in kiloBytes.
 * @throws SystemUtilsException
 */
public static long getSystemMemoryFreeSize() throws SystemUtilsException {
	final MatchResult matchResult = SystemUtils.matchSystemFile("/proc/meminfo", SystemUtils.MEMFREE_PATTERN, 1000);

	try {
		if (matchResult.groupCount() > 0) {
			return Long.parseLong(matchResult.group(1));
		} else {
			throw new SystemUtilsException();
		}
	} catch (final NumberFormatException e) {
		throw new SystemUtilsException(e);
	}
}
 
Example 10
Source File: VersionProvider.java    From datasync with MIT License 5 votes vote down vote up
public static String stripVersion(String text) {
    Scanner scanner = new Scanner(text);
    String versionNums = scanner.findWithinHorizon("(\\d+)(\\.\\d+)(\\.\\d+)?", 0);
    String version = "";
    if (versionNums != null) {
        MatchResult groups = scanner.match();
        for (int i = 1; i <= groups.groupCount() && groups.group(i) != null; i++) // yes, truly 1-indexed
            version += groups.group(i);
    }
    return version;
}
 
Example 11
Source File: SystemUtils.java    From tilt-game-android with MIT License 5 votes vote down vote up
public static float getCPUBogoMips() throws SystemUtilsException {
	final MatchResult matchResult = SystemUtils.matchSystemFile("/proc/cpuinfo", SystemUtils.BOGOMIPS_PATTERN, 1000);

	try {
		if (matchResult.groupCount() > 0) {
			return Float.parseFloat(matchResult.group(1));
		} else {
			throw new SystemUtilsException();
		}
	} catch (final NumberFormatException e) {
		throw new SystemUtilsException(e);
	}
}
 
Example 12
Source File: PluginInfo.java    From springreplugin with Apache License 2.0 5 votes vote down vote up
public static final PluginInfo build(File f) {
    Matcher m = REGEX.matcher(f.getName());
    if (m == null || !m.matches()) {
        if (LOG) {
            LogDebug.d(PLUGIN_TAG, "PluginInfo.build: skip, no match1, file=" + f.getAbsolutePath());
        }
        return null;
    }
    MatchResult r = m.toMatchResult();
    if (r == null || r.groupCount() != 4) {
        if (LOG) {
            LogDebug.d(PLUGIN_TAG, "PluginInfo.build: skip, no match2, file=" + f.getAbsolutePath());
        }
        return null;
    }
    String name = r.group(1);
    int low = Integer.parseInt(r.group(2));
    int high = Integer.parseInt(r.group(3));
    int ver = Integer.parseInt(r.group(4));
    String path = f.getPath();
    PluginInfo info = new PluginInfo(name, low, high, ver, TYPE_PN_INSTALLED, DownloadFileInfo.NONE_PLUGIN, path, -1, -1, -1, null);
    if (LOG) {
        LogDebug.d(PLUGIN_TAG, "PluginInfo.build: found plugin, name=" + info.getName()
                + " low=" + info.getLowInterfaceApi() + " high=" + info.getHighInterfaceApi()
                + " ver=" + info.getVersion());
    }
    return info;
}
 
Example 13
Source File: ReferenceSequenceFromSeekable.java    From cramtools with Apache License 2.0 5 votes vote down vote up
private static Map<String, FastaSequenceIndexEntry> buildIndex(InputStream is) {
	Scanner scanner = new Scanner(is);

	int sequenceIndex = 0;
	Map<String, FastaSequenceIndexEntry> index = new HashMap<String, FastaSequenceIndexEntry>();
	while (scanner.hasNext()) {
		// Tokenize and validate the index line.
		String result = scanner.findInLine("(.+)\\t+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)");
		if (result == null)
			throw new RuntimeException("Found invalid line in index file:" + scanner.nextLine());
		MatchResult tokens = scanner.match();
		if (tokens.groupCount() != 5)
			throw new RuntimeException("Found invalid line in index file:" + scanner.nextLine());

		// Skip past the line separator
		scanner.nextLine();

		// Parse the index line.
		String contig = tokens.group(1);
		long size = Long.valueOf(tokens.group(2));
		long location = Long.valueOf(tokens.group(3));
		int basesPerLine = Integer.valueOf(tokens.group(4));
		int bytesPerLine = Integer.valueOf(tokens.group(5));

		contig = SAMSequenceRecord.truncateSequenceName(contig);
		// Build sequence structure
		index.put(contig, new FastaSequenceIndexEntry(contig, location, size, basesPerLine, bytesPerLine,
				sequenceIndex++));
	}
	scanner.close();
	return index;
}
 
Example 14
Source File: JGoogleAnalyticsTracker.java    From ForgeWurst with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Define the proxy to use for all GA tracking requests.
 * <p>
 * Call this static method early (before creating any tracking requests).
 *
 * @param proxyAddr
 *            "addr:port" of the proxy to use; may also be given as URL
 *            ("http://addr:port/").
 */
public static void setProxy(String proxyAddr)
{
	if(proxyAddr != null)
	{
		
		// Split into "proxyAddr:proxyPort".
		proxyAddr = null;
		int proxyPort = 8080;
		try(Scanner s = new Scanner(proxyAddr))
		{
			s.findInLine("(http://|)([^:/]+)(:|)([0-9]*)(/|)");
			MatchResult m = s.match();
			
			if(m.groupCount() >= 2)
				proxyAddr = m.group(2);
			
			if(m.groupCount() >= 4 && !(m.group(4).length() == 0))
				proxyPort = Integer.parseInt(m.group(4));
		}
		
		if(proxyAddr != null)
		{
			SocketAddress sa = new InetSocketAddress(proxyAddr, proxyPort);
			setProxy(new Proxy(Type.HTTP, sa));
		}
	}
}
 
Example 15
Source File: JGoogleAnalyticsTracker.java    From Wurst7 with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Define the proxy to use for all GA tracking requests.
 * <p>
 * Call this static method early (before creating any tracking requests).
 *
 * @param proxyAddr
 *            "addr:port" of the proxy to use; may also be given as URL
 *            ("http://addr:port/").
 */
public static void setProxy(String proxyAddr)
{
	if(proxyAddr != null)
	{
		// Split into "proxyAddr:proxyPort".
		proxyAddr = null;
		int proxyPort = 8080;
		try(Scanner s = new Scanner(proxyAddr))
		{
			s.findInLine("(http://|)([^:/]+)(:|)([0-9]*)(/|)");
			MatchResult m = s.match();
			
			if(m.groupCount() >= 2)
				proxyAddr = m.group(2);
			
			if(m.groupCount() >= 4 && !(m.group(4).length() == 0))
				proxyPort = Integer.parseInt(m.group(4));
		}
		
		if(proxyAddr != null)
		{
			SocketAddress sa = new InetSocketAddress(proxyAddr, proxyPort);
			setProxy(new Proxy(Type.HTTP, sa));
		}
	}
}
 
Example 16
Source File: BatchRequestParser.java    From cloud-odata-java with Apache License 2.0 4 votes vote down vote up
private ODataRequest parseRequest(final Scanner scanner, final boolean isChangeSet) throws BatchException {
  if (scanner.hasNext(REG_EX_REQUEST_LINE)) {
    scanner.next(REG_EX_REQUEST_LINE);
    currentLineNumber++;
    final String method;
    final String uri;
    MatchResult result = scanner.match();
    if (result.groupCount() == 2) {
      method = result.group(1);
      uri = result.group(2).trim();
    } else {
      currentLineNumber++;
      throw new BatchException(BatchException.INVALID_REQUEST_LINE.addContent(scanner.next()).addContent(currentLineNumber));
    }
    PathInfo pathInfo = parseRequestUri(uri);
    Map<String, String> queryParameters = parseQueryParameters(uri);
    if (isChangeSet) {
      if (!HTTP_CHANGESET_METHODS.contains(method)) {
        throw new BatchException(BatchException.INVALID_CHANGESET_METHOD.addContent(currentLineNumber));
      }
    } else if (!HTTP_BATCH_METHODS.contains(method)) {
      throw new BatchException(BatchException.INVALID_QUERY_OPERATION_METHOD.addContent(currentLineNumber));
    }
    ODataHttpMethod httpMethod = ODataHttpMethod.valueOf(method);
    Map<String, List<String>> headers = parseRequestHeaders(scanner);
    if (currentMimeHeaderContentId != null) {
      List<String> headerList = new ArrayList<String>();
      headerList.add(currentMimeHeaderContentId);
      headers.put(BatchHelper.MIME_HEADER_CONTENT_ID.toLowerCase(Locale.ENGLISH), headerList);
    }

    String contentType = getContentTypeHeader(headers);
    List<String> acceptHeaders = getAcceptHeader(headers);
    List<Locale> acceptLanguages = getAcceptLanguageHeader(headers);
    parseNewLine(scanner);
    InputStream body = new ByteArrayInputStream(new byte[0]);
    if (isChangeSet) {
      body = parseBody(scanner);
    }

    ODataRequestBuilder requestBuilder = ODataRequest.method(httpMethod)
        .queryParameters(queryParameters)
        .requestHeaders(headers)
        .pathInfo(pathInfo)
        .acceptableLanguages(acceptLanguages)
        .body(body)
        .acceptHeaders(acceptHeaders);

    if (contentType != null) {
      requestBuilder = requestBuilder.contentType(contentType);
    }
    return requestBuilder.build();
  } else {
    currentLineNumber++;
    throw new BatchException(BatchException.INVALID_REQUEST_LINE.addContent(scanner.next()).addContent(currentLineNumber));
  }

}
 
Example 17
Source File: PluginManager.java    From springreplugin with Apache License 2.0 4 votes vote down vote up
static final int evalPluginProcess(String name) {
    int index = IPluginManager.PROCESS_AUTO;

    try {
        if (TextUtils.equals(IPC.getPackageName(), name)) {
            if (LOG) {
                LogDebug.d(PLUGIN_TAG, "plugin process checker: default, index=" + 0);
            }
            return IPluginManager.PROCESS_UI;
        }

        if (!TextUtils.isEmpty(name)) {
            if (name.contains(PluginProcessHost.PROCESS_PLUGIN_SUFFIX2)) {
                String tail = PluginProcessHost.processTail(name);
                return PluginProcessHost.PROCESS_INT_MAP.get(tail);
            }
        }

        Matcher m = PROCESS_NAME_PATTERN.matcher(name);
        if (m == null || !m.matches()) {
            if (LOG) {
                LogDebug.d(PLUGIN_TAG, "plugin process checker: non plugin process in=" + name);
            }
            return IPluginManager.PROCESS_AUTO;
        }

        MatchResult r = m.toMatchResult();
        if (r == null || r.groupCount() != 2) {
            if (LOG) {
                LogDebug.d(PLUGIN_TAG, "plugin process checker: no group in=" + name);
            }
            return IPluginManager.PROCESS_AUTO;
        }

        String pr = r.group(1);
        if (!TextUtils.equals(IPC.getPackageName(), pr)) {
            if (LOG) {
                LogDebug.d(PLUGIN_TAG, "plugin process checker: package name not match in=" + name);
            }
            return IPluginManager.PROCESS_AUTO;
        }

        String str = r.group(2);
        index = Integer.parseInt(str);
        if (LOG) {
            LogDebug.d(PLUGIN_TAG, "plugin process checker: index=" + index);
        }
    } catch (Throwable e) {
        if (LOG) {
            LogDebug.d(PLUGIN_TAG, e.getMessage(), e);
        }
    }

    return index;
}
 
Example 18
Source File: DownloadFileInfo.java    From springreplugin with Apache License 2.0 4 votes vote down vote up
/**
 * 通过文件名和文件类型,构建V5FileInfo对象
 *
 * @param f
 * @param type
 * @return
 */
static final DownloadFileInfo build(File f, int type) {
    Matcher m = null;
    String fullname = f.getName();
    if (type == INCREMENT_PLUGIN) {
        m = INCREMENT_REGEX.matcher(fullname);
    } else if (type == SINGLE_PLUGIN) {
        m = INCREMENT_SINGLE_REGEX.matcher(fullname);
    } else if (type == MULTI_PLUGIN) {
        m = MULTI_REGEX.matcher(fullname);
    } else {
        m = NORMAL_REGEX.matcher(fullname);
    }
    if (m == null || !m.matches()) {
        if (AppConstant.LOG_V5_FILE_SEARCH) {
            if (LOG) {
                LogDebug.d(PLUGIN_TAG, "DownloadFileInfo.build: skip, no match1, type=" + type + " file=" + f.getAbsolutePath());
            }
        }
        return null;
    }
    MatchResult r = m.toMatchResult();
    if (r == null || r.groupCount() != 1) {
        if (AppConstant.LOG_V5_FILE_SEARCH) {
            if (LOG) {
                LogDebug.d(PLUGIN_TAG, "DownloadFileInfo.build: skip, no match2, type=" + type + " file=" + f.getAbsolutePath());
            }
        }
        return null;
    }
    if (!f.exists() || !f.isFile()) {
        if (AppConstant.LOG_V5_FILE_SEARCH) {
            if (LOG) {
                LogDebug.d(PLUGIN_TAG, "DownloadFileInfo.build: nor exist or file, file=" + f.getAbsolutePath());
            }
        }
        return null;
    }
    DownloadFileInfo p = new DownloadFileInfo();
    p.mName = r.group(1);
    p.mFile = f;
    p.mType = type;
    if (LOG) {
        LogDebug.d(PLUGIN_TAG, "DownloadFileInfo.build: found plugin, name=" + p.mName + " file=" + f.getAbsolutePath());
    }
    return p;
}
 
Example 19
Source File: SyslogUtils.java    From mt-flume with Apache License 2.0 4 votes vote down vote up
private void formatHeaders() {
  String eventStr = baos.toString();
  for(int p=0; p < formats.size(); p++) {
    SyslogFormatter fmt = formats.get(p);
    Pattern pattern = fmt.regexPattern;
    Matcher matcher = pattern.matcher(eventStr);
    if (! matcher.matches()) {
      continue;
    }
    MatchResult res = matcher.toMatchResult();
    for (int grp=1; grp <= res.groupCount(); grp++) {
      String value = res.group(grp);
      if (grp == SYSLOG_TIMESTAMP_POS) {
        // apply available format replacements to timestamp
        if (value != null) {
          for (int sp=0; sp < fmt.searchPattern.size(); sp++) {
            value = value.replaceAll(fmt.searchPattern.get(sp), fmt.replacePattern.get(sp));
          }
          // Add year to timestamp if needed
          if (fmt.addYear) {
            value = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)) + value;
          }
          // try the available time formats to timestamp
          for (int dt = 0; dt < fmt.dateFormat.size(); dt++) {
            try {
              timeStamp = String.valueOf(fmt.dateFormat.get(dt).parse(value).getTime());
              break; // done. formatted the time
            } catch (ParseException e) {
              // Error formatting the timeStamp, try next format
              continue;
            }
          }
        }
      } else if (grp == SYSLOG_HOSTNAME_POS) {
        hostName = value;
      } else if (grp == SYSLOG_BODY_POS) {
        msgBody = value;
      }
    }
    break; // we successfully parsed the message using this pattern
  }
}
 
Example 20
Source File: HtmlUnitRegExpProxy.java    From htmlunit with Apache License 2.0 4 votes vote down vote up
String computeReplacementValue(final String replacement, final String originalString,
        final MatchResult matcher, final boolean group0ReturnsWholeMatch) {

    int lastIndex = 0;
    final StringBuilder result = new StringBuilder();
    int i;
    while ((i = replacement.indexOf('$', lastIndex)) > -1) {
        if (i > 0) {
            result.append(replacement, lastIndex, i);
        }
        String ss = null;
        if (i < replacement.length() - 1 && (i == lastIndex || replacement.charAt(i - 1) != '$')) {
            final char next = replacement.charAt(i + 1);
            // only valid back reference are "evaluated"
            if (next >= '1' && next <= '9') {
                final int num1digit = next - '0';
                final char next2 = i + 2 < replacement.length() ? replacement.charAt(i + 2) : 'x';
                final int num2digits;
                // if there are 2 digits, the second one is considered as part of the group number
                // only if there is such a group
                if (next2 >= '1' && next2 <= '9') {
                    num2digits = num1digit * 10 + (next2 - '0');
                }
                else {
                    num2digits = Integer.MAX_VALUE;
                }
                if (num2digits <= matcher.groupCount()) {
                    ss = matcher.group(num2digits);
                    i++;
                }
                else if (num1digit <= matcher.groupCount()) {
                    ss = StringUtils.defaultString(matcher.group(num1digit));
                }
            }
            else {
                switch (next) {
                    case '&':
                        ss = matcher.group();
                        break;
                    case '0':
                        if (group0ReturnsWholeMatch) {
                            ss = matcher.group();
                        }
                        break;
                    case '`':
                        ss = originalString.substring(0, matcher.start());
                        break;
                    case '\'':
                        ss = originalString.substring(matcher.end());
                        break;
                    case '$':
                        ss = "$";
                        break;
                    default:
                }
            }
        }
        if (ss == null) {
            result.append('$');
            lastIndex = i + 1;
        }
        else {
            result.append(ss);
            lastIndex = i + 2;
        }
    }

    result.append(replacement, lastIndex, replacement.length());

    return result.toString();
}