org.codehaus.mojo.animal_sniffer.RegexUtils Maven / Gradle / Ivy
package org.codehaus.mojo.animal_sniffer;
/*
* 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.
*/
import java.util.regex.Pattern;
/**
* Utility methods to help with regex manipulation.
*
* @author Stephen Connolly
* @since 1.3
*/
public final class RegexUtils
{
/**
* The end of a regex literal sequence.
*
* @since 1.3
*/
public static final String REGEX_QUOTE_END = "\\E";
/**
* The start of a regex literal sequence.
*
* @since 1.3
*/
public static final String REGEX_QUOTE_START = "\\Q";
/**
* Escape the escapes.
*
* @since 1.3
*/
public static final String REGEX_QUOTE_END_ESCAPED = REGEX_QUOTE_END + '\\' + REGEX_QUOTE_END + REGEX_QUOTE_START;
private RegexUtils()
{
throw new IllegalAccessError( "Utility classes should never be instantiated" );
}
/**
* Takes a string and returns the regex that will match that string exactly.
*
* @param s The string to match.
* @return The regex that will match the string exactly.
* @since 1.3
*/
public static String quote( String s )
{
int i = s.indexOf( REGEX_QUOTE_END );
if ( i == -1 )
{
// we're safe as nobody has a crazy \E in the string
return REGEX_QUOTE_START + s + REGEX_QUOTE_END;
}
// damn there's at least one \E in the string
StringBuffer sb = new StringBuffer( s.length() + 32 );
// each escape-escape takes 10 chars...
// hope there's less than 4 of them
sb.append( REGEX_QUOTE_START );
int pos = 0;
do
{
// we are safe from pos to i
sb.append( s.substring( pos, i ) );
// now escape-escape
sb.append( REGEX_QUOTE_END_ESCAPED );
// move the working start
pos = i + REGEX_QUOTE_END.length();
i = s.indexOf( REGEX_QUOTE_END, pos );
}
while ( i != -1 );
sb.append( s.substring( pos, s.length() ) );
sb.append( REGEX_QUOTE_END );
return sb.toString();
}
/**
* Converts a wildcard rule to a regex rule.
*
* @param wildcardRule the wildcard rule.
* @param exactMatch true
results in an regex that will match the entire string, while
* false
will match the start of the string.
* @return The regex rule.
*/
public static String convertWildcardsToRegex( String wildcardRule, boolean exactMatch )
{
StringBuffer regex = new StringBuffer();
int index = 0;
final int len = wildcardRule.length();
while ( index < len )
{
final int nextQ = wildcardRule.indexOf( '?', index );
final int nextS = wildcardRule.indexOf( '*', index );
if ( nextQ == -1 && nextS == -1 )
{
regex.append( quote( wildcardRule.substring( index ) ) );
break;
}
int nextIndex;
if ( nextQ == -1 )
{
nextIndex = nextS;
}
else if ( nextS == -1 )
{
nextIndex = nextQ;
}
else
{
nextIndex = Math.min( nextQ, nextS );
}
if ( index < nextIndex )
{
// we have some characters to match
regex.append( quote( wildcardRule.substring( index, nextIndex ) ) );
}
char c = wildcardRule.charAt( nextIndex );
if ( c == '?' )
{
regex.append( '.' );
}
else
{
regex.append( ".*" );
}
index = nextIndex + 1;
}
if ( !exactMatch )
{
regex.append( ".*" );
}
return regex.toString();
}
/**
* Compiles a pattern matcher using wildcard based matching.
* @param wildcard The wildcards rule to match.
* @return A pattern to match the supplied wildcards rule.
*/
public static Pattern compileWildcard( String wildcard )
{
return Pattern.compile( convertWildcardsToRegex( wildcard, true ) );
}
}