一般的なアプローチを想定すると、マスク内の1つの文字(eg 'X'
)から正規表現の一部(eg)へのマッピングがあり'.'
、繰り返しのマスク文字は数値の数量詞(のような{3}
)になります。
そこで、ヘルパークラスと簡単なテストメソッドをまとめました。これが出発点かもしれません。
ヘルパークラス:
import java.util.HashMap;
import java.util.Map;
public class PatternBuilder {
protected Map<Character, String> mappings = new HashMap<Character, String>();
protected boolean caseSensitive = false;
public PatternBuilder() {
}
public PatternBuilder(boolean caseSensitive) {
this.caseSensitive = caseSensitive;
}
public PatternBuilder addDefinition(char input, String mapping) {
if (this.caseSensitive) {
this.mappings.put(input, mapping);
} else {
this.mappings.put(Character.toLowerCase(input), mapping);
}
return this;
}
public String buildRegexPattern(String mask) {
if ((mask == null) || (mask.length() == 0)) {
return "";
}
StringBuilder patternBuffer = new StringBuilder();
char lastChar = 0;
int count = 0;
for (int i = 0; i < mask.length(); i++) {
char c = mask.charAt(i);
if (this.caseSensitive == false) {
c = Character.toLowerCase(c);
}
if (c != lastChar) {
if (count > 0) {
String mapped = mappings.get(lastChar);
if (mapped == null) {
// mapping for char not defined
return "";
}
patternBuffer.append(mapped);
patternBuffer.append("{").append(count).append("}");
}
lastChar = c;
count = 1;
} else {
count++;
}
}
if (count > 0) {
String mapped = mappings.get(lastChar);
if (mapped == null) {
mapped = ".";
}
patternBuffer.append(mapped);
patternBuffer.append("{").append(count).append("}");
}
return patternBuffer.toString();
}
}
使用法:
PatternBuilder patternBuilder = new PatternBuilder()
.addDefinition('X', ".")
.addDefinition('Y', "Y")
.addDefinition('M', "[0-9]")
.addDefinition('N', "\\d")
.addDefinition('A', "[a-zA-Z]");
String rePattern = patternBuilder.buildRegexPattern("XxxYMXXXXXA"); // case insensitive, x == X
System.out.println("Pattern: '" + rePattern + "'");
Pattern p = Pattern.compile(rePattern);
String[] tests = new String[]{
"39JY412345O", // Original, match
"39JY41234FO", // replaced 5 with F, still matching
"39JY4123457", // replaced O with 7, no match
"A9JY4123457" // replaced 3 with A, no match
};
for (String s : tests) {
Matcher m = p.matcher(s);
System.out.println("Test '" + s + "': " + m.matches());
}
私の出力:
Pattern: '.{3}Y{1}[0-9]{1}.{5}[a-zA-Z]{1}'
Test '39JY412345O': true
Test '39JY41234FO': true
Test '39JY4123457': false
Test 'A9JY4123457': false