Regex pour correspondre à quelque chose qui n'est pas une sous-chaîne spécifique
-
09-06-2019 - |
Question
Je recherche une expression régulière qui correspondra à une chaîne commençant par une sous-chaîne et ne se terminant pas par une certaine sous-chaîne.
Exemple:
// Updated to be correct, thanks @Apocalisp
^foo.*(?<!bar)$
Doit correspondre à tout ce qui commence par « foo » et ne se termine pas par « bar ».Je connais la syntaxe [^...], mais je ne trouve rien qui fasse cela pour une chaîne au lieu de caractères uniques.
J'essaie spécifiquement de faire cela pour l'expression régulière de Java, mais j'ai déjà rencontré ce problème, donc les réponses pour d'autres moteurs d'expression régulière seraient également excellentes.
Merci à @Kibbee d'avoir vérifié que cela fonctionne également en C#.
La solution
Je pense que dans ce cas tu veux regard négatif derrière, ainsi:
foo.*(?<!bar)
Autres conseils
Vérifié la réponse de @Apocalisp en utilisant :
import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) {
Pattern p = Pattern.compile("^foo.*(?<!bar)$");
System.out.println(p.matcher("foobar").matches());
System.out.println(p.matcher("fooBLAHbar").matches());
System.out.println(p.matcher("1foo").matches());
System.out.println(p.matcher("fooBLAH-ar").matches());
System.out.println(p.matcher("foo").matches());
System.out.println(p.matcher("foobaz").matches());
}
}
Cela donne les bonnes réponses :
false
false
false
true
true
true
Je ne suis pas familier avec Java regex mais la documentation pour le Classe de modèle suggérerait que vous puissiez utiliser (?! X) pour une anticipation négative de largeur nulle sans capture (il recherche quelque chose qui n'est pas X à cette position, sans le capturer comme référence arrière).Donc tu pourrais faire :
foo.*(?!bar) // not correct
Mise à jour:Apocalisp a raison, vous voulez un regard négatif derrière vous.(vous vérifiez que ce à quoi correspond le .* ne se termine pas par bar)
Comme d’autres commentateurs l’ont dit, vous avez besoin d’une analyse prospective négative.En Java, vous pouvez utiliser ce modèle :
"^first_string(?!.?second_string)\\z"
- ^ - s'assure que la chaîne commence par First_string
- \z - garantit que la chaîne se termine par second_string
- (?!.?second_string) - signifie que first_string ne peut pas être suivi de second_string