Javaには、正規表現に含めることができるように任意のテキストをエスケープする組み込みの方法がありますか?たとえば、ユーザーが「$ 5」と入力した場合、入力終了後の「5」ではなく、正確に一致させたいと思います。
8 に答える
Java 1.5以降、はい:
Pattern.quote("$5");
Pattern.quote
次の例を見る前は、との違いMatcher.quoteReplacement
はわかりませんでした
s.replaceFirst(Pattern.quote("text to replace"),
Matcher.quoteReplacement("replacement text"));
あなたが求めているのは\Q$5\E
。Pattern.quote(s)
Java5で導入されたものも参照してください。
詳細については、パターンjavadocを参照してください。
ならばまず、
- あなたはreplaceAll()を使用します
- Matcher.quoteReplacement() を使用しないでください
- 置換されるテキストには $1 が含まれます
最後に 1 を付けません。最初に一致するグループとサブ THAT の検索正規表現を調べます。これが、置換テキストで $1、$2、または $3 が意味することです: 検索パターンからグループに一致します。
私は頻繁に長いテキスト文字列を .properties ファイルに挿入し、それらから電子メールの件名と本文を生成します。実際、これは Spring Framework で i18n を行うデフォルトの方法のようです。XML タグをプレースホルダーとして文字列に挿入し、replaceAll() を使用して実行時に XML タグを値に置き換えます。
ユーザーがドル記号を使用してドルとセントの数字を入力するという問題に遭遇しました。replaceAll() が詰まっており、stracktrace に次のように表示されます。
java.lang.IndexOutOfBoundsException: No group 3
at java.util.regex.Matcher.start(Matcher.java:374)
at java.util.regex.Matcher.appendReplacement(Matcher.java:748)
at java.util.regex.Matcher.replaceAll(Matcher.java:823)
at java.lang.String.replaceAll(String.java:2201)
この場合、ユーザーは入力のどこかに「$3」と入力し、replaceAll() は検索正規表現で 3 番目に一致するグループを探しましたが、見つからず、puked しました。
与えられた:
// "msg" is a string from a .properties file, containing "<userInput />" among other tags
// "userInput" is a String containing the user's input
交換する
msg = msg.replaceAll("<userInput \\/>", userInput);
と
msg = msg.replaceAll("<userInput \\/>", Matcher.quoteReplacement(userInput));
問題を解決しました。ユーザーは、ドル記号を含むあらゆる種類の文字を問題なく入力できました。期待どおりに動作しました。
パターンを保護するには、数字と文字を除くすべての記号を「\\\\」に置き換えることができます。その後、その保護されたパターンに特別な記号を入れて、このパターンをばかげた引用テキストのようにではなく、実際にはパターンのように機能させることができますが、独自のものにすることができます。ユーザー特殊記号なし。
public class Test {
public static void main(String[] args) {
String str = "y z (111)";
String p1 = "x x (111)";
String p2 = ".* .* \\(111\\)";
p1 = escapeRE(p1);
p1 = p1.replace("x", ".*");
System.out.println( p1 + "-->" + str.matches(p1) );
//.*\ .*\ \(111\)-->true
System.out.println( p2 + "-->" + str.matches(p2) );
//.* .* \(111\)-->true
}
public static String escapeRE(String str) {
//Pattern escaper = Pattern.compile("([^a-zA-z0-9])");
//return escaper.matcher(str).replaceAll("\\\\$1");
return str.replaceAll("([^a-zA-Z0-9])", "\\\\$1");
}
}