新しい形式のツリーでノードを変換しようとしていますが、置き換えの権利が得られません。私はHashMap
を持って言う:Java複数が1回のパスで置換されます
"(1:" : "(30:"
",1:" : ",30:"
"(30:" : "(6:"
",30:" : ",6:"
ツリー:
(30:0.07,(1:0.06,2:0.76))
従来の知恵は、複数のreplaceAll
を示唆しているが、これは問題を提起:
replaceAll("(1:", "(30:") >> (30:0.07,(30:0.06,2:0.76))
replaceAll("(30:", "(6:") >> (6:0.07,(6:0.06,2:0.76))
ここでの問題は、我々は」以前に置き換えられたノードが置き換えられました。
def multiple_replace(taxa, text):
regex = re.compile("|".join(map(re.escape, taxa.keys())))
return regex.sub(lambda mo: taxa[mo.group(0)], text)
しかし、私は私のJava実装に問題を抱えている:今、私はすでにPythonでこれをやった
(6:0.07,(30:0.06,2:0.76))
:
private String convertTree (String treeOld, HashMap<String, String> conv) {
Pattern pattern = Pattern.compile("\\(\\d+:|,\\d+:");
Matcher matcher = pattern.matcher(treeOld);
StringBuilder sbt = new StringBuilder(treeOld);
while (matcher.find()) {
String replace = conv.get(matcher.group());
System.out.println(matcher.group() + "||" +replace + " || " + matcher.start() + ":"+matcher.end());
sbt.delete(matcher.start(), matcher.end());
sbt.insert(matcher.start(), replace);
}
return treeOld;
}
ながら正しいツリーは次のようになります。置換が機能しているように見えますが、例のように異なるサイズの文字列でインデックスを作成することはできません。 Javaでこれを行う方法はありますか?この実装はStringBuilder
を使用していないので、公正な警告が、それは大規模な文字列に遅いかもしれ
private String singlePassConvert (String text, HashMap<String, String> conv) {
Pattern pattern = Pattern.compile("\\(\\d+:|,\\d+:");
Matcher matcher = pattern.matcher(text);
int offset = 0;
while (matcher.find()) {
String replace = conv.get(matcher.group());
String head = (String) text.subSequence(0, matcher.start() + offset);
String tail = (String) text.subSequence(matcher.end() + offset, text.length());
text = head + conv.get(matcher.group()) + tail;
if (matcher.group().length() > conv.get(matcher.group()).length()) {
offset --;
} else if (matcher.group().length() < conv.get(matcher.group()).length()) {
offset ++;
}
}
return text;
}
:。
私の試みよりもずっときれいで、ありがとう! – Darkstarone