回答:
あなたはパターンクラスのjavadocを見ることができます:http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html
特別な意味ではなく通常の文字が必要な場合は、そこにリストされている文字をエスケープする必要があります。
おそらくもっと単純な解決策として、テンプレートを\ Qと\ Eの間に置くことができます-それらの間のすべてがエスケープされたと見なされます。
\Q
と\E
]はエスケープされていると見なされます」 —他\Q
のとを除き\E
ます(元の正規表現内で発生する可能性があります)。したがって、ここでPattern.quote
提案されているように使用し、ホイールを再発明しない方が良いでしょう。
\.[]{}()<>*+-=!?^$|
]
および}
)は、同じタイプの括弧を開いた後にのみエスケープする必要があります。[]
一部の文字(のような-brackets +
とは-
)エスケープせずに、時には仕事をします。-
れてい[]
ないものは常に機能するとは限りません。脱出する方が安全です。たとえば、パターン[-]
と[-)]
は文字列と一致します-
が、とは一致しません[(-)]
。
-=!
必ずしもエスケープする必要はありません。コンテキストによって異なります。たとえば、単一の文字として、それらは定数の正規表現として機能します。
文字列リテラル/メタキャラクターのドキュメントページによると、次のとおりです。
<([{\^-=$!|]})?*+.>
また、そのリストがコードのどこかで参照されていると便利ですが、どこにあるかわかりません...
String escaped = tnk.replaceAll("[\\<\\(\\[\\{\\\\\\^\\-\\=\\$\\!\\|\\]\\}\\)\\?\\*\\+\\.\\>]", "\\\\$0");
s.replaceAll("[\\W]", "\\\\$0")
ここで、は\W
単語以外の文字を指定します。
誰もが言ったことを組み合わせて、私は以下を提案します。RegExpに特有の文字のリストを独自の文字列に明確にリストし、数千の「\\」を視覚的に解析する必要がないようにします。これは私にはかなりうまくいくようです:
final String regExSpecialChars = "<([{\\^-=$!|]})?*+.>";
final String regExSpecialCharsRE = regExSpecialChars.replaceAll( ".", "\\\\$0");
final Pattern reCharsREP = Pattern.compile( "[" + regExSpecialCharsRE + "]");
String quoteRegExSpecialChars( String s)
{
Matcher m = reCharsREP.matcher( s);
return m.replaceAll( "\\\\$0");
}
@SorinによるJavaパターンドキュメントの提案では、エスケープする文字は少なくとも次のように見えます。
\.[{(*+?^$|
String escaped = regexString.replaceAll("([\\\\\\.\\[\\{\\(\\*\\+\\?\\^\\$\\|])", "\\\\$1");
)
もエスケープする必要があり、文字クラスの内部か外部かに応じて、エスケープする文字が多くなる可能性があります。その場合Pattern.quote
、文字クラスの内部と外部の両方で使用するために文字列をエスケープするのに非常に適しています。
Pattern.quote(String s)
何をしたいんの一種。しかしそれは望まれるために少し残しておきます。実際に個々の文字をエスケープするのではなく、文字列をで囲みます\Q...\E
。
探していることを正確に実行するメソッドはありませんが、Java正規表現内のすべての特殊文字をエスケープするのは実際にはかなり簡単です。
regex.replaceAll("[\\W]", "\\\\$0")
なぜこれが機能するのですか?まあ、のドキュメントにPattern
は、エスケープする必要のないアルファベット以外の文字をエスケープすることが許可されていると具体的に記載されています。
エスケープされた構造を示さないアルファベット文字の前にバックスラッシュを使用すると、エラーになります。これらは、正規表現言語の将来の拡張のために予約されています。バックスラッシュは、その文字がエスケープされていない構成の一部であるかどうかに関係なく、非アルファベット文字の前に使用できます。
たとえば、;
は正規表現の特殊文字ではありません。ただし、エスケープしても、Pattern
はと解釈さ\;
れ;
ます。さらにいくつかの例を示します。
>
と\>
等価になる>
[
となり\[
のエスケープ形式であります[
8
まだ8
です。\)
となり\\\)
のエスケープ形式である\
と(
連結。注:重要なのは、「非アルファベット」の定義です。ドキュメントでは、これは実際には「非単語」文字、または文字セット外の文字を意味し[a-zA-Z_0-9]
ます。
答えはJavaですが、コードは私が思いついたこのKotlin String拡張機能から簡単に適合させることができます(提供された@brcolowから適応):
private val escapeChars = charArrayOf(
'<',
'(',
'[',
'{',
'\\',
'^',
'-',
'=',
'$',
'!',
'|',
']',
'}',
')',
'?',
'*',
'+',
'.',
'>'
)
fun String.escapePattern(): String {
return this.fold("") {
acc, chr ->
acc + if (escapeChars.contains(chr)) "\\$chr" else "$chr"
}
}
fun main() {
println("(.*)".escapePattern())
}
プリント \(\.\*\)
ここでそれを実際にチェックしてくださいhttps://pl.kotl.in/h-3mXZkNE
Java正規表現が使用するエスケープ文字のリストがあり(信頼できるものである)信頼している(これらの文字が一部のパターンクラスメンバーで公開されている場合は便利です)と仮定すると、本当に必要な場合は次のメソッドを使用して文字をエスケープできます。
private static final char[] escapeChars = { '<', '(', '[', '{', '\\', '^', '-', '=', '$', '!', '|', ']', '}', ')', '?', '*', '+', '.', '>' };
private static String regexEscape(char character) {
for (char escapeChar : escapeChars) {
if (character == escapeChar) {
return "\\" + character;
}
}
return String.valueOf(character);
}