/*******************************************************************************
* Copyright 2011 André Rouél
*
* Licensed 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 net.sf.jacclog.uasparser.internal.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class RegularExpressionConverter {
/**
* Pattern for PERL style regular expression strings
*/
private static final Pattern PERL_STYLE = Pattern.compile("^/.*/((i|m|s|x)*)?$");
/**
* Pattern for PERL style regular expression strings with more fault-tolerance to the modifiers
*/
private static final Pattern PERL_STYLE_TOLERANT = Pattern.compile("^/.*/(([A-z])*)?$");
/**
* Converts a PERL style regular expression into Java style.<br>
* <br>
* The leading and ending slash and the modifiers will be removed. The modifiers will be translated into equivalents
* flags of <code>java.util.Pattern</code>. If there are modifiers that are not valid an exception will be thrown.
*
* @param regex
* A PERL style regular expression
* @return Pattern
*/
public static Pattern convertPerlRegexToPattern(final String regex) {
return convertPerlRegexToPattern(regex, false);
}
/**
* Converts a PERL style regular expression into Java style.<br>
* <br>
* The leading and ending slash and the modifiers will be removed.
*
* @param regex
* A PERL style regular expression
* @param faultTolerant
* Fault-tolerant translating the flags
* @return Pattern
*/
public static Pattern convertPerlRegexToPattern(final String regex, final boolean faultTolerant) {
if (regex == null) {
throw new IllegalArgumentException("Argument 'regex' can not be null.");
}
String pattern = regex.trim();
final Matcher matcher = (faultTolerant) ? PERL_STYLE_TOLERANT.matcher(pattern) : PERL_STYLE.matcher(pattern);
if (!matcher.matches()) {
throw new IllegalArgumentException("The given regular expression '" + pattern
+ "' seems to be not in PERL style or has unsupported modifiers.");
}
pattern = pattern.substring(1);
final int lastIndex = pattern.lastIndexOf('/');
pattern = pattern.substring(0, lastIndex);
final int flags = translateModifiers(matcher.group(1));
return Pattern.compile(pattern, flags);
}
/**
* Translates PERL style modifiers to a set of <code>Pattern</code> compatible ones.<br>
* <br>
*
* @param modifiers
* Modifiers string of a PERL style regular expression
* @return A bit mask of modifier flags that may include CASE_INSENSITIVE, MULTILINE, DOTALL and COMMENTS.
*/
public static int translateModifiers(final String modifiers) {
if (modifiers == null) {
throw new IllegalArgumentException("Argument 'modifiers' can not be null.");
}
int flags = 0;
for (int i = 0; i < modifiers.length(); i++) {
final char chr = modifiers.charAt(i);
switch (chr) {
case 'i':
flags = flags | Pattern.CASE_INSENSITIVE;
break;
case 'm':
flags = flags | Pattern.MULTILINE;
break;
case 's':
flags = flags | Pattern.DOTALL;
break;
case 'x':
flags = flags | Pattern.COMMENTS;
break;
default:
break;
}
}
return flags;
}
/**
* <strong>Attention:</strong> This class is not intended to create objects from it.
*/
private RegularExpressionConverter() {
// This class is not intended to create objects from it.
}
}