122

メッセージテンプレートをユーザーが送信しようとしているメッセージと一致させるアプリケーションを作成しようとしています。メッセージの照合にJava正規表現を使用しています。テンプレート/メッセージには特殊文字が含まれている場合があります。

正規表現が機能し、可能な限り最大の場合に一致するためにエスケープする必要がある特殊文字の完全なリストを取得するにはどうすればよいですか?

Java正規表現のすべての特殊文字をエスケープするためのユニバーサルソリューションはありますか?

4

10 に答える 10

102

Patternクラスのjavadocを見ることができます:http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html

特別な意味ではなく通常の文字が必要な場合は、そこにリストされている文字をエスケープする必要があります。

おそらくもっと簡単な解決策として、テンプレートを\Qと\Eの間に置くことができます-それらの間のすべてはエスケープされていると見なされます。

于 2013-01-03T07:44:05.003 に答える
99
  • 正規表現でエスケープする必要のあるJava文字は次のとおりです。
    \.[]{}()<>*+-=!?^$|
  • 2つの閉じ括弧(]および})は、同じタイプの括弧を開いた後にのみエスケープする必要があります。
  • []括弧内の一部の文字(+およびなど-)は、エスケープなしで機能する場合があります。
于 2014-10-07T05:03:29.860 に答える
32

エスケープするには、 Java1.5からこれを使用できます。

Pattern.quote("$test");

あなたは単語と完全に一致します$test

于 2016-05-13T18:02:54.270 に答える
18

文字列リテラル/メタ文字のドキュメントページによると、次のとおりです。

<([{\^-=$!|]})?*+.>

また、そのリストをコードのどこかで参照するのはクールですが、それがどこにあるのかわかりません...

于 2014-12-13T00:53:41.590 に答える
7

誰もが言ったことを組み合わせて、正規表現に固有の文字のリストを独自の文字列に明確にリストし、何千もの「\\」を視覚的に解析しようとする必要をなくすために、次のことを提案します。これは私にとってはかなりうまくいくようです:

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");
}
于 2017-04-01T06:22:26.667 に答える
6

答えは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

于 2019-08-23T23:48:38.610 に答える
5

@SorinによるJavaパターンドキュメントの提案では、エスケープする文字は少なくとも次のように見えます。

\.[{(*+?^$|
于 2014-02-12T04:17:50.407 に答える
4

Pattern.quote(String s)ある種はあなたが望むことをします。ただし、それはまだ少し残っています。実際には個々の文字をエスケープするのではなく、文字列を。でラップするだけ\Q...\Eです。

探していることを正確に実行する方法はありませんが、幸いなことに、Java正規表現のすべての特殊文字をエスケープするのは実際にはかなり簡単です。

regex.replaceAll("[\\W]", "\\\\$0")

なぜこれが機能するのですか?のドキュメントには、Pattern必ずしもエスケープする必要のないアルファベット以外の文字をエスケープすることが許可されていると具体的に記載されています。

エスケープされた構成を示さない英字の前に円記号を使用するとエラーになります。これらは、正規表現言語の将来の拡張のために予約されています。非アルファベット文字がエスケープされていない構成の一部であるかどうかに関係なく、その文字の前に円記号を使用できます。

たとえば、;は正規表現の特殊文字ではありません。ただし、エスケープすると、Patternはとして解釈\;され;ます。さらにいくつかの例を示します。

  • >\>に相当するものになります>
  • [\[のエスケープされた形式になります[
  • 8まだ8です。
  • \)\\\)のエスケープされた形式\(連結されたものになります。

注:重要なのは「非アルファベット」の定義です。これは、ドキュメントでは実際には「非単語」文字、または文字セット外の文字を意味し[a-zA-Z_0-9]ます。

于 2019-05-24T21:49:47.533 に答える
3

コインの反対側では、特殊文字= allChars --number --ABC --spaceをアプリのコンテキストで使用する場合、次のような「non-char」正規表現を使用する必要があります。

String regepx = "[^\\s\\w]*";
于 2013-01-03T07:39:30.463 に答える
1

Java正規表現が使用するエスケープ文字のリストを持っていて信頼していると仮定すると(これらの文字がPatternクラスのメンバーで公開されていると便利です)、本当に必要な場合は、次のメソッドを使用して文字をエスケープできます。

private static final char[] escapeChars = { '<', '(', '[', '{', '\\', '^', '-', '=', '$', '!', '|', ']', '}', ')', '?', '*', '+', '.', '>' };

private static String regexEscape(char character) {
    for (char escapeChar : escapeChars) {
        if (character == escapeChar) {
            return "\\" + character;
        }
    }
    return String.valueOf(character);
}
于 2019-08-05T19:09:28.800 に答える