文字列を複数置換するためのこの小さなクラスがあります。
import Java.util.HashMap;
import Java.util.Map;
import Java.util.regex.Matcher;
import Java.util.regex.Pattern;
import org.Apache.commons.lang.StringUtils;
public class MultipleReplace {
public static void main(String[] args) {
Map<String,String> tokens = new HashMap<String,String>();
tokens.put(":asd:", "<img src=asd.gif>");
tokens.put(":)", "<img src=sorriso.gif>");
String template = ":asd: bravo! :)";
String patternString = "(" + StringUtils.join(tokens.keySet(), "|") + ")";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(template);
StringBuffer sb = new StringBuffer();
while(matcher.find()) {
matcher.appendReplacement(sb, tokens.get(matcher.group(1)));
}
matcher.appendTail(sb);
System.out.println(sb.toString());
}
}
問題は2番目の置換にあり、括弧があり、次のようになります。
スレッド "main" Java.util.regex.PatternSyntaxExceptionの例外:一致しない終了 ')'インデックス8(:) |:asd:)
かっこをエスケープするにはどうすればよいですか?または、この複数の置換を行うための代替案を提案できますか?
どうもありがとうございました、そして私の英語をお詫びします:)
編集:
バックスラッシュ ')'を使用したエスケープも機能せず、コンパイルされません。
"無効なエスケープシーケンス(有効なものは\ b\t\n\f\r \"\'\) "
新しい編集
2つの円記号を使用してコンパイルしますが、置換は行いません。
最終編集
最後に、パターンの作成中にPattern.quoteを使用して、解決策を見つけました。ループを実行するには、イテレータを使用する必要があります。
ここに正しいコードがあります:
package string;
import Java.util.HashMap;
import Java.util.Iterator;
import Java.util.Map;
import Java.util.regex.Matcher;
import Java.util.regex.Pattern;
public class MultipleReplace {
@SuppressWarnings("rawtypes")
public static void main(String[] args) {
Map<String,String> tokens = new HashMap<String,String>();
tokens.put(":asd:", "<img src=asd.gif>");
tokens.put(":)", "<img src=sorriso.gif>");
String template = ":asd: bravo! :)";
Iterator it = tokens.entrySet().iterator();
String patternString = "(";
while (it.hasNext()) {
Map.Entry pairs = (Map.Entry)it.next();
System.out.println(pairs.getKey() + " = " + pairs.getValue());
patternString = patternString +Pattern.quote((String) pairs.getKey());
if (it.hasNext())
{
patternString = patternString + "|";
}
}
patternString = patternString + ")";
System.out.println(patternString);
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(template);
StringBuffer sb = new StringBuffer();
while(matcher.find()) {
matcher.appendReplacement(sb, tokens.get(matcher.group(1)));
}
matcher.appendTail(sb);
System.out.println(sb.toString());
}
}
仕事を改善できたらコメントしてください!どうもありがとうございました!
使用する Pattern.quote
コメントに書いたように。これはすべての文字列で機能し、英数字以外の文字が多数含まれている長い文字列の場合、エラーが発生しにくくなります。
これは光沢のある(そしてテストされていない)Java 8ソリューション:
final Map<String, String> tokens = new HashMap<>();
tokens.put(":asd:", "<img src=asd.gif>");
tokens.put(":)", "<img src=sorriso.gif>");
final String template = ":asd: bravo! :)";
final String patternString = tokens.keySet()
.stream().map(Pattern::quote).collect(Collectors.joining("|"));
final Pattern pattern = Pattern.compile(patternString);
final Matcher matcher = pattern.matcher(template);
final StringBuffer sb = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(sb, tokens.get(matcher.group(0)));
}
matcher.appendTail(sb);
System.out.println(sb.toString());
バックスラッシュを使用します:\)
。正規表現の一部をグループ化するために使用できるため、Parensはエスケープする必要があります。
String template = ":asd: bravo\\! :\\)";
ティムNよりも良い例を挙げましょう。
あなたが文字列の単語を持っているとしましょう。
Word = "http://www.randomwebsite.com/images/That Image (English)";
角かっこをスペースに置き換える場合は、次のようにします。
Word.replaceAll("\\(", " ");
コンパイラをシャットダウンし、泣き言を言わないようにするには、2つのダブルバックスラッシュを実行する必要があります。
また、その関数は文字列を返すことにも注意してください。だからあなたはするだろう
Word = Word.replaceAll("\\(", " ");
見たくない場合は、印刷してください。