Échapper aux caractères spéciaux dans les Expressions régulières Java

existe t'il une méthode en Java ou l'une bibliothèque open source pour s'échapper (ne pas citer) un caractère spécial (méta-caractère), afin de l'utiliser comme une expression régulière?

ce serait très pratique pour construire dynamiquement une expression régulière, sans avoir à échapper manuellement chaque caractère individuel.

par exemple, considérez un simple regex comme d+.d+ qui correspond aux nombres avec un point décimal comme 1.2, ainsi que les suivants code:

String digit = "d";
String point = ".";
String regex1 = "d+.d+";
String regex2 = Pattern.quote(digit + "+" + point + digit + "+");

Pattern numbers1 = Pattern.compile(regex1);
Pattern numbers2 = Pattern.compile(regex2);

System.out.println("Regex 1: " + regex1);

if (numbers1.matcher("1.2").matches()) {
    System.out.println("tMatch");
} else {
    System.out.println("tNo match");
}

System.out.println("Regex 2: " + regex2);

if (numbers2.matcher("1.2").matches()) {
    System.out.println("tMatch");
} else {
    System.out.println("tNo match");
}

il N'est pas surprenant que la sortie produite par le code ci-dessus soit:

Regex 1: d+.d+
    Match
Regex 2: Qd+.d+E
    No match

Qui est regex1 correspond à 1.2 mais regex2 (qui est" dynamiquement " construit) ne correspond pas (à la place, il correspond à la chaîne littérale d+.d+).

alors, y a-t-il une méthode qui échapperait automatiquement à chaque méta-caractère regex?

Si il n'y avait, disons, un statique escape() méthode java.util.regex.Pattern, la sortie de

Pattern.escape('.')

la chaîne ".", mais

Pattern.escape(',')

devrait juste produire ",", puisqu'il n'est pas un méta-caractère. De même,

Pattern.escape('d')

pourrait produire "d", car 'd' est utilisé pour indiquer des chiffres (bien que l'évasion peut ne pas avoir de sens dans ce cas, comme 'd' pourrait signifier littérale 'd', ce qui ne serait pas mal compris par l'interpètre de regex d'être autre chose, comme ce serait le cas avec '.').

19
demandé sur nhahtdh 2012-05-19 14:39:10

5 réponses

existe t'il une méthode en Java ou l'une bibliothèque open source pour s'échapper (ne pas citer) un caractère spécial (méta-caractère), afin de l'utiliser comme une expression régulière?

Je ne suis pas sûr à 100% que ce soit ce que vous demandez ici. Si vous êtes à la recherche d'un moyen de créer des constantes que vous pouvez utiliser dans vos modèles regex alors juste les préparer avec "\" devrait fonctionner, mais il n'y a pas de belles Pattern.escape('.') fonction pour aider avec cela.

Donc, si vous essayons de faire correspondre "\d" (la chaîne de caractères \d au lieu d'un caractère décimal), puis vous ferait:

// this will match on \d as opposed to a decimal character
String matchBackslashD = "\\d";
// as opposed to
String matchDecimalDigit = "\d";

les 4 slashes dans la chaîne Java se transforment en 2 slashes dans le motif regex. 2 backslashs dans un motif regex correspondent au backslash lui-même. La préparation de tout caractère spécial avec antislash le transforme en un caractère normal au lieu d'un caractère spécial.

matchPeriod = "\.";
matchPlus = "\+";
matchParens = "\(\)";
... 

Dans votre post, vous utilisez le Pattern.quote(string) méthode. Vous savez sans doute que cette enveloppe votre modèle entre "\Q" et "\E" donc vous pouvez faire correspondre une chaîne de caractères même si elle a un caractère regex spécial (+,.,\d, etc.)

21
répondu Gray 2018-05-16 18:38:56

j'ai écrit ce modèle:

Pattern SPECIAL_REGEX_CHARS = Pattern.compile("[{}()\[\].+*?^$\\|]");

Et l'utiliser dans cette méthode:

String escapeSpecialRegexChars(String str) {

    return SPECIAL_REGEX_CHARS.matcher(str).replaceAll("\\");
}

Ensuite, vous pouvez l'utiliser comme ceci, par exemple:

Pattern toSafePattern(String text)
{
    return Pattern.compile(".*" + escapeSpecialRegexChars(text) + ".*");
}

nous avions besoin de faire cela parce que, après nous être échappés, nous ajoutons quelques expressions regex. Si non, vous pouvez tout simplement utiliser \Q et \E:

Pattern toSafePattern(String text)
{
    return Pattern.compile(".*\Q" + text + "\E.*")
}
21
répondu Ferran Maylinch 2014-09-15 17:33:14

le seul moyen pour que le matcher regex sache que vous cherchez un chiffre et non la lettre d c'est échapper à la lettre (\d). Pour taper le caractère regex escape en java, vous devez l'échapper (donc \ devient \). Donc, il n'y a aucun moyen de taper deux barres obliques pour les barres regex spéciales.

6
répondu Attila 2012-05-19 12:23:32

D'accord avec Gray, car vous pourriez avoir besoin de votre motif pour avoir à la fois des lithals (\[, \]) et des méta-caractères ([, ]). donc avec un certain utilitaire vous devriez être en mesure d'échapper à tous les caractères d'abord et ensuite vous pouvez ajouter des méta-caractères que vous voulez ajouter sur le même modèle.

1
répondu nir 2013-10-09 01:49:04

utiliser

pattern.compile("\"");
String s= p.toString()+"yourcontent"+p.toString();

va donner le résultat sous la forme yourcontent comme

0
répondu kavita 2017-05-01 18:37:15