これは非常に簡単に実現できます。
正規表現は行く方法です。正規表現には、 backreferenceと呼ばれるものがあります。後方参照はまったく同じ文字列と一致する必要があります。前述の一致グループは既に一致しています。つまり、正規表現はor^([ab])\\1$
のようなすべての文字列に一致します。最初のグループは a または b のいずれかに一致しますが、後方参照は同じものに一致する必要があり、一致グループ (この場合は "1") が一致します。aa
bb
したがって、必要なことは次のとおりです。文字列ベースのパターンを正規表現パターンに変換します。
例:
String regex = "^([a-z]+)\\1([a-z]+)\\1$";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher("catcatdogcat");
if (m.matches()){
System.out.println("matches!");
System.out.println(m.group(0));
System.out.println(m.group(1));
System.out.println(m.group(2));
}else{
System.out.println("no matches!");
}
生成:
matches!
catcatdogcat
cat
dog
これは、指定された文字列「catcatdogcat」と正確に一致しますが、グループ 1 beeing 「cat」と一致し、グループ 2 beeing 「dog」と一致します。
あなたが今しなければならないことは次のとおりです。
- 文字列パターンを 1 文字ずつチェックする関数を作成します
aaba
。
- 文字の最初の出現: それを置き換えて
([a-z]+)
、そのマッチグループの番号を書き留めます (配列、ハッシュマップなど)
- それ以降の文字の出現: で置き換えます
\\1
(文字の記録された番号が 1 の場合)
^
結果をandでラップし$
ます。
最後に、文字列aaba
が変換され^([a-z]+)\\1([a-z]+)\\1$
、ニーズに応えます。パターンabccba
は正規表現になります^([a-z]+)([a-z]+)([a-z]+)\\3\\2\\1$
最後にマッチャーを使用して、指定された文字列をチェックします。
この例では小文字のみを想定していますが、拡張できます。
ただし、「+」を保持することが重要です。「*」では長さの一致がゼロになるため、正規表現はほぼ常に一致します。
言及された2番目の例:
import java.util.regex.*;
public class HelloWorld {
public static void main(String[] args) {
String regex = "^([a-z]+)([a-z]+)([a-z]+)\\3\\2\\1$";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher("catdogcowcowdogcat");
if (m.matches()){
System.out.println("matches!");
System.out.println(m.group(0));
System.out.println(m.group(1));
System.out.println(m.group(2));
System.out.println(m.group(3));
}else{
System.out.println("no matches!");
}
}
}
生成:
matches!
catdogcowcowdogcat
cat
dog
cow
編集:必要に応じて(要件に100%一致しない場合でも-コメントを参照してください):
public static String convertToRegex(String pattern){
String regex = "";
Map<Character, Integer> refs = new HashMap<Character, Integer>();
Integer i=1;
for (Character c : pattern.toCharArray()){
if (refs.containsKey(c)){
//known.
regex += "\\" + refs.get(c);
}else{
//unknown
regex += "([a-z]+)";
refs.put(c, i++);
}
}
return "^" + regex + "$";
}